简体   繁体   中英

ASP.NET Web API CreatedAtRoute return 500 Internal Server Error

I'm trying to build a test web API controller, just for the purpose of understanding web API. I'm wrote the following web API controller:

[Route("api/books")]
public class BookController : Controller
{

    public IEnumerable<Book> Get()
    {
        List<Book> books = new List<Models.Book>();
        books.Add(new Book { Title = "Test Title 1", Author = "Test Author 1", ISBN = "Test ISBN 1" });
        books.Add(new Book { Title = "Test Title 2", Author = "Test Author 2", ISBN = "Test ISBN 2" });

        return books;
    }

    [HttpGet("{id}")]
    public Book Get(int id)
    {
        return new Book { Title = "Test Title 1", Author= "Test Author 1", ISBN="Test ISBN 1", PublishingDate = DateTime.Today.AddYears(-90).AddDays(-73) };
    }


    //[HttpPost]
    //public IActionResult Post([FromBody]Book book)
    //{
    //    string str = "Post request received";

    //    return new JsonResult(str);
    //}


    [HttpPost]
    public IActionResult Post([FromBody]Book book)
    {            
        //return CreatedAtRoute("abi/books", new { controller = "Book", id = 1  }, book);
        //return CreatedAtRoute("Get", new { controller = "Book", id = 1  }, book);
        //return CreatedAtRoute("Get", book);
        //return CreatedAtRoute("abi/books", book);
        return CreatedAtRoute("abi/books/1", book);
    }
}

The Get and Get(id) methods work fine. The commented port method also works fine. In the other post method, I'm trying to use the CreatedAtRoute method. When I call this action using the postman tool, it returns 500 internal server error . I tried several alternatives for the method parameters (as you can see in the comment return statements) but non of them worked.

This is the detailed error that I get:

System.InvalidOperationException: No route matches the supplied values.

at Microsoft.AspNetCore.Mvc.CreatedAtRouteResult.OnFormatting(ActionContext context)

at Microsoft.AspNetCore.Mvc.Internal.ObjectResultExecutor.ExecuteAsync(ActionContext context, ObjectResult result)

at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__32.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)

at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__31.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__29.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)

at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__23.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__18.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)

at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

at Microsoft.AspNetCore.Builder.RouterMiddleware.d__4.MoveNext()

--- End of stack trace from previous location where exception was thrown ---

at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)

at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.d__6.MoveNext()

Any help is highly appreciated

The problem seems to be a misspelling in your HTTP POST return statement ( abi should be api ). Fixing that should do it. Also, it might be better to specify a route name for your HTTP GET method (ie, GetBook). And in your HTTP POST return statement, pass in the route name along with the route value and object. Also, you should wrap your book object in an ObjectResult before you return it in you HTTP GET method.

// GET /api/books/{id}
[HttpGet("{id}", Name = "GetBook")]
public IActionResult Get(int id)
{
    var book = new Book { 
        Title = "Test Title 1", 
        Author = "Test Author 1", 
        ISBN="Test ISBN 1", 
        PublishingDate = DateTime.Today.AddYears(-90).AddDays(-73) 
    };
    return new ObjectResult(book);
}

// POST api/books
[HttpPost]
public IActionResult Post([FromBody] Book book)
{
    if (book == null)
    {
        return BadRequest();
    }

    // code to add book to database
    //_context.Books.Add(book);
    //_context.Books.SaveChanges();

    return CreatedAtRoute(
        routeName: "GetBook",
        routeValues: new { id = 1 },
        value: book);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM