我正在尝试使用网络API来发布帖子请求。以下是我的api控制器。
public class WebsController : ApiController
{
[HttpPost]
public void PostOne(string id)
{
}
[HttpPost]
public void PostTwo(Temp id)
{
}
}
我已经改变了webapi路线以考虑行动。 Temp模型看起来像这样。
public class Temp
{
public string Id { get; set; }
}
我的观点看起来像这样
@using (Ajax.BeginForm(new AjaxOptions
{
Url = "/api/webs/postone",
HttpMethod = "post"
}))
{
<input name="id" id="id" value="2" />
<input type="submit" value="submit" />
}
以上代码根本不适用于postone,除非我将[FromBody]属性放在参数前面。
[HttpPost]
public void PostOne([FromBody]string id)
{
}
然后它命中了动作,但id仍为null。它不会填充文本框中的值。
但是,如果我将Url
的{{1}}更改为Ajax.BeginForm
,它会使用模型posttwo
,它可以很好地运行,Temp
字段可以获得文本框中的适当值。
任何人都可以向我解释一下这种情况发生的原因以及如何将简单的值发布到网络API动作中吗?我的意思是,为什么它可以绑定复杂类型而不是简单类型。
答案 0 :(得分:107)
自从我问这个问题以来,已经有一段时间了。现在我更清楚地理解它,我将提供一个更完整的答案来帮助他人。
在Web API中,记住参数绑定的发生方式非常简单。
POST
为简单类型,则Web API会尝试将其与网址绑定如果您POST
复杂类型,Web API会尝试将其绑定到主体
请求(这使用media-type
格式化程序)。
如果要从网址绑定复杂类型,则会在action参数中使用[FromUri]
。这种情况的局限性取决于您的数据将会持续多长时间以及它是否超过网址字符限制。
public IHttpActionResult Put([FromUri] ViewModel data) { ... }
如果要从请求正文绑定一个简单类型,您将在action参数中使用[FromBody]。
public IHttpActionResult Put([FromBody] string name) { ... }
作为旁注,假设您正在发出PUT
请求(只是一个字符串)来更新某些内容。如果您决定不将其附加到URL并作为复杂类型传递,模型中只有一个属性,那么jQuery ajax中的data
参数将如下所示。传递给data参数的对象只有一个属性为空属性的属性。
var myName = 'ABC';
$.ajax({url:.., data: {'': myName}});
并且您的网络API动作将如下所示。
public IHttpActionResult Put([FromBody] string name){ ... }
这个asp.net页面解释了这一切。 http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api