Groups | Blog | Home
all groups > dotnet web services enhancements > january 2005 >

dotnet web services enhancements : strange error when sending dataset using WSE 2.0 encryption


Ben Schwehn
1/16/2005 8:09:12 PM
Hello,


I have a Webmethod

===
[WebMethod]
public void SaveDataset(DataSet ds)
{
return;
}
====

I call this webmethod from a client, passing a DataSet with an
ForeignKeyConstraint like this:

===
DataSet ds = new DataSet("NewDataSet");
DataTable table1 = new DataTable("master");
DataColumn col11 = new DataColumn("ID", typeof(int));
DataColumn col12 = new DataColumn("text", typeof(string));

table1.Columns.Add(col11);
table1.Columns.Add(col12);
DataTable table2 = new DataTable("detail");
DataColumn col21 = new DataColumn("ID", typeof(int));
DataColumn col22 = new DataColumn("FK", typeof(int));

table2.Columns.Add(col21);
table2.Columns.Add(col22);
ds.Tables.Add(table1);
ds.Tables.Add(table2);

UniqueConstraint constraint1 = new UniqueConstraint("detailIDUnique",
ds.Tables["detail"].Columns["ID"], true);
ds.Tables["detail"].Constraints.Add(constraint1);

UniqueConstraint constraint2 = new UniqueConstraint("masterIDUnique",
ds.Tables["master"].Columns["ID"], true);
ds.Tables["master"].Constraints.Add(constraint2);

ForeignKeyConstraint constraint3 = new
ForeignKeyConstraint(ds.Tables["master"].Columns["ID"],
ds.Tables["detail"].Columns["FK"]);
ds.Tables["detail"].Constraints.Add(constraint3);


service.SaveDataset(ds);
====

So far so good, this works all right.

However If I then enable Encryption and Signature on both the webservice
and the client (I use an X509 certificate and a policy file similar to
<http://msdn.microsoft.com/webservices/building/wse/default.aspx?pull=/library/en-us/dnwse/html/wse2wspolicy.asp>
) I get the following error:

===
Server was unable to read request. --> There is an error in XML document
(1, 1653). --> The 'http://tempuri.org/:masterIDUnique' identity
constraint is not declared. An error occurred at , (1, 1477).

at
System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage
message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String
methodName, Object[] parameters)\r\n at
tester.Service1.SaveDataset(DataSet ds) in
d:\\dev\\tempstuff\\datasetconstrainterror\\tester\\service1.cs:line
37\r\n at tester.Form1.button1_Click(Object sender, EventArgs e) in
d:\\dev\\tempstuff\\datasetconstrainterror\\tester\\form1.cs:line 97\r\n
at System.Windows.Forms.Control.OnClick(EventArgs e)\r\n at
System.Windows.Forms.Button.OnClick(EventArgs e)\r\n at
System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)\r\n at
System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button,
Int32 clicks)\r\n at System.Windows.Forms.Control.WndProc(Message&
m)\r\n at System.Windows.Forms.ButtonBase.WndProc(Message& m)\r\n at
System.Windows.Forms.Button.WndProc(Message& m)\r\n at
System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)\r\n at
System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)\r\n at
System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32
msg, IntPtr wparam, IntPtr lparam)\r\n at
System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)\r\n
at
System.Windows.Forms.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(Int32
dwComponentID, Int32 reason, Int32 pvLoopData)\r\n at
System.Windows.Forms.ThreadContext.RunMessageLoopInner(Int32 reason,
ApplicationContext context)\r\n at
System.Windows.Forms.ThreadContext.RunMessageLoop(Int32 reason,
ApplicationContext context)\r\n at
System.Windows.Forms.Application.Run(Form mainForm)\r\n at
tester.Form1.Main() in
d:\\dev\\tempstuff\\datasetconstrainterror\\tester\\form1.cs:line 87" string
===

I don't change anything in the code of either server and client, I just
uncomment the <policy> section in each of the config files and I get
this error.

I had a look a the soap envelope the webserice is recieving in each case
(with and without encryption) by using a SoapInputFilter and can't see
anything wrong with it. The xml is very slightly different (as confirmed
by XML Diff http://apps.gotdotnet.com/xmltools/xmldiff/) but nothing major.

Transfering datasets without contstraints works fine.

I have no idea what is wrong here, any help is appreciated.


In case someone is interested, here are the soap requests in both cases:


1. not using encryption -> works

===
<?xml version="1.0" encoding="utf-8"?><soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><soap:Header><wsa:Action>http://tempuri.org/SaveDataset</wsa:Action><wsa:MessageID>uuid:02f41450-d071-452c-919d-7b0fedb5bed5</wsa:MessageID><wsa:ReplyTo><wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address></wsa:ReplyTo><wsa:To>http://localhost/dataseterror/Service1.asmx</wsa:To></soap:Header><soap:Body><SaveDataset
xmlns="http://tempuri.org/"><ds><xs:schema id="NewDataSet" xmlns=""
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"><xs:element
name="NewDataSet" msdata:IsDataSet="true"
msdata:Locale="de-DE"><xs:complexType><xs:choice
maxOccurs="unbounded"><xs:element
name="master"><xs:complexType><xs:sequence><xs:element name="ID"
type="xs:int" /><xs:element name="text" type="xs:string" minOccurs="0"
/></xs:sequence></xs:complexType></xs:element><xs:element
name="detail"><xs:complexType><xs:sequence><xs:element name="ID"
type="xs:int" /><xs:element name="FK" type="xs:int" minOccurs="0"
/></xs:sequence></xs:complexType></xs:element></xs:choice></xs:complexType><xs:unique
name="masterIDUnique" msdata:PrimaryKey="true"><xs:selector
xpath=".//master" /><xs:field xpath="ID" /></xs:unique><xs:unique
name="detailIDUnique" msdata:PrimaryKey="true"><xs:selector
xpath=".//detail" /><xs:field xpath="ID" /></xs:unique><xs:keyref
name="Constraint1" refer="masterIDUnique"
msdata:ConstraintOnly="true"><xs:selector xpath=".//detail" /><xs:field
xpath="FK" /></xs:keyref></xs:element></xs:schema><diffgr:diffgram
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"
/></ds></SaveDataset></soap:Body></soap:Envelope>
===

2. using encryption, after the request is decrypted -> There is an
error in XML document

====
<?xml version="1.0" encoding="utf-8"?><soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
Bojan
3/18/2005 8:45:34 AM
Hi Ben,

It seems that we stoumbled over the same problem. I think it has nothing to
do with WSE 2.0.

The bug could be reproduced like this:

1.
DataColumn[] arrKey = new DataColumn[1];;
arrKey[0] = ds.Tables["Request"].Columns["RequestID"];
ds.Tables["Request"].PrimaryKey = arrKey;

DataColumn[] arrKey2 = new DataColumn[1];;
arrKey2[0] = ds.Tables["Package"].Columns["PackageID"];
ds.Tables["Package"].PrimaryKey = arrKey2;
ds.Tables["Package"].Columns[arrKey2[0].ColumnName].AutoIncrement = true;
ds.Tables["Package"].Columns[arrKey2[0].ColumnName].AutoIncrementSeed =
-1;
ds.Tables["Package"].Columns[arrKey2[0].ColumnName].AutoIncrementStep =
-1;


In this case the exception would be:

There is
an error in XML document (1, 4321). --> The
'http://tempuri.org/:Request_Constraint1' identity constraint is not
declared. An error occurred at , (1, 3905)."}


2.

DataColumn[] arrKey2 = new DataColumn[1];;
arrKey2[0] = ds.Tables["Package"].Columns["PackageID"];
ds.Tables["Package"].PrimaryKey = arrKey2;
ds.Tables["Package"].Columns[arrKey2[0].ColumnName].AutoIncrement = true;
ds.Tables["Package"].Columns[arrKey2[0].ColumnName].AutoIncrementSeed =
-1;
ds.Tables["Package"].Columns[arrKey2[0].ColumnName].AutoIncrementStep =
-1;

DataColumn[] arrKey = new DataColumn[1];;
arrKey[0] = ds.Tables["Request"].Columns["RequestID"];
ds.Tables["Request"].PrimaryKey = arrKey;

In this case the exception would be:

There is
an error in XML document (1, 4321). --> The
'http://tempuri.org/:Package_Constraint1' identity constraint is not
declared. An error occurred at , (1, 3905)."}

which leads us to a conclusion that XML parser always skips Constraint
Definition for the first table and WSE2.0 just reports the error.


Take a look at my webservices.enhancements group message: WSE2 identity
constraint is not declared problem




[quoted text, click to view]
Bojan
3/30/2005 11:05:03 AM
I found the bug in .NET Framework Assembly System.Data.dll

Declaring Type: System.Data.XmlTreeGen
Assembly: System.Data, Version=1.0.5000.0

method

private void GenerateConstraintNames(DataTable table)
{
foreach (Constraint constraint1 in table.Constraints)
{
string text1 = constraint1.ConstraintName;
for (int num1 = 0; this.ConstraintNames.Contains(text1); num1++)
{
text1 = table.TableName + '_' + constraint1.ConstraintName;
if (num1 > 0)
{
text1 = text1 + '_' + num1.ToString();
}
}
this.ConstraintNames.Add(text1);
constraint1.SchemaName = text1;
}
}


by using Lutz Roeder's REFLECTOR tool.

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