all groups > dotnet compact framework > february 2006 >
You're in the

dotnet compact framework

group:

Build & Deployment problem.


Build & Deployment problem. James
2/14/2006 10:58:53 AM
dotnet compact framework:
A colleague of mine has written a web service and a SoapExtension that I
must reference from my windows mobile 5.0 app (developed in VS2005).

My app was working fine when it referenced just the web service, deployed ok
to a real windows mobile 5.0 device and also to the emulators from Visual
Studio 2005. As soon as the SoapExtension was added (it is a separate
assembly), the project suddenly tries to include all sorts of assemblies
that are not dependencies of the Mobile App, the SoapExtension or the Web
Service (when I look in my MobileApp\bin\Debug folder there are Dll's like
System.Data.OracleClient.dll that should not be there). Then, when I try and
deploy the app to an emulator or a real device, the device does not have
sufficient memory for all the Dll's.

It this a problem with the compact framework, because we created a test
windows forms app, referenced the web service and the SoapExtension and this
problem does not occur.

Any idea's on how to get around this?

Cheers

James

Re: Build & Deployment problem. Simon Hart
2/14/2006 3:54:05 PM
Can you show us your SoapExtension code?

Simon.

[quoted text, click to view]

Re: Build & Deployment problem. James
2/14/2006 4:57:38 PM
sure...here is the code for the SoapExtension

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.IO;
using System.Xml;
using System.Text;
using System.Security.Cryptography;

namespace SoapExtensionLib
{

// Define a SOAP Extension that encrypts the SOAP request and SOAP
// response for the XML Web service method the SOAP extension is
// applied to.

public class EncryptExtension : SoapExtension
{
Stream oldStream;
Stream newStream;

// Save the Stream representing the SOAP request or SOAP response
into
// a local memory buffer.
public override Stream ChainStream(Stream stream)
{
oldStream = stream;
newStream = new MemoryStream();
return newStream;
}

// When the SOAP extension is accessed for the first time, the XML
Web
// service method it is applied to is accessed to store the file
// name passed in, using the corresponding SoapExtensionAttribute.
public override object GetInitializer(LogicalMethodInfo methodInfo,
SoapExtensionAttribute attribute)
{
return null;
}

// The SOAP extension was configured to run using a configuration
file
// instead of an attribute applied to a specific XML Web service
// method.
public override object GetInitializer(Type WebServiceType)
{
return null;
}

// Receive the file name stored by GetInitializer and store it in a
// member variable for this specific instance.
public override void Initialize(object initializer)
{
return;
}

// If the SoapMessageStage is such that the SoapRequest or
// SoapResponse is still in the SOAP format to be sent or received,
// save it out to a file.
public override void ProcessMessage(SoapMessage message)
{
switch (message.Stage)
{
case SoapMessageStage.BeforeSerialize:
break;
case SoapMessageStage.AfterSerialize:
Encrypt();
break;
case SoapMessageStage.BeforeDeserialize:
Decrypt();
break;
case SoapMessageStage.AfterDeserialize:
break;
default:
throw new Exception("invalid stage");
}
}

public void Encrypt()
{
newStream.Position = 0;

newStream = EncryptHeader(newStream);

Copy(newStream, oldStream);
}

public void Decrypt()
{
Stream unEncryptedStream = DecryptHeader(oldStream);

Copy(unEncryptedStream, newStream);

newStream.Position = 0;
}

public Stream EncryptHeader(Stream streamToEncrypt)
{
streamToEncrypt.Position = 0;
XmlTextReader reader = new XmlTextReader(streamToEncrypt);
XmlDocument dom = new XmlDocument();
dom.Load(reader);


XmlNamespaceManager nsmgr = new
XmlNamespaceManager(dom.NameTable);
nsmgr.AddNamespace("soap",
"http://schemas.xmlsoap.org/soap/envelope/");

XmlNode node = dom.SelectSingleNode("//soap:Header", nsmgr);

if (node != null)
{
node = node.FirstChild.FirstChild;

node.InnerText = Encrypt(node.InnerText);
}


MemoryStream ms = new MemoryStream();
dom.Save(ms);
ms.Position = 0;

return ms;
}

private MemoryStream DecryptHeader(Stream streamToDecrypt)
{
if (streamToDecrypt.CanSeek)
{
streamToDecrypt.Position = 0;
}

XmlTextReader reader = new XmlTextReader(streamToDecrypt);
XmlDocument dom = new XmlDocument();
dom.Load(reader);

XmlNamespaceManager nsmgr = new
XmlNamespaceManager(dom.NameTable);
nsmgr.AddNamespace("soap",
"http://schemas.xmlsoap.org/soap/envelope/");

XmlNode node = dom.SelectSingleNode("//soap:Header", nsmgr);

if (node != null)
{
node = node.FirstChild.FirstChild;

node.InnerText = Decrypt(node.InnerText);
}
MemoryStream ms = new MemoryStream();

dom.Save(ms);
ms.Position = 0;

return ms;

}

private Byte[] key = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd,
0xef };
private Byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd,
0xef };

public string Encrypt(string stringToEncrypt)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray =
Encoding.Unicode.GetBytes(stringToEncrypt);

MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(key,
IV), CryptoStreamMode.Write);

cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();

return Convert.ToBase64String(ms.ToArray());
}

public string Decrypt(string stringToDecrypt)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray =
Convert.FromBase64String(stringToDecrypt);

MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(key,
IV), CryptoStreamMode.Write);

cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();

return Encoding.Unicode.GetString(ms.ToArray());
}

void Copy(Stream from, Stream to)
{
TextReader reader = new StreamReader(from);
TextWriter writer = new StreamWriter(to);
writer.WriteLine(reader.ReadToEnd());
writer.Flush();
}
}

// Create a SoapExtensionAttribute for the SOAP Extension that can be
// applied to an XML Web service method.
[AttributeUsage(AttributeTargets.Method)]
public class EncryptExtensionAttribute : SoapExtensionAttribute
{
private int priority;

public override Type ExtensionType
{
get { return typeof(EncryptExtension); }
}

public override int Priority
{
get { return priority; }
set { priority = value; }
}
}
}



[quoted text, click to view]
Re: Build & Deployment problem. Simon Hart
2/14/2006 5:45:19 PM
Hmm seems strange...what happens if you remove the SoapExtensionAttribute
from your Web Service proxy method but still deploy the SoapExtension
assembly?

Probebly not related but I did notice your priority field in your
SoapExtensionAttribute is not initialized.

[quoted text, click to view]
Re: Build & Deployment problem. James
2/16/2006 12:00:00 AM
Hi Simon,

I tried what you suggested and instead of referencing the SoapExtension
assembly from my project, I just deployed it which worked. If I re-add the
reference though, the problem reoccurrs.

Cheers

James

[quoted text, click to view]
Re: Build & Deployment problem. James
2/16/2006 12:04:55 PM
I've just thought, in a windows app, I would put the following lines into my
config file. What do I do in a mobile app where I dont have a proper .config
file?


<system.web>

<webServices>

<soapExtensionTypes>

<add type="SoapExtensionLib.EncryptExtension, SoapExtensionLib" priority="1"
group="High" />

</soapExtensionTypes>

</webServices>

</system.web>


Cheers

James

[quoted text, click to view]
Re: Build & Deployment problem. Simon Hart
2/16/2006 12:57:52 PM
You don't need to specify soapExtensionTypes in your config file as well as
an Attribute class. Your EncryptExtensionAttribute is written so you can
individually select the required methods that will use your implementation
of SoapExtension. Whereas the config file will apply the extension to all
members. The attribute class is then specified in the Web Service proxy
class that WSDL.exe creates for you. By the way, group="High" is invalid.
Not sure what the CLR will translate that to but this needs to be either 0
or 1. 0 means config attributes are executed first whereas setting it to 1
will execute Attribute configured extensions first in order of priority for
each group of course.

I think the fact that priority in your Attribute class *might* be the cause.
Try setting it to 1 and try it again.

Also in your Attribute class set your overridden method ExtensionType to
return the full name inc namespace of your SoapExtension: ie:
SoapExtensionLib.EncryptExtension.

Simon.

[quoted text, click to view]
Re: Build & Deployment problem. James
2/20/2006 12:20:36 PM
Hi Simon,

Thanks for your reply. We have now initialized the Priority with a default
value, but I have realised that the real problem is in the proxy - there is
no reference to the EncryptExtensionAttribute above the method calls.

Why would this be missing?

Cheers

James



[quoted text, click to view]
Re: Build & Deployment problem. Simon Hart
2/20/2006 5:29:27 PM
Hi James,

Failing to include the Attribute in the proxy will not give you the symtoms
you are getting. Failing to include it will result in the Soap extension not
being invoked during method calls.

But going back to your question, one thing to bear in mind is VS.NET IDE
will overwrite any changes you make to your proxy via the IDE or if using
WSDL.exe direct this will still overwrite any changes you make. So when you
update your proxy ensure you put the extension back into the proxy method
definition headers.

Cheers
Simon.

[quoted text, click to view]
Re: Build & Deployment problem. James
2/21/2006 12:00:00 AM
Cheers, thanks for all your help Simon.

[quoted text, click to view]
AddThis Social Bookmark Button