Wednesday, March 21, 2012

Complex Type Serialization problem client -> server

I built a real simple sample that downloads an object to the client, then sends the object back up to the server. I love how easy this is, but there's a problem with the upload:
Here's what comes down:
{"__serverType":"Westwind.AtlasTest.busCustomer","Name":"Rick","Company":"West Wind","Entered":new Date(2005,8,25,1,10,16)}
and here's what goes back up:
{"Customer":{"__serverType":"Westwind.AtlasTest.busCustomer","Name":"Rick","Company":"West Wind","Entered":{}}}
Notice the Entered date is no longer set isn't serialized properly - it's empty and on the server side a failure occurs.
This brings up another question: What hapens on an exception? Right now a 500 error and an HTML error page goes back. There's no trigger and no error nothing that happens on the client side page?
+++ Rick --More info...
The failure above doesn't seem to be related to the date field even - it looks like complex types do not marshall up at all. Even doing this on the client:

function btnSaveCustomer_Click()

{

var Customer =new Westwind.AtlasTest.busCustomer();

Customer.Name = document.getElementById("txtName").value;

Customer.Company ="West";

// Customer.Entered =new Date(2005,8,26,20,54,56);

alert(Customer.Entered);

Service = Westwind.AtlasTest.SimpleService.SaveCustomer(Customer,btnSaveCustomer_Click_Complete,btnSaveCustomer_Click_Complete);

returnfalse;

}

Fails. What goes up to the server looks right (I assume) and it's apparently picking up the type properly:

{"Customer":{"__serverType":"Westwind.AtlasTest.busCustomer","Name":"Rick","Company":"West"}}
Here's what I get back:

<html>

<head>

<title>error: Invalid object passed in, ',' or '}' expected. (69): {"Customer":{"__serverType":"Westwind.AtlasTest.busCustomer","Name":"Rick","Company":"West"}}</title>

<style>

body {font-family:"Verdana";font-weight:normal;font-size: .7em;color:black;}

p {font-family:"Verdana";font-weight:normal;color:black;margin-top: -5px}

b {font-family:"Verdana";font-weight:bold;color:black;margin-top: -5px}

H1 { font-family:"Verdana";font-weight:normal;font-size:18pt;color:red }

H2 { font-family:"Verdana";font-weight:normal;font-size:14pt;color:maroon }

pre {font-family:"Lucida Console";font-size: .9em}

.marker {font-weight: bold; color: black;text-decoration: none;}

.version {color: gray;}

.error {margin-bottom: 10px;}

.expandable { text-decoration:underline; font-weight:bold; color:navy; cursor:hand; }

</style>

</head>

<body bgcolor="white">

<span><H1>Server Error in '/atlastest' Application.<hr width=100% size=1 color=silver></H1>

<h2> <i>error: Invalid object passed in, ',' or '}' expected. (69): {"Customer":{"__serverType":"Westwind.AtlasTest.busCustomer","Name":"Rick","Company":"West"}}</i> </h2></span>

<font face="Arial, Helvetica, Geneva, SunSans-Regular, sans-serif ">

<b> Description: </b>An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

<br><br>

<b> Exception Details: </b>System.ArgumentException: error: Invalid object passed in, ',' or '}' expected. (69): {"Customer":{"__serverType":"Westwind.AtlasTest.busCustomer","Name":"Rick","Company":"West"}}<br><br>

<b>Source Error:</b> <br><br>

<table width=100% bgcolor="#ffffcc">

<tr>

<td>

<code>

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.</code>

</td>

</tr>

</table>

<br>

<b>Stack Trace:</b> <br><br>

<table width=100% bgcolor="#ffffcc">

<tr>

<td>

<code><pre>

[ArgumentException: error: Invalid object passed in, ',' or '}' expected. (69): {"Customer":{"__serverType":"Westwind.AtlasTest.busCustomer","Name":"Rick","Company":"West"}}]

Microsoft.Web.Services.JavaScriptObjectDeserializer.DeserializeObject(JavaScriptString s, Type type, IDictionary`2 paramTypeInfo) +1103

Microsoft.Web.Services.JavaScriptObjectDeserializer.DeserializeInternal(JavaScriptString s, Type type) +248

Microsoft.Web.Services.JavaScriptObjectDeserializer.DeserializeObject(JavaScriptString s, Type type, IDictionary`2 paramTypeInfo) +673

Microsoft.Web.Services.JavaScriptObjectDeserializer.DeserializeRequestParameters(String input, IDictionary`2 paramTypeInfo, IJavaScriptSerializationContext context) +107

Microsoft.Web.Services.RestHandler.ProcessRequest(HttpContext context) +92

Microsoft.Web.Services.HandlerWrapper.ProcessRequest(HttpContext context) +10

System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +317

System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +65

</pre></code>

</td>

</tr>

</table>

<br>

<hr width=100% size=1 color=silver>

<b>Version Information:</b> Microsoft .NET Framework Version:2.0.50727.26; ASP.NET Version:2.0.50727.26

</font>

</body>

</html>

<!--

[ArgumentException]: error: Invalid object passed in, ',' or '}' expected. (69): {"Customer":{"__serverType":"Westwind.AtlasTest.busCustomer","Name":"Rick","Company":"West"}}

at Microsoft.Web.Services.JavaScriptObjectDeserializer.DeserializeObject(JavaScriptString s, Type type, IDictionary`2 paramTypeInfo)

at Microsoft.Web.Services.JavaScriptObjectDeserializer.DeserializeInternal(JavaScriptString s, Type type)

at Microsoft.Web.Services.JavaScriptObjectDeserializer.DeserializeObject(JavaScriptString s, Type type, IDictionary`2 paramTypeInfo)

at Microsoft.Web.Services.JavaScriptObjectDeserializer.DeserializeRequestParameters(String input, IDictionary`2 paramTypeInfo, IJavaScriptSerializationContext context)

at Microsoft.Web.Services.RestHandler.ProcessRequest(HttpContext context)

at Microsoft.Web.Services.ScriptHandlerFactory.HandlerWrapper.ProcessRequest(HttpContext context)

at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)


The Web Service is simple as can be for this:

[WebMethod]

publicbusCustomer GetCustomer()

{

//throw new SoapException("Failure dude!", SoapException.ServerFaultCode);

returnnewbusCustomer();

}

[WebMethod]

publicstring SaveCustomer(busCustomer Customer)

{

return Customer.Name;

}


Hi Rick,
I investigated this, and it is indeed a bug in the Atlas serialization code. In order for it to work correctly in its current form, you need to make sure that the fields you set into your client object (in your case Name and Company) have a matching publicproperty on the server object. Fields are not supported at this time, and maybe that's what you are using. If so, just switch to a property and you should be on your way. Thanks for reporting this issue, as it's definitely something we wnat to have fixed.
As for the fact that error reporting is lacking, it is one of those things that we didn't get to implement yet, but will be included in the next release.
Hope this helps,
David

No comments:

Post a Comment