Build & Deployment problem.

J

James

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
 
J

James

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; }
}
}
}
 
S

Simon Hart

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.

James said:
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; }
}
}
}



Simon Hart said:
Can you show us your SoapExtension code?

Simon.
 
J

James

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

Simon Hart said:
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.

James said:
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; }
}
}
}



Simon Hart said:
Can you show us your SoapExtension code?

Simon.

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
 
J

James

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

James said:
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

Simon Hart said:
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.

James said:
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; }
}
}
}



Can you show us your SoapExtension code?

Simon.

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
 
S

Simon Hart

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.

James said:
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

James said:
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

Simon Hart said:
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.

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; }
}
}
}



Can you show us your SoapExtension code?

Simon.

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
 
J

James

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



Simon Hart said:
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.

James said:
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

James said:
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

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.

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; }
}
}
}



Can you show us your SoapExtension code?

Simon.

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
 
S

Simon Hart

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.

James said:
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



Simon Hart said:
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.

James said:
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

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

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.

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; }
}
}
}



Can you show us your SoapExtension code?

Simon.

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
 
J

James

Cheers, thanks for all your help Simon.

Simon Hart said:
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.

James said:
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



Simon Hart said:
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.

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

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

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.

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; }
}
}
}



Can you show us your SoapExtension code?

Simon.

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
 

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