簡體   English   中英

ASP.NET Web API 2模型不會自動綁定

[英]Asp.Net Web API 2 model not automatically 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; }
}

簡單的帖子:

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]

難道我做錯了什么?

解決方案(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默認為GET。

兩件事情

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM