I’m writing an ASP.NET web application that transmits JSON between the client and the server. I have nearly everything complete, except that I cannot seem to transmit from the client the JSON to the ASMX and have it interpreted as anything but a Dictionary<string>
On the server-side, I have
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ToolboxItem(false)]
[ScriptService]
public class WebService1: System.Web.Services.WebService
{
[WebMethod(EnableSession = true)]
public bool SaveExpression(ExpressionStructure Expression) {
return true;
}
}
On the client-side, I am sending the data using $.ajax(), where expressionObject.expression is an object of .NET class ExpressionStructure received earlier by the client:
var dataSubmit = { Expression: expressionObject.expression };
$.ajax({
url: "WebService.asmx/SaveExpression",
contentType: "application/json; charset=utf-8",
dataType: "json",
type: 'POST',
data: JSON.stringify(dataSubmit),
success: function (msg) {
alert(msg.d);
},
error: function (obj, status, msg) { ajaxServerError(obj, status, msg); }
});
When the SaveExpression method accepts Object, I get a dictionary of strings. When I use ExpressionStructure, I get a 500 Internal Server Error.
The expression being sent is an unmodified version of what is received from this MVC3 controller method.
public ActionResult Expression(int ExpressionID) {
ExpressionStructure es = GetExpressionFromDatabase(ExpressionID);
return new JsonResult {
Data = new {
expression = es,
view = this.RenderPartialView("_Expression_Statement", es)
},
JsonRequestBehavior = System.Web.Mvc.JsonRequestBehavior.AllowGet
};
}
The expression itself looks like this:
{
"Expression":
{
"Name":"Status Desc",
"Type":0,
"Statement":
{
"FormulaItem":
{
"Type":"Replace",
"Parameters":
[
{
"Type":"Char",
"Value":
{
"Value":"[Status]"
},
"Source":"picker"
},
{
"Type":"input",
"Value":
{
"Value":"0,1,2;Home,Driving,Away"
},
"Source":"inputBox"
}
]
}
}
}
}
I’ve tried changing the ASMX method to take string, ExpressionStructure but both return a 500 Internal Server Error. I’ve also tried modifying the JSON coming from the client, doing various wrappings (including wrapping the outermost "Expression" with square braces).
What critical element am I missing that is preventing the ASMX from correctly taking the JSON and getting the ExpressionStructure? Optionally, how can I get a string either directly or from the Dictionary so I can perform the JSON convertion manually (which I’d rather not do)?
After building a small test case separated from the main project, I was able to get better information about why the server was returning
500 Internal Server Error. As it happens, the web app was catching a deserialization error and attempting to redirect the request to the error handler page. Since it wasn’t an actual page request, the redirect threw an error, which forced a redirect to the error handler page….until too many redirects kicked out an error.The underlying problem was in the deserializing of the JSON to a rather complicated (collection of) classes on the .NET side. The classes, perfectly decorated with XML attribute decorators, used abstract classes when there was a choice in the schema (ie one element or another). Without similar JSON decorators, the deserialization didn’t know how to deserialize the JSON to which class.