Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
303 views
in Technique[技术] by (71.8m points)

c# - ASP.NET Core "CreatedAtRoute" Failure

Inside my ASP.NET Core app I have a controller action like this:

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

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

The above code works as expected. However, if I use the built-in method "CreatedAtRoute", then I get an exception:

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

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

The exception is:

System.InvalidOperationException: No route matches the supplied values.

The exception causes the service to return a 500 status code.

It is the same route in either case, so I don't know why the first example works correctly and the second does not.

My project.json contains this:

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

For reference sake, the named route is composed from two pieces. First is the controller prefix:

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

Second is the GET action, where the actual "SubscriberLink" route is named:

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

Thoughts?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Short Answer

You are using the wrong overload of CreatedAtRoute. Use the overload that takes three arguments instead.

Working Example

For instance, the following works on my machine.

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

Details

The result is a 201 response. The response's body contains details of the entity we created (the value argument) and the response's Location header contains a URI to the entity.

The response includes the obj we created and its location.

There are three overloads for CreatedAtRoute.

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

If we want to pass a route name and route values, we use the overload that takes three arguments. If we do not want to return details of the entity we created, we can pass null for the third argument,


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...