无法设置StatusCode,因为响应已经开始

时间:2020-03-17 18:31:10

标签: c# .net rest docker asp.net-core-2.1

我遇到无法解决自己的错误。

我在ASP.NET Core 2.1中有一个Rest API,它使用EntityFrameworkCore与MySQL数据库进行通信。

当我使用IIS Express从VS2017运行我的API时,一切工作正常。但是当我用docker运行它时,它会返回 StatusCode cannot be set because the response has already started

以下是一些示例代码:

首先,这是一种通用方法,用于获取数据库中给定类的所有元素。

    /// <summary>
    /// Return all the elements of the table T
    /// </summary>
    /// <param name="navigationProperties"></param>
    /// <returns></returns>
    public static IList<T> GetAll(params Expression<Func<T, object>>[] navigationProperties)
    {
        List<T> list;
        using (var context = new SupGoDatabaseContext())
        {
            IQueryable<T> dbQuery = context.Set<T>();

            //Apply eager loading
            foreach (Expression<Func<T, object>> navigationProperty in navigationProperties)
                dbQuery = dbQuery.Include<T, object>(navigationProperty);

            list = dbQuery
                .AsNoTracking()
                .ToList<T>();
        }
        return list;
    }

第二,这是调用上述方法的控制器

    // GET api/category
    [Authorize(Policy = "Administrator")]
    [HttpGet]
    public List<Category> Get()
    {
        List<Category> categories = new List<Category>();
        categories = DatabaseService<Category>.GetAll().ToList();
        return categories;
    }

最后,这是Startup.cs类,它可能是最重要的。

public class Startup
{
    public IConfiguration Configuration { get; }
    public IHostingEnvironment Environment { get; }

    public Startup(IHostingEnvironment environment, IConfiguration configuration)
    {
        Configuration = configuration;
        Environment = environment;
    }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

        services.AddCors(options =>
        {
            options.AddPolicy("*",
            builder =>
            {
                builder.WithOrigins("*").AllowAnyHeader().AllowAnyMethod();
            });
        });

        services.AddAuthentication(options =>
        { 
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(o =>
        {
            o.RequireHttpsMetadata = false;
            o.Audience = "supgo-api";
            o.Authority = "http://keycloak:8080/auth/realms/SupGo";
            o.IncludeErrorDetails = true;
            o.TokenValidationParameters = new TokenValidationParameters()
            {
                ValidateAudience = false,
                ValidateIssuerSigningKey = true,
                ValidateIssuer = true,
                ValidIssuer = "http://keycloak:8080/auth/realms/SupGo",
                ValidateLifetime = true
            };

            o.Events = new JwtBearerEvents()
            {
                OnAuthenticationFailed = c =>
                {
                    c.NoResult();

                    c.Response.StatusCode = 401;
                    c.Response.ContentType = "text/plain";
                    if (Environment.IsDevelopment())
                    {
                        return c.Response.WriteAsync(c.Exception.ToString());
                    }
                    return c.Response.WriteAsync("An error occured processing your authentication.");
                }
            };
        });

        services.AddAuthorization(options =>
        {
            options.AddPolicy("Administrator", policy =>
            {
                policy.RequireClaim("user_roles", "supgo-api-admin");
                policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
                policy.RequireAuthenticatedUser();

            });

            options.AddPolicy("User", policy =>
            {
                policy.RequireClaim("user_roles", "supgo-api-user");
                policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
                policy.RequireAuthenticatedUser();

            });
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }


        app.UseAuthentication();
        //app.UseHttpsRedirection();
        app.UseMvc();
    }
}

感谢您的帮助,我们将考虑任何建议。 保罗。

0 个答案:

没有答案