问题
In my asmx file, I have
[WebMethod]
[ScriptMethod]
public void Method(IDictionary<string, CustomClass> objectOfCustomClass)
{
//do stuff
}
custom class is defined as:
public class CustomClass
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
}
All goes well and the web service is being successfully consumed from Jquery ajax method. Recently I decided to test and try and access it from the direct URL such as http://localhost/Services.asmx/Method
and I get this message
"Cannot serialize interface System.Collections.Generic.IDictionary"
This seems off. What's causing it and is it normal? I am confused - it seems like the clean way of doing things but according to Microsoft shouldn't be done, yet it works, only not when accessing the web service directly. What gives? I also read on some MS sites that you can't pass IDictionary to the web service as a parameter yet it works fine...SO can it be done or not? Can someone clarify this once and for all?
回答1:
Unfortunately, yes, this is normal. What you see is a limitation of XML serialization (the XmlSerializer) in the classic ASP.NET Web Service stack - it refuses to work with anything that implements IDictionary.
The service exposed to JavaScript via [ScriptMethod] uses a different serializer (the JavaScriptSerializer), which does not have this limitation.
When you call the service from JavaScript, you invoke the JSON endpoint (declared with [ScriptMethod]). When you test from the browser, however, you reach the traditional XML enpoint (declared with [WebMethod]).
There are some workarounds, see e.g. this question. However, if you only need to support AJAX clients, you may simply remove the XML endpoint (the [WebMethod] attribute) and avoid the issue.
As a side note, the improved serializer in WCF supports serialization of dictionaries.
回答2:
ASMX Webservices serialize and deserialize objects using an XmlSerializer, and there isn't a good way to represent a Dictionary in a proper XML schema. Unfortunately, I don't think there is a good way around this besides converting your IDictionary to another type of object that can be serialzed by an XmlSerializer.
Taken from this article "XML Serialization in the .NET Framework" (http://msdn.microsoft.com/en-us/library/ms950721.aspx):
Q: Why can't I serialize hashtables?
A: The XmlSerializer cannot process classes implementing the IDictionary interface. This was partly due to schedule constraints and partly due to the fact that a hashtable does not have a counterpart in the XSD type system. The only solution is to implement a custom hashtable that does not implement the IDictionary interface.
来源:https://stackoverflow.com/questions/4939829/passing-idictionary-object-to-web-service