Ich folge [1] für die Einrichtung meiner ersten .NET Core WebAPI (Wechsel von "alten" WebAPI). Als ich Httppost Aktion zu tun, wie in Tutorial:ASP.Net Core CreatedAtAction in der HttpPost-Aktion gibt 201 zurück, aber die gesamte Anfrage endet mit 500
[HttpPost]
public IActionResult Create([FromBody] TodoItem item)
{
if (item == null)
{
return BadRequest();
}
TodoItems.Add(item);
return CreatedAtAction("GetTodo", new { id = item.Key }, item);
}
Ich erhalte eine 500 nach meinen httperror-Controller zu verlassen. CreatedAtAction
gibt das richtige Objekt mit Statuscode 201 zurück, wie ich es erwarten würde, und nachdem meine Methode beendet wurde, verwandelt sich der Server irgendwie in 500. Ich bin nicht in der Lage, in den Rest der Pipeline zu treten. Trace gibt mir folgende Fehlermeldung:
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 The operation completed successfully. (0x0)
ConfigExceptionInfo
Alles (Program.cs, Startup.cs) eingerichtet sind, genau wie in [1]. Verhält sich genauso in IISExpress (VS2015 Update 3) und IIS7.5 (Windows 7). Andere Rückgabetypen, 200 (mit new ObjectResult(item)
für GET, 404 für NotFound()
oder 204 NoContentResult()
für PUT Arbeit ok. So scheint es, als wäre es ein Problem mit 201 irgendwie ist. Irgendwelche Ideen?
[1] https://docs.asp.net/en/latest/tutorials/first-web-api.html
Update Posting weitere Details per Anfrage:
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; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddLogging();
services.AddSingleton<ITodoRepository, TodoRepository>();
}
// This method gets called by the runtime. Use this method to configure the 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();
}
}
}
TodoControll er.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
stellt sich heraus, CreateAtAction
mit 201 versucht, nicht behandelte Route zu umleiten:
System.InvalidOperationException: No route matches the supplied values.
at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting(ActionContext context)
Immer noch nicht sicher, warum tho, wie die Methode GetById
sollte zu GetTodo
pro Controller-Einstellungen zugeordnet werden.
Vielleicht posten Sie Ihre 'Startup.cs' so können wir sehen, wenn Sie einige ungerade Middleware oder so verwenden? Auch Ihre GetTodo Methode wäre nützlich – Tseng
@Tseng Danke. Ich habe es nicht in den ursprünglichen Beitrag aufgenommen, weil alles, was ich in 'Startup.cs' hatte, ein Gerüst aus' Neu> Projekt> ASP.NET-Kernwebanwendung (.NET Core)> Web API + 'UseDeveloperExceptionPages' war. Das einzige, was ich anders als das, was Sie Schritt für Schritt nach Tutorial haben würde, ist, dass 'UseDeveloperExceptionPages' Ich fügte hinzu, nachdem ich das Problem in der Hoffnung, ich werde mehr Informationen bekommen. Ich tat es nicht. Die Create-Methode wird korrekt mit einem Objekt beendet, das ein neues Element enthält, und 201 wurde von CreateAtAction übergeben. Es wirft nichts. Der Artikel wird wie erwartet zum Repository hinzugefügt. –
BTW.Ich bin nicht sicher, ob das etwas ändert, aber ich benutze auch Fiddler4, um die POST-Anfrage mit korrekten Headern zu erstellen - was wiederum nicht wichtig ist, da der Controller ordnungsgemäß beendet wird und tut, was er sollte, d. Es fügt dem Repository ein Element hinzu. –