Passing Multiple Parameters to ASP.NET Web API With jQuery

2 篇文章 0 订阅

ASP.NET MVC 4 Web API has limited support to map POST form variables to simple parameters of a Web API method. Web API does not deal with multiple posted content values, you can only post a single content value to a Web API Action method. This post explains the different ways to pass multiple parameters to Web API method.

Suppose You have following Web API method:

?
public HttpResponseMessage PostProduct(int Id,String Name,String Category, decimal Price)
{
         //...
}

and you are trying to call using jQuery:

?
$.ajax({
 
  url: 'api/products' ,
  type: 'POST' ,
  data: { Id: 2012, Name: 'test' , Category: 'My Category' , Price: 99.5 },
  dataType: 'json' ,
  success: function (data) {
alert(data);
}
 
});

Unfortunately, Web API can’t handle this request and you’ll get error. But if you pass parameters using query string, It’ll work:

?
$.ajax({
 
  url: 'api/products?Id=2012&Name=test&Category=My%20Category&Price=99.5' ,
  type: 'POST' ,               
  dataType: 'json' ,
  success: function (data) {
  alert(data);
   }
 
  });

But it’s not good solution and not applicable for complex objects. So here are the different ways to do it.

Using Model Binding:

Model: Create a model having all parameters to be passed

?
public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
        public decimal Price { get; set; }
    }

Controller: Use the model as argument type in the method

?
public HttpResponseMessage PostProduct(Product item)
  {
      item = repository.Add(item);
      var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item);
      string uri = Url.Link( "DefaultApi" , new { id = item.Id });
      response.Headers.Location = new Uri(uri);
      return response;
  }

jQuery:

?
$.ajax({
  url: 'api/products' ,
  type: 'POST' ,
  data: { Id: 2012, Name: 'test' , Category: 'My Category' , Price: 99.5 },
  dataType: 'json' ,
  success: function (data) {
                    ...
   }
});

OR

?
var product = {
             Id: 2012, Name: 'test' , Category: 'My Category' , Price: 99.5
}
 
$.ajax({
  url: 'api/products' ,
  type: 'POST' ,
  data: JSON.stringify(product),
  dataType: 'json' ,
  contentType: "application/json" ,
  success: function (data) {
 
  }
});

Using Custom Parameter Binding:

ASP.NET Web API provides to create a custom Parameter Binding to extend the functionality and allows you to intercept processing of individual parameters. Check Rick’s Post to implement it.

JObject:

Web API now uses JSON.NET for it’s JSON serializer, So you can use the JObject class to receive a dynamic JSON result, cast it properly or parse it into strongly typed objects.

?
public HttpResponseMessage PostProduct(JObject data)
        {
            dynamic json = data;
            Product item = new Product() {
                Id = json.Id,
                Name = json.Name,
                Category = json.Category,
                Price =json.Price
            };
            item = repository.Add(item);
            var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item);
            string uri = Url.Link( "DefaultApi" , new { id = item.Id });
            response.Headers.Location = new Uri(uri);
            return response;
        }

OR

You can directly parse it into strongly typed class:

?
public HttpResponseMessage PostProduct(JObject data)
        {
 
            Product item = data.ToObject<Product>(); 
            item = repository.Add(item);
            var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item);
            string uri = Url.Link( "DefaultApi" , new { id = item.Id });
            response.Headers.Location = new Uri(uri);
            return response;
        }

FormDataCollection:

You can define FormDataCollection type argument and read parameter one by one manually using .Get() or .GetValues() methods (for multi-select values).

data: { Id: 2012, Name: ‘test’, Category: ‘My Category’, Price: 99.5 },

For above data:

?
public HttpResponseMessage PostProduct(FormDataCollection data)
        {
            Product item = new Product() {
                Id = Convert.ToInt32(data.Get( "Id" )),
                Name = data.Get( "Name" ),
                Category = data.Get( "Category" ),
                Price = Convert.ToDecimal(data.Get( "Price" ))
            };
            item = repository.Add(item);
            var response = Request.CreateResponse<Product>(HttpStatusCode.Created, item);
            string uri = Url.Link( "DefaultApi" , new { id = item.Id });
            response.Headers.Location = new Uri(uri);
            return response;
        }

Query String:

We have seen to access multiple parameters from query string easily. It’s very helpful when you have to pass Model with additional parameters. So the additional parameters can be passed using query string.

Controller:

?
public HttpResponseMessage PostProduct(Product item, string criteria)
      {
      //...
      }

jQuery:

?
$.ajax({
   url: 'api/products?criteria=full' ,
   type: 'POST' ,
   data: JSON.stringify(product),
   dataType: 'json' ,
   contentType: "application/json" ,
   success: function (data) {
                }
            });

You can parse your query string explicitly in method If you have too many query string values to push into parameters.

?
public HttpResponseMessage PostProduct(Product item)
       {          
           var queryItems = Request.RequestUri.ParseQueryString();
           string criteria = queryItems[ "criteria" ];
           //...
   }

Return Multiple Parameters:

Now, the next question is how to return multiple parameters. First thing is to use Model having all parameters and return its instance, but each time we can’t create model for each return type. If all parameters have same data-type then we can create and return a collection. But it might be different data-types. The simplest solution is use dynamic return type.

?
public dynamic GetProducts()
        {
            var products = repository.GetAll() as IEnumerable<Product>;
            return new
            {
               Products = products,
               Criteria = "full"
            };
        }

Here is the response:

multiple parameters

Share your opinion how you are passing multiple parameters to Web API. Hopefully, this behavior can be enabled in future release without being a breaking change.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值