HttpPost操作中的ASP.Net Core CreatedAtAction返回201,但整个请求以500结尾 [英] ASP.Net Core CreatedAtAction in HttpPost action returns 201 but entire request ends with 500

查看:74
本文介绍了HttpPost操作中的ASP.Net Core CreatedAtAction返回201,但整个请求以500结尾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在关注[1],用于设置我的第一个.NET Core WebAPI(从旧的" WebAPI移出).当我执行HttpPost操作时,如教程中所示:

I'm following[1] for setting up my first .NET Core WebAPI (moving from "old" WebAPI). When I do HttpPost action, as 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);
}

退出控制器后,我收到HttpError 500.正如我所期望的那样,CreatedAtAction返回状态代码为201的正确对象,并且在我的方法退出服务器后,它以某种方式将其变为500.我似乎无法进入其余的管道.跟踪给我以下错误:

I get a HttpError 500 after exiting my Controller. CreatedAtAction returns proper object with Status Code 201 as I would expect, and after my method exits the Server somehow turns it into 500. I don't seem to be able to step into the rest of the 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           The operation completed successfully. (0x0) 
      ConfigExceptionInfo

所有内容(Program.cs,Startup.cs)的设置均与[1]中的设置完全相同.在IISExpress(VS2015 Update 3)和IIS7.5(Windows 7)中的行为完全相同.其他返回类型,200(对于GET,使用new ObjectResult(item),对于NotFound(),使用404,对于PUT,则使用204 NoContentResult(),可以正常工作.所以似乎以某种方式出现了201问题.有什么想法吗?

Everything (Program.cs, Startup.cs) are set up exactly as in[1]. Behaves exactly the same in IISExpress (VS2015 Update 3) and IIS7.5 (Windows 7). Other return types, 200 (with new ObjectResult(item) for GET, 404 for NotFound() or 204 NoContentResult() for PUT work ok. So it seems like it's a problem with 201 somehow. Any ideas?

[1] https://docs.asp.net /en/latest/tutorials/first-web-api.html

更新 根据请求发布其他详细信息:

update Posting additional details per request:

Startup.cs:

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

TodoController.cs:

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

更新2

结果是,带有201的CreateAtAction试图重定向到未处理的路由:

turns out, CreateAtAction with 201 tries to redirect to unhandled route:

System.InvalidOperationException: No route matches the supplied values.
   at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.OnFormatting(ActionContext context)

仍然不确定为什么,按照控制器设置将方法GetById映射到GetTodo.

Still not sure why tho, as the method GetById should be mapped to GetTodo per Controller settings.

推荐答案

因此,经过一些调试后,我找到了引起问题的原因.事实证明this.Url.Action("Get", "GetTodo", new { id=item.Key })将返回null,而500则来自IIS无法匹配附加到201的路由的事实.

So, after a bit of debugging I found what caused it. It turned out that this.Url.Action("Get", "GetTodo", new { id=item.Key }) would return null and the 500 came from the fact that IIS could not match route attached to 201.

事实证明,您要么需要设置:

As it turns out, You either need to setup:

app.UseMvc(routes =>
{
    routes.MapRoute(
        name: "default",
        template: "{controller}/{action}");
});

或使用CreateAtRoute.

这篇关于HttpPost操作中的ASP.Net Core CreatedAtAction返回201,但整个请求以500结尾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆