What the difference between [FromRoute] and [FromB

2020-02-26 06:15发布

What the difference between [FromRoute] and [FromBody] in a Web API?

[Route("api/Settings")]
public class BandwidthController : Controller
{
    // GET: api/Settings
    [HttpGet]
    public IEnumerable<Setting> GetSettings()
    {
        return _settingRespository.GetAllSettings();
    }

    // GET: api/Settings/1
    [HttpGet("{facilityId}", Name = "GetTotalBandwidth")]
    public IActionResult GetTotalBandwidth([FromRoute] int facilityId)
    {
        if (!ModelState.IsValid)
        {
            return HttpBadRequest(ModelState);
        }
    }
}

Also for PUT:

// PUT: api/Setting/163/10
[HttpPut]
public void UpdateBandwidthChangeHangup([FromRoute] int facilityId, int bandwidthChange)
{
    _settingRespository.UpdateBandwidthHangup(facilityId, bandwidthChange);
}

Can I use [FromBody]?

1条回答
虎瘦雄心在
2楼-- · 2020-02-26 06:26

FromBody

Specifies that a parameter or property should be bound using the request body.

When you use FromBody attribute you are specifying that the data is coming from the body of the request body and not from the request URL/URI. You cannot use this attribute with HttpGet requests, only with PUT,POST,and Delete requests. Also you can only use one FromBody attribute tag per action method in Web API (if this has changed in mvc core I could not find anything to support that).

FromRouteAttribute

Summary: Specifies that a parameter or property should be bound using route-data from the current request.

Essentially it FromRoute will look at your route parameters and extract / bind the data based on that. As the route, when called externally, is usually based on the URL. In previous version(s) of web api this is comparable to FromUri.

[HttpGet("{facilityId}", Name = "GetTotalBandwidth")]
public IActionResult GetTotalBandwidth([FromRoute] int facilityId)

So this would try to bind facilityId based on the route parameter with the same name.

Complete route definition: /api/Settings/GetTotalBandwidth/{facilityId}
Complete received url: /api/Settings/GetTotalBandwidth/100

Edit

Based on your last question, here is the corresponding code assuming you want 163 to be bound to facilityId and 10 to bandwidthChange parameters.

// PUT: api/Setting/163/10

[HttpPut("{facilityId}/{bandwidthChange}")] // constructor takes a template as parameter
public void UpdateBandwidthChangeHangup([FromRoute] int facilityId, [FromRoute] int bandwidthChange) // use multiple FromRoute attributes, one for each parameter you are expecting to be bound from the routing data
{
    _settingRespository.UpdateBandwidthHangup(facilityId, bandwidthChange);
}

If you had a complex object in one of the parameters and you wanted to send this as the body of the Http Request then you could use FromBody instead of FromRoute on that parameter. Here is an example taken from the Building Your First Web API with ASP.NET Core MVC

[HttpPut("{id}")]
public IActionResult Update([FromRoute] string id, [FromBody] TodoItem item);

There are also other options in MVC Core like FromHeader and FromForm and FromQuery.

查看更多
登录 后发表回答