ASP.NET Core"CreatedAtRoute"失败

Bre*_*ias 26 c# asp.net-core

在我的ASP.NET Core应用程序中,我有一个像这样的控制器动作:

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

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

上面的代码按预期工作.但是,如果我使用内置方法"CreatedAtRoute",那么我得到一个例外:

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

    return CreatedAtRoute("SubscriberLink", new { id = subscriber.ID });
}
Run Code Online (Sandbox Code Playgroud)

例外是:

System.InvalidOperationException:没有路由匹配提供的值.

该异常导致服务返回500状态代码.

在任何一种情况下都是相同的路由,所以我不知道为什么第一个例子正常工作而第二个例子没有.

project.json包含这个:

"frameworks": {
  "dnx46": { },
  "dnxcore50": { }
},
Run Code Online (Sandbox Code Playgroud)

为了参考起见,命名路由由两部分组成.首先是控制器前缀:

[Route("api/[controller]")]
public class SubscribersController : Controller
{
    // ...
}
Run Code Online (Sandbox Code Playgroud)

其次是GET操作,其中实际"SubscriberLink"路由命名为:

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

思考?

Sha*_*tin 39

简答

你正在使用错误的重载CreatedAtRoute.使用带有三个参数的重载.

工作实例

例如,以下工作在我的机器上.

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

细节

结果是201响应.响应的主体包含我们创建的实体(value参数)的详细信息,响应的Location头包含实体的URI.

响应包括我们创建的obj及其位置.

有三个重载CreatedAtRoute.

CreatedAtRoute(object routeValues, object value)
CreatedAtRoute(string routeName, object value)
CreatedAtRoute(string routeName, object routeValues, object value)
Run Code Online (Sandbox Code Playgroud)

如果我们想传递路由名称和路由值,我们使用带有三个参数的重载.如果我们不想返回我们创建的实体的细节,我们可以传递null第三个参数,

  • 卫生署!我认为第一次和第二次重载都是误导和误解.每当提供一个`Location`标题时,**肯定**有必要提供****相关路由和`routeValues`.相反,永远不必为回复提供内容.所以,那些重载都被淹没了恕我直言.简而言之,此时只有第三个重载具有任何值.谢谢你的提醒! (4认同)