Asp.net web api ASP.Net Web API 2属性路由HTTP POST操作未获取正确的参数

Asp.net web api ASP.Net Web API 2属性路由HTTP POST操作未获取正确的参数,asp.net-web-api,asp.net-web-api2,asp.net-web-api-routing,Asp.net Web Api,Asp.net Web Api2,Asp.net Web Api Routing,我有一个简单的ASP.Net Web API 2控制器: public class TestController : ApiController { [Route("api/method/{msg?}")] [AcceptVerbs("GET", "POST")] public string Method(string msg = "John") { return "hello " + msg; } } 和一个简单的HTML表单来测试它

我有一个简单的ASP.Net Web API 2控制器:

public class TestController : ApiController
{
    [Route("api/method/{msg?}")]
    [AcceptVerbs("GET", "POST")]
    public string Method(string msg = "John")
    {
        return "hello " + msg;
    }
}
和一个简单的HTML表单来测试它

<form action="/api/method/" method="post">
    <input type="text" name="msg" value="Tim" />
    <input type="submit" />
</form>
=============编辑2==========

我没有更改默认路由,因此它仍然是这样的:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}

如果您使用的是html
表单
,则
POST
方法中的参数不会立即反序列化。获取
msg
的值

[HttpPost]
[路线(“api/方法”)]
公共字符串方法([FromBody]字符串消息)
{
返回“hello”+msg;
}
否则,必须使用
Fiddler
(或类似的web调试器)调用
POST
方法,并将
msg
作为查询字符串传递

如果您确实希望使用
HTML表单
,而不使用
[FromBody]
属性,请尝试以下操作

[HttpPost]
[路线(“api/方法”)]
公共字符串方法()
{
var msg=Request.Content.ReadAsFormDataAsync();
var res=msg.Result[“msg”];
返回“hello”+res;
}

出于兴趣,为什么对GET和POST请求使用相同的方法?通常,GET用于检索资源,UPDATE/POST用于修改资源。在这种情况下,该方法接受这两个动词没有什么意义——如果我不得不打赌,如果你把这两个方法分开,你的问题就不会成为问题。真正的应用程序可能只使用POST,但GET更容易在浏览器中粘贴为URL。所以除非有一个很好的理由去区分,否则我就不麻烦了。这取决于你是否认为违反休息原则是一个很好的理由。我会的!事实上,虽然这不是我要问的。我已编辑该问题,为您添加了一个仅限POST的控制器。您是否更改了默认路由配置?如果是的话,请把它也贴出来。谢谢。有趣的是,
[FromBody]
似乎不适用于可选参数。例如,如果我将代码更改为
公共字符串方法([FromBody]string msg=“John”)
,则调用将失败,出现
InvalidOperationException
,并显示消息“可选参数'msg'不受'FormatterParameterBinding'支持”。我发现
[FromBody]的解决方法
使用可选的简单类型参数是为了不使其成为可选的,并且根据您是否有可选参数的值,以不同的方式构造请求主体:
=stringvalue
然后
msg
将成为WebAPI中的
“stringvalue”
msg=
然后
msg
将在WebAPI中
null
。您必须在控制器方法中定义默认值
“John”
,但这将消除
无效操作异常。不要忘记将
内容类型
标题设置为
应用程序/x-www-form-urlencoded
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();
        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
    }
}