C# Asp.Net Web API 2模型未自动绑定

C# Asp.Net Web API 2模型未自动绑定,c#,asp.net-web-api,model-binding,C#,Asp.net Web Api,Model Binding,简单ApiController方法: public class TestController : ApiController { public void TakeIt(MyObject o){ Console.Write(o.ToString()); } } 简单数据类型: public class MyObject{ public string V1{ get; set; } public string V2{ get; set; } } 简

简单ApiController方法:

public class TestController : ApiController
{
    public void TakeIt(MyObject o){
        Console.Write(o.ToString());
    }
}
简单数据类型:

public class MyObject{
    public string V1{ get; set; }
    public string V2{ get; set; }
}
简单帖子:

POST http://localhost:11026/api/test/takeit HTTP/1.1
Accept: application/json
Content-Type: application/json
Host: localhost:11026

{"V1":"Something","V2": "Something else"}
出于某种原因,MyObject o不会自动从JSON表单post主体绑定(即使在方法上的参数之前插入了
[FromBody]

我做错什么了吗

解决方案(DUH!)

为了调试传入的请求,我把它放在了我的global.asax中(因为我无法让请求通过Fiddler),这样我就可以先检查它们

    protected void Application_BeginRequest()
    {
        using (Stream receiveStream = Request.InputStream)
        {
            using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8))
            {
                var content = readStream.ReadToEnd();
                Console.WriteLine(content);
            }
        }
    }

这会阻止任何东西读取发布的数据。我一删除它,自动模型绑定就工作得很好。

我想你要么需要用[HttpPost]来修饰你的方法,要么将它重命名为PostTakeIt。我相信Web API默认为获取。

两件事

public class TestController : ApiController
{
    [HttpPost]
    public void TakeIt([FromBody]MyObject o){
        Console.Write(o.ToString());
    }
}
使用
HttpPost
标记操作,因为它实际上不符合基于约定的路由,然后使用
[FromBody]
标记参数,以便模型绑定器知道在哪里查找模型

另外,给定URI
api/test/takeit
,这里的假设是路由模板是
api/{controller}/{action}

默认模板通常是
api/{controller}/

// Convention-based routing.
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
这与动作名称不符

您可能需要添加另一条路线

// Convention-based routing.    
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);

config.Routes.MapHttpRoute(
    name: "DefaultActionApi",
    routeTemplate: "api/{controller}/{action}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
或者使用属性路由

// Attribute routing.
config.MapHttpAttributeRoutes();

// Convention-based routing.
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
使用更新的控制器

[RoutePrefix("api/test")]
public class TestController : ApiController
{
    [HttpPost]
    [Route("takeit")] //Matches POST api/test/takeit
    public IHttpActionResult TakeIt([FromBody]MyObject o){
        Console.Write(o.ToString());
        return Ok();
    }
}

我应该明确指出,我将API路由映射器更改为“API/{controller}/{action}/{id}”。不幸的是,既没有将[FromBody]添加到参数中,也没有将[HttpPost]方法对我的控制器上的绑定有任何影响。我有一种感觉,它是缺少某个配置设置的地方。@Jimbo我必须同意。OP中没有足够的信息来说明。提供一个可以用来重现问题并帮助找到解决方案的方法。该死,我知道这很简单…我有put更多信息在我的OP中解释为什么这不起作用。谢谢你的努力。