iis - ASP.Net Core CreatedAtAction in HttpPost action returns 201 but entire request ends with 500 -
i'm following[1] setting first .net core webapi (moving "old" webapi). when httppost action, in tutorial:
[httppost] public iactionresult create([frombody] todoitem item) { if (item == null) { return badrequest(); } todoitems.add(item); return createdataction("gettodo", new { id = item.key }, item); } i httperror 500 after exiting controller. createdataction returns proper object status code 201 expect, , after method exits server somehow turns 500. don't seem able step rest of pipeline. trace gives me following error:
81. -general_request_entity 82. -notify_module_completion 83. -module_set_response_error_status [warning] 171ms modulename aspnetcoremodule notification execute_request_handler httpstatus 500 httpreason internal server error httpsubstatus 0 errorcode operation completed successfully. (0x0) configexceptioninfo everything (program.cs, startup.cs) set in[1]. behaves same in iisexpress (vs2015 update 3) , iis7.5 (windows 7). other return types, 200 (with new objectresult(item) get, 404 notfound() or 204 nocontentresult() put work ok. seems it's problem 201 somehow. ideas?
[1] https://docs.asp.net/en/latest/tutorials/first-web-api.html
update posting additional details per request:
startup.cs:
using system; using system.collections.generic; using system.linq; using system.threading.tasks; using firstwebapi.models; using microsoft.aspnetcore.builder; using microsoft.aspnetcore.hosting; using microsoft.extensions.configuration; using microsoft.extensions.dependencyinjection; using microsoft.extensions.logging; namespace firstwebapi { public class startup { public startup(ihostingenvironment env) { var builder = new configurationbuilder() .setbasepath(env.contentrootpath) .addjsonfile("appsettings.json", optional: true, reloadonchange: true) .addjsonfile($"appsettings.{env.environmentname}.json", optional: true) .addenvironmentvariables(); configuration = builder.build(); } public iconfigurationroot configuration { get; } // method gets called runtime. use method add services container. public void configureservices(iservicecollection services) { services.addmvc(); services.addlogging(); services.addsingleton<itodorepository, todorepository>(); } // method gets called runtime. use method configure http request pipeline. public void configure(iapplicationbuilder app, ihostingenvironment env, iloggerfactory loggerfactory) { loggerfactory.addconsole(configuration.getsection("logging")); loggerfactory.adddebug(); app.usedeveloperexceptionpage(); app.usestatuscodepages(); app.usemvc(); } } } todocontroller.cs:
using system.collections.generic; using firstwebapi.models; using microsoft.aspnetcore.mvc; namespace firstwebapi.controllers { [route("api/[controller]")] public class todocontroller : controller { public todocontroller(itodorepository todoitems) { todoitems = todoitems; } public itodorepository todoitems { get; set; } public ienumerable<todoitem> getall() { return todoitems.getall(); } [httpget("{id}", name = "gettodo")] public iactionresult getbyid(string id) { var item = todoitems.find(id); if (item == null) { return notfound(); } return new objectresult(item); } [httppost] public iactionresult create([frombody] todoitem item) { if (item == null) { return badrequest(); } todoitems.add(item); return createdataction("gettodo", new { id = item.key }, item); } [httpput("{id}")] public iactionresult update(string id, [frombody] todoitem item) { if (item == null || item.key != id) { return badrequest(); } var todo = todoitems.find(id); if (todo == null) { return notfound(); } todoitems.update(item); return new nocontentresult(); } [httpdelete("{id}")] public void delete(string id) { todoitems.remove(id); } } } update 2
turns out, createataction 201 tries redirect unhandled route:
system.invalidoperationexception: no route matches supplied values. @ microsoft.aspnetcore.mvc.createdatactionresult.onformatting(actioncontext context) still not sure why tho, method getbyid should mapped gettodo per controller settings.
so, after bit of debugging found caused it. turned out this.url.action("get", "gettodo", new { id=item.key }) return null , 500 came fact iis not match route attached 201.
as turns out, either need setup:
app.usemvc(routes => { routes.maproute( name: "default", template: "{controller}/{action}"); }); or use createatroute.
Comments
Post a Comment