在Web API中,[FromRoute]
和[FromBody]
有什么区别?
[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);
}
}
}
同样适用于PUT
:
// PUT: api/Setting/163/10
[HttpPut]
public void UpdateBandwidthChangeHangup([FromRoute] int facilityId, int bandwidthChange)
{
_settingRespository.UpdateBandwidthHangup(facilityId, bandwidthChange);
}
我可以使用[FromBody]
吗?
2条答案
按热度按时间kxeu7u2r1#
指定应使用请求正文绑定参数或属性。
使用
FromBody
属性时,指定数据来自请求正文的正文,而不是来自请求URL/URI。不能将此属性用于HttpGet
请求,只能用于PUT、POST、和删除请求。此外,在Web API中,每个操作方法只能使用一个FromBody
属性标记(如果这在MVC核心中发生了变化,我找不到任何支持它的东西)。摘要:指定应使用当前请求中的路由数据绑定参数或属性。
本质上,
FromRoute
会查看您的路由参数,并基于此提取/绑定数据。当外部调用路由时,通常基于URL。在以前版本的web api中,这与FromUri
相当。因此,这将尝试基于具有相同名称的route参数绑定
facilityId
。编辑
根据您的上一个问题,假设您希望将163绑定到facilityId,将10绑定到bandwidthChange参数,下面是相应的代码。
如果您在其中一个参数中有一个复杂对象,并且您希望将其作为Http请求的主体发送,那么您可以在该参数上使用
FromBody
而不是FromRoute
。MVC核心中还有其他选项,如
FromHeader
、FromForm
和FromQuery
。kr98yfug2#
混淆[从路线]与[从车身]
微软在ASP.NET方面做得很好,它试图将互联网技术连接到他们的框架和系统中。但是在这个过程中,他们常常试图在非常简单的HTTP和HTML技术之上修补他们的技术解决方案,从而使开发人员感到困惑。人们认为他们的解决方案代表了万维网的工作方式......而实际上它根本没有。NET框架和核心版本的ASP.NET仍然令许多人困惑。
希望这能帮上忙...
当你在ASP.NET核心中创建一个基本的"路由"时,**你将你的浏览器的 * URL地址路径 * 绑定到一个特定的 * Controller类和它的子方法()(在ASP.NET编译的应用程序中)。绑定意味着他们设计的 * Middleware * 会嗅探URL地址,并尝试将其分解,然后将这些片段与你网站中的代码进行匹配。
特殊的Controller-ControllerBase类在ASP.NET中使用Map到类中的子方法的常规路由模板和路由属性来处理此过程。这包括这些方法的 * 参数 *。然后,这将所有URL浏览器地址路径请求"路由"到ASP.NET中Web应用程序中的特定代码集。
不幸的是,有太多的方式来配置这个绑定。在过去,它是一堆随机组合的路由模板到控制器和方法,与额外的代码Map一个url到参数。但这并不总是明确的东西,如 * 查询字符串 *。ASP.NET核心试图清理这些混乱的新属性路由装饰,如[FromRoute]等。
那么它们是如何工作的呢?
在最简单的形式中,ASP.NET MVC或WebAPI使用"route"文本字符串将特定的方法参数名称Map到匹配的URL路径。
[FromRoute]
通过将方法参数名称显式绑定到{}
中URL的匹配部分来提供帮助:然而,
[FromRoute]
属性修饰是可选的,因为ASP.NET中的中间件在默认情况下会尝试为您Map它。如果您关闭[FromRoute]
,它会尝试将您的参数名称Map到{}
中的路由模板名称,如下所示:然而,根据微软的说法,
[FromQuery]
只绑定到Querystring URL参数,这些参数位于URL路由之外。但我一直认为它们是URL的一部分。在ASP.NET的过去版本中,这一点被忽略了,所以人们不得不捏造一种方法来使用Request.QueryString
在方法内部获取这些值。因此,这个新特性解决了这个问题:[FromBody]完全不同!
从
POST
捕获数据总是很棘手。ASP.NET通过允许路由URLMap系统在侦听POST和URL请求时正常工作,但使用额外的方法参数属性系统绑定到使用[FromBody]
传入的数据,来帮助解决这个问题。对于POST HTTP VERB类型,POST是唯一的,因为POST与URLMap无关。2但是在这个例子中,ASP.NET使用属性参数绑定系统来为你抓取表单域数据。我们先来看看
POST
* 表单域 * 是如何工作的。当您使用"method = post"发送HTML表单数据时,如下所示:
...发送封装在请求"主体"内的表单字段数据,如POST:
请注意,表单字段POST数据位于请求post(
field1=hello&mybutton=submit
)的特殊"body"或有效负载部分中。要获取该数据,需要在ASP.NET参数修饰中使用[FromForm]
(用于传统的名称-值表单POST数据)或[FromBody]
(仅用于特殊的JavaScript JSON Post数据),如下所示:[FromForm]
在WebAPI POST端点中将常规HTML POST表单字段(一个字段或所有字段)捕获为 * 名称-值 * 对。[FromBody]
捕获表单字段,但仅作为JSON数据捕获,需要在发送到服务器的POST请求中添加额外的内容类型"application/json"。由于HTML表单无法执行此操作,因此在使用[FromBody]
时必须使用JavaScript。因此,
[FromBody]
几乎总是与POST一起使用,与[FromRoute]或[FromQuery]可能做的那样将Route Template绑定为URL的一部分无关,而只是捕获通常在HTTP请求包内发送的POST请求表单提交中找到的任何POST数据。希望能有所帮助!