我有一个简单的Web服务方法定义为:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string MyWebMethod(string foo, string bar)
{
// DataContractJsonSerializer to deserialize foo and bar to
// their respective FooClass and BarClass objects.
return "{\"Message\":\"Everything is a-ok!\"}";
}
我将通过以下方式从客户端拨打电话:
var myParams = { "foo":{"name":"Bob Smith", "age":50},"bar":{"color":"blue","size":"large","quantity":2} };
$.ajax({
type: 'POST',
url: 'https://mydomain.com/WebServices/TestSvc.asmx/MyWebMethod',
data: JSON.stringify(myParams),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (response, status) {
alert('Yay!');
},
error: function (xhr, err) {
alert('Boo-urns!');
}
});
然而,这会产生以下错误(MyWebMethod()中第一行的断点永远不会被命中):
{“消息”:“没有无参数 为类型定义的构造函数 \ u0027System.String \ u0027 “” 堆栈跟踪 “:” 在 System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary的
2 dictionary, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeInternal(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Serialization.ObjectConverter.ConvertObjectToTypeMain(Object o, Type type, JavaScriptSerializer serializer, Boolean throwOnError, Object& convertedObject)\r\n at System.Web.Script.Services.WebServiceMethodData.StrongTypeParameters(IDictionary
2 rawParams)\ r \ n at System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext的 context,WebServiceMethodData methodData,IDictionary`2 rawParams)\ r \ n at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext的 context,WebServiceMethodData methodData)”, “ExceptionType”: “system.missingMethodException而”}
我想传入两个字符串参数并使用DataContractJsonSerializer来编写新的Foo和Bar对象。我错过了什么吗?
答案 0 :(得分:2)
对于服务中的代码,您需要使用object而不是string来表示“foo”和“bar”。然后使用Newtonsoft.Json的函数解析将此对象转换为Json对象,然后构建强类型对象。
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string MyWebMethod(object foo, object bar)
{
// DataContractJsonSerializer to deserialize foo and bar to
// their respective FooClass and BarClass objects.
//parse object to JObject using NewtonJson
JObject jsonFoo = JObject.Parse(JsonConvert.SerializeObject(foo));
JObject jsonBar = JObject.Parse(JsonConvert.SerializeObject(bar));
Foo fo = new Foo(jsonFoo);
Bar ba = new Bar(jsonBar);
return "{\"Message\":\"Everything is a-ok!\"}";
}
public class Foo{
public Foo(JObject jsonFoo){
if (json["prop1"] != null) prop1= json["prop1"].Value<long>();
if (json["prop2"] != null) prop2= (string)json["prop2"];
if (json["prop3"] != null) prop3= (string)json["prop3"];
}
}
答案 1 :(得分:1)
我知道这是一个旧的线程,但是额外的评论/洞察力可能会有所帮助(不仅对OP而且对于那些发现此线程寻找答案的其他人)。
OP表示他的服务器端webmethod收到两个字符串,foo和bar。他的客户端jquery .ajax(...)调用在一个对象({foo:...,bar:...})中创建了他的两个参数,并正确地使用了JSON.stringify这个对象。问题似乎是客户端,foo和bar都是对象本身,foo有两个属性(名称和年龄),而bar有三个属性(颜色,大小和数量)。然而,服务器端webmethod期望它的foo和bar参数是字符串,而不是对象。我认为解决这个问题的正确方法是创建Foo和Bar类服务器端,并让服务器端webmethod接收foo和bar作为Foo和Bar对象而不是字符串。类似的东西:
public enum Sizes
{
Small = 1,
Medium = 2,
Large = 3
}
public class Foo
{
public string name { get; set; }
public int age { get; set; }
}
public class Boo
{
public string color { get; set; }
public Sizes size { get; set; }
public int quantity { get; set; }
}
...
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string MyWebMethod(Foo foo, Bar bar)
{
// foo and bar will already BE deserialized as long as their signatures
// are compatible between their client-side and server-side representations.
// Bar.size as an enum here server-side should even work with its
// client-side representation being a string as long the string contains
// the name of one of the Sizes enum elements.
return "{\"Message\":\"Everything is a-ok!\"}";
}
免责声明:我从头开始键入该代码,因此可能会有一些类型o。 :)
答案 2 :(得分:0)
您的服务方式的签名不应该像
public string MyWebMethod(Foo foo, Bar bar)
但是,当然,据我所知,ASMX服务使用JavaScriptSerializer。您应该使用带有webHttpBinding的WCF服务来使用DataContractJsonSerializer。
答案 3 :(得分:0)
我知道这听起来很疯狂,但尝试将您的Web方法的响应格式设置为XML(ResponseFormat.Xml)。出于某种原因,这对我有用。
答案 4 :(得分:0)
您需要在json字符串中制定“request”元素,然后将其传递给数据元素,而不使用JSON.stringify。见代码。
var myParams = "{request: \'{\"foo\":{\"name\":\"Bob Smith\", \"age\":50},\"bar\":{\"color\":\"blue\",\"size\":\"large\",\"quantity\":2}}\' }";
$.ajax({
type: 'POST',
url: 'https://mydomain.com/WebServices/TestSvc.asmx/MyWebMethod',
data: myParams,
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (response, status) {
alert('Yay!');
},
error: function (xhr, err) {
alert('Boo-urns!');
}
});