博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
asp.net web api [FromBody]参数
阅读量:7113 次
发布时间:2019-06-28

本文共 7195 字,大约阅读时间需要 23 分钟。

  hot3.png

Using jQuery to POST [FromBody] parameters to Web API

时间2013-04-04 00:28:17 原文

square-peg-round-holeASP.NET Web API has been one of my favorite recent additions to ASP.NET. Whether you prefer a RESTful approach or something more RPC-oriented, . Even if you’re still using ASP.NET WebForms,   – a nice example of the “One ASP.NET” philosophy that’s finally beginning to come together.

However, ASP.NET Web API throws an unintuitive curveball at you when you want to accept simple primitive types as parameters to POST methods. Figuring this issue out is particularly confusing because it’s one of the rare parts of Web API that violates .

Because of that, using jQuery to interact with those methods requires a slight contortion that seems strange at first, but makes sense once you understand why it’s necessary. In this post, I’ll briefly describe the underlying issue and show you how jQuery can be convinced to work around the issue.

POSTing primitive parameters to Web API

There are three things you need to know about Web API if you want to go the route of POSTing a primitive type (e.g. string, int, or bool) to a method. For example, say you’re working with this straightforward POST method in a Web API controller named ValuesController :

// POST api/valuespublic string Post(string value) {  return value;}

You might try POSTing a value into that Web API method using a standard jQuery$.post , like this:

$.post('/api/values', { value: 'Dave' });

If you inspect the server’s response to that request, you’ll be greeted with a bewildering 404 error:

Confronted with that response, it’s only natural to treat the problem as an issue with your routing configuration and debug from there, but that’s not the issue.

1. Parameters must be marked as [FromBody]

As it turns out, the reason for that 404 error isn’t a routing problem. ASP.NET correctly identifies our  ValuesController as the controller to handle a POST to/api/values , but it can’t locate an acceptable method to process the request.

The reason for that is a twofold mismatch between the required parameter that Web API expects to accompany requests to our Post  method and what we sent. The first of those mismatches is that the method’s parameter must be decorated with the[FromBody] attribute.

[FromBody] directs Web API to search for the parameter’s value in the body of a POST request. Adding that directive to our method is easy enough:

// POST api/valuespublic string Post([FromBody]string value) {  return value;}

I can’t say that I understand why this extra hassle is necessary, especially since it wasn’t required in WCF Web API and preliminary versions of ASP.NET Web API , but it’s easy enough as long as you’re aware that it needs to be present.

Adding [FromBody] fixes our 404 error, but things unfortunately still aren’t working quite right. Making the same request to it again works, but the value parameter is coming back as null now instead of the provided value:

2. Only one parameter per method

Speaking of the parameters to our method, another potentially confusing thing about accepting [FromBody] parameters is that there can be only one .

Attempting to accept multiple parameters from the POST body will result in a (refreshingly decipherable) server-side error along these lines:

Can’t bind multiple parameters (‘foo’ and ‘bar’) to the request’s content.

It’s possible to circumvent this limitation by using manual parsing techniques, but that seems antithetical to Web API and model binding to me. If you want Web API to automatically convert POST data to your [FromBody] input parameter, you have to limit yourself to only a single parameter.

I believe the thinking here is that, especially in a RESTful API, you’ll want to bind data to the single  resource  that a particular method deals with. So, pushing data into several loose parameters isn’t the sort of usage that Web API caters to.

This limitation can be a bit confusing when you’re coming from WebForms or MVC though, and trying work around it feels like going against the grain of the framework. So, if I need to accept more than one POST parameter, I just define a quick view model.

In other words, don’t try to do this:

public string Post([FromBody]string FirstName,                   [FromBody]string LastName) {  return FirstName + " " + LastName;}

Instead, work with the framework and do something like this if you need to accept more than a single parameter:

// DTO or ViewModel? Potato or potato, IMO.public class PersonDTO {  public string FirstName { get; set; }  public string LastName { get; set; }}   public string Post(PersonDTO Person) {  return Person.FirstName + " " + Person.LastName;}
3. [FromBody] parameters must be encoded as =value

The final hurdle remaining is that Web API requires you to pass  [FromBody]parameters in a particular format. That’s the reason why our value parameter was null in the previous example even after we decorated the method’s parameter with[FromBody] .

Instead of the fairly standard key=value encoding that most client- and server-side frameworks expect, Web API’s model binder expects to find the [FromBody]values in the POST body without a key name at all. In other words, instead ofkey=value , it’s looking for =value .

This part is, by far, the most confusing part of sending primitive types into a Web API POST method. Not too bad once you understand it, but terribly unintuitive and not discoverable.

What not to do

Now that we’ve covered what you need to know about the server-side code, let’s talk about using jQuery to POST data to [FromBody] parameters. Again, here’s the Web API method that we’re trying to POST data into:

// POST api/valuespublic string Post([FromBody]string value) {  return value;}

You’ll have a hard time finding a  jQuery $.post (or $.ajax ) example that conforms to the =value  encoding approach. Typically, platform-agnostic jQuery documentation and tutorials suggest that one of these two approaches should work:

// Value will be null.$.post('api/values', value);   // Value will be null.$.post('api/values', { key: value });

Unfortunately, neither of those work with Web API in the case of [FromBody]parameters (the latter would work to send an object, rather than a single primitive value). In both cases, our method will be invoked, but the model binder won’t assign anything to  value and it will be null .

Making it work

There are two ways to make jQuery satisfy Web API’s encoding requirement. First, you can hard code the = in front of your value, like this:

$.post('api/values', "=" + value);

Personally, I’m not a fan of that approach. Aside from just plain looking kludgy, playing fast and loose with JavaScript’s type coercsion is a good way to find yourself debugging .

Instead, you can take advantage of how jQuery encodes object parameters to$.ajax , by using this syntax:

$.post('api/values', { '': value });

If the data parameter has properties with empty string keys, jQuery serializes those properties in the form of =value . And, that’s exactly what we need to make Web API happy:

相关主题
如果你感兴趣

喜 欢 收 藏

分享该文章

分享到

该来源最新文章

  • 2014-02-14 03:26:54
  • 2014-02-01 01:30:22
  • 2014-01-22 17:30:45
  • 2014-01-08 02:27:27
  • 2013-12-11 04:25:23

转载于:https://my.oschina.net/wzzz/blog/268578

你可能感兴趣的文章
你需要知道面试中的10个JavaScript概念
查看>>
TiDB RC4 Release
查看>>
阿里云有对手了!CDN横评:腾讯云优势明显
查看>>
Ajax常用方法
查看>>
Glide 简单流程分析
查看>>
Hmily 2.0.3 发布,高性能异步分布式事务 TCC 框架
查看>>
烟花年下岁月
查看>>
Java源码阅读之HashMap - JDK1.8
查看>>
Docker 构建统一的前端开发环境
查看>>
一文让你了解大数据时代,你的真实处境
查看>>
Problems at works
查看>>
Dell服务器系统安装后无法正常进入系统
查看>>
深入理解asp.net里的HttpModule机制
查看>>
java基础学习_常用类03_StringBuffer类、数组高级和Arrays类、Integer类和Character类_day13总结...
查看>>
Asp.net MVC Session过期异常的处理
查看>>
python ThreadPoolExecutor线程池使用
查看>>
IPTABLES 规则(Rules)
查看>>
关于URL编码
查看>>
深度学习的可解释性研究(一):让模型「说人话」
查看>>
QT5提示can not find -lGL的解决方法
查看>>