【问题标题】:AJAX Passing multiple parameter to WebApiAJAX将多个参数传递给WebApi
【发布时间】:2013-09-27 13:37:29
【问题描述】:

AJAX 请求:

$.ajax({
            url: url,
            dataType: 'json',
            type: 'Post',
            data: {token:"4", feed:{"id":0,"message":"Hello World","userId":4} }
        });

服务器端 Web API:

 [HttpPost]
 public HttpResponseMessage Post(string token, Feed feed)
 {
    /* Some code */

    return new HttpResponseMessage(HttpStatusCode.Created);
 }

错误代码 404: {"message":"没有找到匹配的 HTTP 资源 请求 URI 'localhost:8080/api/feed'。","messageDetail":"无操作 在与请求匹配的控制器 'Feed' 上找到。"}

为什么我会收到此错误以及为什么我无法将多个参数发布到我的 API?

【问题讨论】:

  • 参数名称必须与服务器路由/映射匹配。第一个参数通常是id(不是令牌),除非您更改了路由/映射默认值。
  • 这是正确的代码吗?它说你正在调用feed,但方法名称是post?
  • @TrueBlueAussie localhost:8080/api/feed
  • @christiandev: feed 是控制器名称,而不是这样的 WEBAPI 调用中的方法。
  • 是的,Feed 是一个控制器,而 Post 是我的 webapi 的默认操作

标签: asp.net jquery asp.net-web-api


【解决方案1】:

我最近遇到了类似的问题,这里有一些关于我如何解决它的信息。我认为问题在于 WebApi 如何处理参数。您可以阅读一些关于它的信息herehere,但基本上有两种方法可以发布参数,在正文中或在 uri 中。 body 只能包含一个参数,但它可以是一个复杂的参数,而 uri 可以包含任意数量的参数(最多 uri 字符限制),但它们必须是简单的。当 jquery 执行 POST ajax 调用时,它会尝试传递正文中的所有数据参数,这在您的情况下不起作用,因为正文只能有一个参数。

在代码方面我认为你需要这样的东西:

var token = "4";
var feed = {Id:0, Message:"Hello World", UserId:4};

$.ajax({
    url: "/api/Feed/?token=" + token,
    dataType: 'json',
    type: 'Post',
    data: JSON.stringify(feed)
});

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    试试这个。您必须从正文中获取 json 对象数据。读取 Request 的输入流并将其映射到您的数据模型。

    public class TokenAndFeed
    {
    public string Token { get; set; }
    public Feed Feed { get; set; }
    }      
    
    [HttpPost]
    public HttpResponseMessage Post()
    {
        System.IO.Stream str;
        String jsonContents;
        Int32 strLen, strRead;
        str = HttpContext.Current.Request.InputStream;
        strLen = Convert.ToInt32(str.Length);
        byte[] byteArray = new byte[strLen];
        strRead = str.Read(byteArray, 0, strLen);
        jsonContents = Encoding.UTF8.GetString(byteArray);
    
        TokenAndFeed tAndf = JsonConvert.DeserializeObject<TokenAndFeed>(jsonContents);
    
        // some code here  
        return new HttpResponseMessage(HttpStatusCode.Created);
        }
    

    希望这会有所帮助。

    【讨论】:

      【解决方案3】:

      您能否发布您的Feed 课程,以确保属性匹配。

      var data = {
           token: "4",
           feed: {Id:0,Message:"Hello World",UserId:4}
      }
      
      $.ajax({
                  url: "/api/Feed/",
                  dataType: 'json',
                  type: 'Post',
                  data: JSON.stringify(data)
              });
      

      【讨论】:

      • @TrueBlueAussie,已更新 - 我以为是提要,因为 / 不见了。
      • 这是我的 Feed 类,public class Feed { public int Id { get;放; } 公共字符串消息 { 获取;放; } 公共 int 用户 ID { 获取;放; } }
      • 属性不匹配,它们区分大小写。我会更新的。
      【解决方案4】:

      从编写视图模型开始:

      public class MyViewModel
      {
          public string Token { get; set; }
          public Feed Feed { get; set; }
      }
      

      您的控制器操作将作为参数:

      [HttpPost]
      public HttpResponseMessage Post(MyViewModel model)
      {
          /* Some code */
      
          return new HttpResponseMessage(HttpStatusCode.Created);
      }
      

      最后调整您的 jQuery 调用以将其作为 JSON 发送:

      $.ajax({
          url: url,
          type: 'POST',
          contentType: 'application/json',
          data: JSON.stringify({
              token: '4',
              feed: {
                  id: 0,
                  message: 'Hello World',
                  userId: 4
              } 
          })
      });
      

      AJAX 调用的重要注意事项:

      • 将请求contentType设置为application/json
      • 将数据包装在 JSON.stringify 函数中以有效地将 javascript 对象转换为 JSON 字符串
      • 删除了无用的dataType: 'json' 参数。 jQuery 会自动使用服务器发送的Content-Type 响应头来推断如何解析传递给success 回调的结果。

      【讨论】:

      • 不,这绝对不是真的。 Web API 使用的 Newtonsoft JSON 序列化器将完美地处理这种情况。这允许根据语言编写语义正确的变量名:在 JS 变量名以小写字母开头,而在 C# 中,属性名以大写字母开头。
      • @DarinDimitrov 你的意思是我不能在 POST API 中使用多个参数?
      • 你可以,但是模型活页夹会让你的生活变得更加艰难。真是一团糟。在此处阅读:blogs.msdn.com/b/jmstall/archive/2012/04/16/… 阅读完本文后,您将绝对忘记传递多个参数,而只需按照我的答案中所示的正确方式进行操作-使用视图模型。这样您就不必担心哪个参数是从哪个身体或头部绑定的。您只有一个参数,即您的视图模型,客户端直接将其作为 JSON 字符串发送到请求负载中。
      • 我同意@DarinDimitrov(很难不同意有 464k 点的人 :))使用视图模型的方法,这肯定会让事情变得更干净
      【解决方案5】:

      试试这个服务器端(从内存你只能有一个 FromBody 参数,所以它需要包含所有传入的属性):

      public class TokenAndFeed
      {
          public String token {get; set;}
          public Feed feed {get; set;}
      }
      
       public HttpResponseMessage Post([FromBody]TokenAndFeed tokenAndFeed)
       {
          /* Some code */
      
          return new HttpResponseMessage(HttpStatusCode.Created);
       }
      

      【讨论】:

      • @Mohsin JK:我的错……我认为你只能有一个 [FromBody] 参数,所以它必须包含你的两个对象。
      猜你喜欢
      • 2015-11-14
      • 1970-01-01
      • 1970-01-01
      • 2012-12-18
      • 1970-01-01
      • 2015-08-11
      • 2010-12-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多