I'm working on my first .net project using c#. I've been using
activex controls embedded in a web page and wanted to do the same in
..net. My approach has been to create a windows control library and
then reference the dll with a web page as follows:
<html>
<body>
<center>
<object id="UserControl1" height="500" width="700"
classid="http://wiffle/WindowsControlLibrary3.dll#WindowsControlLibrary3. UserControl1">
</object>
</center>
</body>
</html>
A small form seems to work pretty well. Please let me know if this is
not the best way to do the same as an activex control within a web
page.
Having met with success thus far, I decided to attempt to call a web
service with a soap call. We have an IBM product called Redback which
can act as a web service, so I created a SOAP call to it. From
talking to IBM support, I learned that the web service needs to be
called with http/1.0. Sadly there is a bug in the .net framework
where http/1.0 acts like http/1.1 and waits for a 100-continue after
posting the header before posting the body.
http://support.microsoft.com/default...b;en-us;327885 There
is a hotfix if you go through microsoft's gauntlet, but I didn't
figure it was a good idea to write a production application which
depends on applying a hotfix. Strangely, the hotfix came out in 2002,
yet isn't included in the .net framework version 1.1. So I decided to
punt on the SOAP method unless someone has a suggestion for getting
around the problem.
I currently connect to a windows service from my activex controls
which in turn talks to redback. This works great and is very fast, so
I thought I'd try to get a .net application talking to it. I wrote an
object in c# to take care of the communications with my windows
service thinking I could eventually re-write the object to talk SOAP
once things are working. Invoking the object from a windows form
connects and works great. I then added the object to a windows
control library solution. It works, but the connect takes 2-3 minutes
to complete. After the initial connect, it's quite fast, but the
connect wait time is too long. I've seen posts about
TcpClient.Connect being slow from within a windows control library,
but I haven't seen a solution. Under .net 1.0, my windows control
library didn't have permission to make a tcp connection, so my guess
is that the extra wait time is being caused by .net security checks.
So I'm basically at strike 2 with no third option. Here is the code
for my object if that helps. I'd love to hear any suggestions.
namespace WindowsApplication15
{
/// <summary>
/// Summary description for RBIntf.
/// </summary>
public class RBIntf
{
TcpClient cl;
public ParamLst Parameters = new ParamLst();
public RtnLst Returns = new RtnLst();
string imethod;
string ihost;
int iport;
public string method
{
get { return this.imethod; }
set { this.imethod = value; }
}
public string host
{
get { return this.ihost; }
set { this.ihost = value; }
}
public int port
{
get { return iport; }
set { iport = value; }
}
public RBIntf(string host,int port)
{
this.ihost = host;
this.iport = port;
// this is where it hangs for 2-3 minutes
// within a windows control library
// it doesn't have when part of a windows form
cl = new TcpClient(this.ihost,this.iport);
NetworkStream stm = this.cl.GetStream();
// wait for initial connect message
byte[] data = new byte[this.cl.ReceiveBufferSize];
int recv;
string stArray;
System.Text.ASCIIEncoding ascii = new ASCIIEncoding();
stArray = "";
while (stm.DataAvailable == false);
do
{
recv = stm.Read(data, 0, data.Length);
stArray = stArray + ascii.GetString(data, 0, recv);
}
while (stArray.Substring(stArray.Length-2,2) != "\r\n");
}
public string GetRtn(string IName)
{
string rval;
rval = "";
for (int i=0;i <= Returns.RtnList.Count-1;i++)
{
Rtn R;
R = (Rtn)Returns.RtnList[i];
if (R.GetName() == IName)
{
rval = R.GetValue();
}
}
return rval;
}
public void Execute()
{
string RBCmd;
RBCmd = "M`" + this.method;
for (int i=0;i <= Parameters.ParamList.Count-1;i++)
{
Parm P;
P = (Parm)Parameters.ParamList[i];
RBCmd = RBCmd + "`P`" + P.GetName() + "`" + P.GetValue();
}
for (int i=0;i <= Returns.RtnList.Count-1;i++)
{
Rtn R;
R = (Rtn)Returns.RtnList[i];
RBCmd = RBCmd + "`R`" + R.GetName();
}
RBCmd = RBCmd + "\r\n";
NetworkStream stm = this.cl.GetStream();
byte[] data = new byte[this.cl.ReceiveBufferSize];
int recv;
string stArray;
System.Text.ASCIIEncoding ascii = new ASCIIEncoding();
// now send the execute command
byte[] arrData = System.Text.Encoding.ASCII.GetBytes(RBCmd);
stm.Write(arrData,0,RBCmd.Length);
// wait for the command response
while (stm.DataAvailable == false);
stArray = "";
while (stm.DataAvailable == false);
do
{
recv = stm.Read(data, 0, data.Length);
stArray = stArray + ascii.GetString(data, 0, recv);
}
while (stArray.Substring(stArray.Length-2,2) != "\r\n");
// now parse the response
int p;
string Nm;
string Vl;
while (stArray != "")
{
p = stArray.IndexOf("`");
Nm = stArray.Substring(0,p);
stArray = stArray.Substring(p+1,stArray.Length-p-1);
p = stArray.IndexOf("`");
if (p == -1)
{
Vl = stArray;
stArray = "";
}
else
{
Vl = stArray.Substring(0,p);
stArray = stArray.Substring(p+1,stArray.Length-p-1);
}
for (int i=0;i <= Returns.RtnList.Count-1;i++)
{
Rtn R;
R = (Rtn)Returns.RtnList[i];
if (R.GetName() == Nm)
{
R.SetValue(Vl);
}
}
}
}
}
public class ParamLst
{
public ArrayList ParamList = new ArrayList();
public void paramlst()
{
}
public void Add(string Name,string Value)
{
Parm ParmObj = new Parm (Name,Value);
ParamList.Add(ParmObj);
}
public void Clear()
{
ParamList.Clear();
}
}
public class Parm
{
string Name;
string Value;
public Parm(string IName,string IValue)
{
this.Name = IName;
this.Value = IValue;
}
public string GetName()
{
return this.Name;
}
public string GetValue()
{
return this.Value;
}
}
public class RtnLst
{
public ArrayList RtnList = new ArrayList();
public void rtnlst()
{
}
public void Add(string Name)
{
Rtn RtnObj = new Rtn (Name);
RtnList.Add(RtnObj);
}
public void Clear()
{
RtnList.Clear();
}
}
public class Rtn
{
string Name;
string Value;
public Rtn(string IName)
{
this.Name = IName;
this.Value = "";
}
public string GetName()
{
return this.Name;
}
public string GetValue()
{
return this.Value;
}
public void SetValue(string IValue)
{
this.Value = IValue;
}
}
}