2016-04-11 27 views
19

私はこのようなコントローラのアクションがあります。ASP.NETコア「CreatedAtRoute」障害

[HttpPost] 
public async Task<IActionResult> CreateSubscriber([FromBody] SubscriberDef subscriber) 
{ 
    //...implementation removed 

    var link = Url.Link("SubscriberLink", new { id = subscriber.ID }); 
     return Created(link, null); 
} 

期待通りに上記のコードは動作しますが。私は「CreatedAtRoute」ビルトインメソッドを使用する場合は、その後、私は例外を取得:

[HttpPost] 
public async Task<IActionResult> CreateSubscriber([FromBody] SubscriberDef subscriber) 
{ 
    //...implementation removed 

    return CreatedAtRoute("SubscriberLink", new { id = subscriber.ID }); 
} 

例外は次のとおりです。

のSystem.InvalidOperationException:Noルートは、供給された値と一致しません。

例外により、サービスは500のステータスコードを返すことになります。

どちらの場合も同じルートなので、最初の例が正しく動作し、2番目の例が正しく動作しない理由はわかりません。参照便宜上

"frameworks": { 
    "dnx46": { }, 
    "dnxcore50": { } 
}, 

、という名前のルートが2枚から構成されています

project.jsonが、これは含まれています。まず、コントローラの接頭辞である:

[Route("api/[controller]")] 
public class SubscribersController : Controller 
{ 
    // ... 
} 

第二には、実際の"SubscriberLink"ルートの名前がGETアクション、次のとおりです。

[HttpGet("{id}", Name = "SubscriberLink")] 
[SwaggerResponse(HttpStatusCode.OK, Type = typeof(Subscriber))] 
public async Task<IActionResult> GetSubscriber(Guid id) 
{ 
    //...implementation removed... 
    return Ok(subscriber); 
} 

思考?

+1

の3番目の引数にnullを渡すことができます。「SubscriberLink」ルート名はどこに定義されていますか? – haim770

+0

@ haim770最後のコードスニペットで定義されています。 –

+0

'var link = Url.Link(" SubscriberLink "、new {id = subscriber.ID});'正しいURLを返すか、例外をスローしないだけですか? – haim770

答えて

25

あなたはCreatedAtRouteの間違ったオーバーロードを使用している

短い答え。代わりに3つの引数をとるオーバーロードを使用してください。

作業例

例えば、次のものは私のマシンで動作します。

[Route("api/[controller]")] 
public class SubscribersController : Controller 
{ 
    public IActionResult Index() 
    { 
     var subscriber = new 
     { 
      Id = Guid.NewGuid(), 
      FirstName = "Shaun", 
      LastName = "Luttin" 
     }; 

     // overload with three arguments 
     return CreatedAtRoute(
      routeName: "SubscriberLink", 
      routeValues: new { id = subscriber.Id }, 
      value: subscriber); 
    } 

    [HttpGet("{id}", Name = "SubscriberLink")] 
    public IActionResult GetSubscriber(Guid id) 
    { 
     var subscriber = new 
     { 
      Id = id, 
      FirstName = "Shaun", 
      LastName = "Luttin" 
     }; 

     return new JsonResult(subscriber); 
    } 
} 

詳細

結果は、201応答です。応答の本文には、作成したエンティティの詳細(value引数)が含まれ、レスポンスのLocationヘッダーにはエンティティへのURIが含まれます。

The response includes the obj we created and its location.

CreatedAtRouteための3つのオーバーロードがあります。

CreatedAtRoute(object routeValues, object value) 
CreatedAtRoute(string routeName, object value) 
CreatedAtRoute(string routeName, object routeValues, object value) 

ルート名とルート値を渡したい場合は、3つの引数をとるオーバーロードを使用します。作成したエンティティの詳細を返さない場合は、

+0

あなたのケースでは名前ではなくルートテンプレートを設定しているので、[Route( "api/[controller]"、Name = "SubscriberLink")にする必要があります。 –

+1

これは間違っています。新しい 'HttpGetAttribute' *は' Name'プロパティを定義し、またルート名を提供する 'IRouteTemplateProvider'を実装します – haim770

+0

@ haim770それを修正しました。 :)フィードバックいただきありがとうございます。 –