【问题标题】:Using BeginForm to post form data to an ASP.NET MVC API controller使用 BeginForm 将表单数据发布到 ASP.NET MVC API 控制器
【发布时间】:2013-09-19 01:27:31
【问题描述】:

基本上,我有一个 API 控制器,方法如下:

public void Post([FromBody] string value)
{
   Repository.Save(value);
}

我这样构造我的表单:

@using (Ajax.BeginForm(new AjaxOptions { HttpMethod = "Post", Url = "/api/MyController"}))
{
   <input type="text" name="value" value="" />
   <input type="submit" value="Post" />
}

请求被路由到控制器,但由于某种原因,始终为空。我尝试过使用和不使用 [FromBody] 属性。

可以显然将 value 查询字符串参数附加到 URL,但我真的想弄清楚如何使用简单类型发布表单数据(而不是创建我自己的 DTO 类型)。

谢谢!

【问题讨论】:

  • 当您在调试中运行并在return Repository.Save(value) 上停止时(Save 也是无效的吗?),value 的值是多少?
  • Save 方法返回一个 int。 value 参数始终为 null。
  • 你的代码编译了吗?因为当你的方法是 void 时,如果你想返回任何东西,你应该只返回一个 void
  • 啊,抱歉,更新了代码 sn-p(为了清楚起见,我之前清理了它,不小心留下了 return 关键字)。 action 方法和 Save 方法实际上都返回整数,但无论哪种方式都不会影响 value 参数。 ://
  • 我对 Ajax.BeginForm 了解不多,但是通过 Fiddler/Browser 的诊断,能否告诉我们请求正文中的内容是什么样的?是form-url编码格式还是json格式?

标签: asp.net asp.net-mvc asp.net-web-api


【解决方案1】:

默认情况下,Web API 会尝试从请求 URI 中获取简单类型。 FromBody 属性告诉 Web API 从请求正文中读取值。

Web API 最多读取一次响应正文,因此一个动作的一个参数只能来自请求正文。如果您需要从请求正文中获取多个值,请定义一个复杂类型。

其次,客户端需要发送如下格式的值:

=值

不是这样的:

值=foo

因此,如果您像 $.post('/api/myapicontroller', { "": $('#myinput').val() }); 这样发布数据,它应该可以正常工作,如果您想发送简单类型的数组,只需像这样发送数据 $.post('/api/myapicontroller', { "": ["update one", "update two", "update three"] });

如果您使用 Fiddler,只需将 =John+Smith 添加到请求正文并确保您具有正确的内容类型,如下所示:Content-Type: application/x-www-form-urlencoded

【讨论】:

  • 是的,我现在使用了我自己的 DTO 类型,尽管我真的只需要一个字符串值......添加“=”的方法似乎有点 hacky? :) 我的想法是能够将 Razor 助手用于表单,以避免不得不滚动我自己的脚本来发布值 - 我认为这会使 UI 代码更清晰。现在我几乎认为使用复杂类型是更简单的方法?
  • @TedNyberg 我同意这感觉有点骇人听闻,但根据 HTTP 规范它是正确的。是的,使用复杂类型更简单,在我看来,这是将数据发布到 Web api 控制器的首选方式。
猜你喜欢
  • 2014-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-07
  • 2018-04-30
  • 2016-07-12
  • 2015-01-31
  • 2012-09-08
相关资源
最近更新 更多