No Touch Deployment with website Session using Web Services

E

Endo

It seems that a number of people have been trying to pass arguments to
a smart client launched through IE. In order to get the access to the
arguments you must run in 1.1 and call
domain.GetData("APP_LAUNCH_URL"). This call only works in 1.1 and
will return null in 1.0. I don't have the resources to upgrade past
VS2000, so running in 1.1 requires a configuration file. Just a note,
configuration files are created by adding a app.config file to the
project. They config file is then copied to the executable directory.
Since IIS does not like the .config extension the config extensiong
must be renamed to .xml. The .exe, dlls, and config file must be
copied to a virtual directory.

HTML file

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 7.0">
<TITLE></TITLE>
<link rel="configuration" href="TestBedForm.exe.xml">
</HEAD>
<BODY>
<a id="app" href='TestBedForm.exe'>Launch App</a>
</BODY>
</HTML>

Config file

<configuration>
<startup>
<requiredRuntime imageVersion="v1.1.4322" version="v1.1.4322" />
<supportedRuntime version="v1.1.4322" />
</startup>
</configuration>

Unfortunatly as soon as you add arguments to the line

<a id="app" href='TestBedForm.exe'>Launch App</a>

to make it

<a id="app" href='TestBedForm.exe?arg1=arg1value'>Launch App</a>

The executable will no longer read the config file through the link
tag with arguments in the URL. So it is a chicken and an egg problem.

SOLOUTION:
Create an aspx page whose sole reason for living is to serve up a
config file called TestBedForm.exe.aspx.

TestBedForm.exe.aspx code
private void Page_Load(object sender, System.EventArgs e)
{
Response.Clear();
string txt = string.Emtpy();
txt += @"<?xml version='1.0' encoding='utf-8' ?>";
txt += @"<configuration>";
txt += @"<startup>";
txt += @"<requiredRuntime imageVersion='v1.1.4322'
version='v1.1.4322'/>";
txt += @"<supportedRuntime version='v1.1.4322' /> ";
txt += @"</startup>";
txt += @"<appsettings>";
txt += "<add key=\"sessionID\" value=\""+Session.SessionID+"\"/>";
txt += "</appsettings>";
txt += "</configuration>";
Response.Write(txt);
Response.End();
}

HTML file

<HTML>
<HEAD>
<META NAME="GENERATOR" Content="Microsoft Visual Studio 7.0">
<TITLE></TITLE>
<link rel="configuration" href="TestBedForm.exe.aspx">
</HEAD>
<BODY>
<a id="app" href='TestBedForm.exe'>Launch App</a>
</BODY>
</HTML>

I can also include any other data I might need including the session
ID. I no longer need to pass in args through the URL. Note I also no
longer have to use 1.1. My goal is to integrate NTD apps into a sight
with a single sign on. The NTD apps should use the same session when
communicating through webservices as the website so that the website
session does not timeout while using the NTD apps. Does anybody know
if this is possible?

Endo
 
E

Endo

I apologize in advance for the large post, but this is a very
frustrating concept. I haven't even seen any of the MS guys get it
right.
After further testing I was unable to get the above soloution to work.
It seems that passing in args thru the URL for no touch apps is not
supported. There are additional problems when calling webservices
without a proper config file. I did however find a soloution that
works using isolated storage. I create 4 projects

1. ConsoleSessionSaver - Only saves session info
2. IsolatedStorageUtils - Shared DLL
3. TestBedFormApp - Read session info and talks to webservices
4. TetsBedWebApp - The web app that contains launch web form and
webservice.

The idea is that the ConsoleApp gets launched first with the arguments
and saves them to isolated storage, then the TestBedFormApp gets
launched with no arguments and reads the session info back from
isolated storage. Since the IsolatedStorageUtils is a shared DLL it
can be used by both application. The TestBedFormApp then reads back
from isolated storage the sessionID.

First I launch the ConsoleSessionSaver by calling
string paramStr = "?SessionID="+Session.SessionID +"&TestBed2=" +
Request.Cookies["TestBed2"].Value;
window.open('./apps/ConsoleSessionSaver.exe"+paramStr+"');

The ConsoleApp loads with the arguments and saves them to isolated
storage. You can search for the
Genghis.Web.WebCommandLineHelper.GetCommandLineArgs code. Next the
call

window.open('./apps/TestBedForm.exe');

this will open the app with no arguments. The TestBedForm then loads
the data from isolated storage by

(new IsoStorageUtils.SessionSaver()).SessionID

and sets its Cookie container appropriatly. Then call the webservice
and you will have the same session as the page that launched the No
Touch App as the webservice being consumed. The ConsoleSessionSaver
is a lightweight console and will get downloaded everytime since I am
calling it with arguments. The TestBedForm will however get cached,
this is a good thing since this is where a the app I am interested in
running. I was unable to get this soloution to work with forms
authentication. I Even matched the cookies exactly and I kept getting
a accessed denied. So is what I did was allow access to the
webservices directory and validate the cookie manualy. This is not
the most elegant soloution; however, it does work.

Endo

-First rule of digging holes is to stop digging.


****CODE****

1. ConsoleSessionSaver
//+++
ConsoleSessionSaver Code

public Class1(string[] _args)
{
string[] args = Genghis.Web.WebCommandLineHelper.GetCommandLineArgs(_args);
string sessionID = string.Empty;
string cred = string.Empty;
foreach(string s in args)
if(s.Substring(0, s.IndexOf('=')) == "SessionID")
sessionID=s.Substring(s.IndexOf('=')+1);
else if(s.Substring(0, s.IndexOf('=')) == "TestBed2")
cred=s.Substring(s.IndexOf('=')+1);
(new IsoStorageUtils.SessionSaver()).setSessionVars(sessionID,cred);
}

//---


2. IsoStorageUtils

//+++

public class SessionSaver
{
private bool dataLoaded = false;
private string sessionID;
private string credentials;

public void setSessionVars(string _sessionID, string _credentials)
{
sessionID = _sessionID;
credentials = _credentials;
SaveSettings();
}
public string SessionID
{
get
{
LoadSettings();
return sessionID;
}
}

public string Credentials
{
get
{
LoadSettings();
return credentials;
}
}

private object ReadSetting(StreamReader reader, Type type)
{
TypeConverter converter = TypeDescriptor.GetConverter(type);
return converter.ConvertFromString(reader.ReadLine());
}
private void WriteSetting(StreamWriter writer, object obj)
{
Type type = obj.GetType();
TypeConverter converter = TypeDescriptor.GetConverter(type);
writer.WriteLine(converter.ConvertToString(obj));
}
private IsolatedStorageFileStream CreateSettingsStream()
{
IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForAssembly();

return new IsolatedStorageFileStream("settings.txt",
FileMode.Create, store);
}

private IsolatedStorageFileStream OpenSettingsStream()
{
IsolatedStorageFile store =
IsolatedStorageFile.GetUserStoreForAssembly();

return new IsolatedStorageFileStream("settings.txt",
FileMode.Open, store);
}

private void LoadSettings()
{
if(!dataLoaded)
{
using( Stream stream = OpenSettingsStream() )
using( StreamReader reader = new StreamReader(stream) )
{
sessionID = (string)ReadSetting(reader, typeof(string));
credentials = (string)ReadSetting(reader, typeof(string));
}
dataLoaded = true;
}
}

private void SaveSettings()
{
// Save the window location
using( Stream stream = CreateSettingsStream() )
using( StreamWriter writer = new StreamWriter(stream) )
{
WriteSetting(writer, sessionID);
WriteSetting(writer, credentials);
}
}
}
//---

3. TestBedFormApp

//+++

private void button5_Click(object sender, System.EventArgs e)
{
localhost.Service1 serv2 = new localhost.Service1();
serv2.CookieContainer = new System.Net.CookieContainer();
serv2.CookieContainer.SetCookies(
new Uri(serv2.Url)
,"ASP.NET_SessionId="+(new
IsoStorageUtils.SessionSaver()).SessionID);
serv2.CookieContainer.SetCookies(
new Uri(serv2.Url)
,"TestBed2="+(new IsoStorageUtils.SessionSaver()).Credentials);
string resp = serv2.GetSessionID();
MessageBox.Show(resp);
}
//---

4. TetsBedWebApp
//+++
private void Button1_Click(object sender, System.EventArgs e)
{
Session["test"] = "FromSession";
string paramStr = "?SessionID="+Session.SessionID +"&TestBed2=" +
Request.Cookies["TestBed2"].Value;
string startupScript = string.Empty;
startupScript += "<script type=text/javascript>";
startupScript += "window.open('./apps/ConsoleSessionSaver.exe"+paramStr+"');";
startupScript += "window.open('./apps/TestBedForm.exe');";
startupScript += "</script>";
Page.RegisterStartupScript("LaunchApp",startupScript);

}
//---
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top