简体   繁体   English

基本的.NET Core应用程序混合了多个请求

[英]Basic .NET Core app mixing multiple requests

I'm working with .NET 5/Core and created the most basic ASP.NET Core web application to understand .NET Core basics (my code below), but my private class field/property is behaving like a static field and preserving its value between HTTP requests. 我正在使用.NET 5 / Core,并创建了最基本的ASP.NET Core Web应用程序来了解.NET Core基础(下面的代码),但是我的私有类字段/属性的行为就像一个静态字段,并保留其值HTTP请求之间。 I would like to understand why, how to solve this in a simplest way, and if there are multiple solutions/approaches. 我想了解为什么,如何以最简单的方式解决此问题,以及是否有多种解决方案/方法。

I am declaring 'Output' string as private non-static field and I'm assuming it should be reset with each new HTTP request, but instead it behaves like a static field/property and each new page refresh results in a longer and longer output, preserving previous value and adding a new one. 我将'Output'字符串声明为私有非静态字段,并且我假设应该在每个新的HTTP请求中将其重置,但是它的行为类似于静态字段/属性,并且每个新页面刷新导致输出的时间越来越长,保留以前的值并添加新的值。 For example the web page first shows output / , but after refreshing the page couple more times I see the following 5 outputs merged 例如,网页首先显示输出/ ,但是刷新页面几次后,我看到合并了以下5个输出

/
/favicon.ico
/
/favicon.ico
/

favicon.ico is not a problem and I understand that my web browser is requesting it. favicon.ico 没问题 ,我知道我的网络浏览器正在请求它。 The output above shows after first 3 page refreshes, while each additional page refresh outputs two more of these lines since the web browser submits 2 HTTP requests. 上面的输出显示的是在刷新前3个页面之后,而每个其他页面刷新将输出另外两行,因为Web浏览器提交了2个HTTP请求。 I probably could come up with a solution using services.AddScoped or services.AddTransient , but not sure why services would be needed in this case since each HTTP request seems to be handled separately and should re-initialize my RequestHandler class. 我可能可以使用services.AddScopedservices.AddTransient提出一个解决方案,但是由于每个HTTP请求似乎是单独处理的,并且应该重新初始化我的RequestHandler类,因此不确定在这种情况下为什么需要服务。 Am I missing something simple and is there a way to handle this at the simplicity level of my sample code? 我是否缺少一些简单的东西,是否可以在示例代码的简单性级别上进行处理?

My whole app consists of the Startup.cs below: 我的整个应用程序由以下Startup.cs组成:

using System.Threading.Tasks;
using Microsoft.AspNet.Builder;
using Microsoft.AspNet.Http;

namespace BasicApp
{
    public class Startup
    {
        public static void Main()
        {
        }

        public void Configure(IApplicationBuilder app)
        {
            app.UseMiddleware<RequestHandler>();
        }
    }

    public class RequestHandler
    {
        RequestDelegate _next;
        private string Output = "";

        public RequestHandler(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            Output += context.Request.Path + "\n";
            await context.Response.WriteAsync(Output);
        }
    }
}

Middleware classes are only instantiated once through IApplicationBuilder.UseMiddleware{T} , and put into the request pipeline. 中间件类仅通过IApplicationBuilder.UseMiddleware{T}实例化一次,并放入请求管道中。 The ASP.NET documentation on this does a pretty good job of explaining the process. 关于此ASP.NET文档在解释该过程方面做得很好。

You could achieve a simple response through the IApplicationBuilder.Run method: 您可以通过IApplicationBuilder.Run方法获得简单的响应:

public void Configure(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync(context.Request.Path);
    });
}

Another way to think of it would be that a middleware class instantiates your RequestHandler with each request: 另一种考虑方式是中间件类用每个请求实例化您的RequestHandler

public class Startup
{
    public Startup(IHostingEnvironment env)
    {
    }

    public void Configure(IApplicationBuilder app)
    {
        app.UseMiddleware<RequestHandlerMiddleware>();
    }

    public static void Main(string[] args) => WebApplication.Run<Startup>(args);
}

public class RequestHandlerMiddleware
{
    RequestDelegate _next;

    public RequestHandlerMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task Invoke(HttpContext context)
    {
        var handler = new RequestHandler();
        await handler.HandleRequestAsync(context);
        await _next.Invoke(context); // invoke the next delegate in the pipeline
    }
}

public class RequestHandler
{
    private string Output = "";

    public async Task HandleRequestAsync(HttpContext context)
    {
        Output += context.Request.Path + "\n";
        await context.Response.WriteAsync(Output);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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