2017-07-27 7 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 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

2つのこと

public class TestController : ApiController 
{ 
    [HttpPost] 
    public void TakeIt([FromBody]MyObject o){ 
     Console.Write(o.ToString()); 
    } 
} 

タグそれは実際に規則ベースのルーティング、および次のタグ[FromBody]でパラメータに適合していないようHttpPostとアクションはとてもモデルバインダーは、どこのモデルを検索する場所を知っています。

また、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 } 
); 

です。

あなたは、私が明示的に私はAPIのルートを変更することを述べている必要があります別のルート

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

または更新されたコントローラ

[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

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

のルーティング属性を使用するを追加する必要がありますどちらか{api/{controller}/{action}/{id} "へのマッパー。残念ながら、[FromBody]をパラメータにも[HttpPost]にもメソッドに追加しても、コントローラのバインドには何の違いもありません。私は設定がどこかに設定されていないと感じています。 – Jimbo

+0

@ジンボ私は同意する必要があります。 OPには情報を伝えるだけの十分な情報がありません。問題を再現し、解決策を見つけるのに役立つ[mcve]を提供してください。 – Nkosi

+0

Dammit、それは何か簡単だと分かっていました...私はなぜこのwasntの働きを説明するOPの詳細を入れました。あなたの努力に感謝します。 – Jimbo

関連する問題