【问题标题】:Problems Passing Multiple Parameters to Web Service将多个参数传递给 Web 服务的问题
【发布时间】:2011-04-21 20:10:16
【问题描述】:

我有一个简单的 Web Service 方法定义为:

[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() 中第一行的断点永远不会被命中):

{"Message":"无参数 为类型定义的构造函数 \u0027System.String\u0027.","StackTrace":" 在 System.Web.Script.Serialization.ObjectConverter.ConvertDictionaryToObject(IDictionary2 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(IDictionary2 rawParams)\r\n 在 System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext 上下文,WebServiceMethodData 方法数据,IDictionary`2 rawParams)\r\n 在 System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext 上下文,WebServiceMethodData methodData)","ExceptionType":"System.MissingMethodException"}

我想传入两个字符串参数并使用 DataContractJsonSerializer 编写新的 Foo 和 Bar 对象。我错过了什么吗?

【问题讨论】:

  • 对不起,我有点困惑。你在哪里传递两个字符串参数?看起来您只是传递了一个字符串参数,它是 myParams 中 JSON 值的字符串表示形式。还是 遗漏了什么? :)
  • 由于参数是作为查询字符串值传递的,我假设:{ "queryString1":{}, "queryString2":{}}。我走远了吗?

标签: asp.net jquery


【解决方案1】:

对于服务中的代码,“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"];
    }
}

【讨论】:

    【解决方案2】:

    我知道这是一个旧线程,但添加 cmets/insight 可能会有所帮助(不仅对 OP,而且对发现此线程寻找答案的其他人)。

    OP 声明他的服务器端 web 方法接收两个字符串,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。 :)

    【讨论】:

      【解决方案3】:

      你的服务方法的签名不应该是这样的

      public string MyWebMethod(Foo foo, Bar bar)
      

      当然,据我了解,ASMX 服务使用 JavaScriptSerializer。您应该使用带有 webHttpBinding 的 WCF 服务来使用 DataContractJsonSerializer。

      【讨论】:

        【解决方案4】:

        我知道这听起来很疯狂,但请尝试将 Web 方法的响应格式设置为 XML (ResponseFormat.Xml)。出于某种原因,这对我有用。

        【讨论】:

          【解决方案5】:

          您需要在 json 字符串中制定一个“请求”元素,然后将其传递给数据元素而不使用 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!');
              }
          });
          

          【讨论】:

            猜你喜欢
            • 2019-05-19
            • 1970-01-01
            • 2014-12-26
            • 1970-01-01
            • 2016-09-25
            • 1970-01-01
            • 1970-01-01
            • 2015-06-28
            • 1970-01-01
            相关资源
            最近更新 更多