2017-07-27 35 views
1

简单ApiController方法:Asp.Net的Web API 2模式不会自动绑定

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:

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表单发布主体绑定(即使在参数前插入[FromBody]在方法上。

我做错了什么?

SOLUTION(DUH!)

调试我传入的请求,我在Global.asax中已经把这个(因为我没能拿到请求通过提琴手流),这样我就可以先检查它们

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

这是从读取数据发布任何停止的路线。不久,我删除了,自动模型绑定工作正常。

回答

1

我想你要么用[HttpPost]来装饰你的方法,要么把它重命名为PostTakeIt。我相信Web API默认为GET。

1

两件事情

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(); 
    } 
} 
+0

我应该明确表示,我改变了API路线映射到“api/{controller}/{action}/{id}”。不幸的是,既不向该方法添加[FromBody],也不向该方法添加[HttpPost],这对我的控制器上的绑定没有任何影响。我有一种感觉,它的配置设置丢失的地方。 – Jimbo

+0

@Jimbo我必须同意。 OP中没有足够的信息用于说明。提供可用于重现问题并帮助找到解决方案的[mcve]。 – Nkosi

+0

该死的,知道这件事很简单......我已经在我的OP中提供了更多的信息,解释了为什么这不起作用。感谢您的努力。 – Jimbo

相关问题