将多个参数传递给Web服务的问题

时间:2010-10-06 13:31:53

标签: asp.net jquery

我有一个简单的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对象。我错过了什么吗?

5 个答案:

答案 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!');
    }
});