拦截和委托自定义对象/库的请求

时间:2017-02-06 07:23:05

标签: c# asp.net-core

以之前的question为基础,我在middleware Configure方法中拦截传入的请求。

public class Startup: IStartup
{
    public Startup(IHostingEnvironment environment)
    {
        // starting apparatus
    }

    public void Configure(IApplicationBuilder app)
    {
        var self = this;
        app.Run(async (context) =>
        {
             await self.Delegate.Service(context);
        });
    }

    public void output(HttpContext context string output) 
    {
          context.Response.WriteAsync(output);
    }

    // other methods

    public IRouter Delegate { get; set; }
}

处理程序

public class Handler: IRouter
{

    public void Service(HttpContext context)
    {
        // shuttles the context to the other parts of the system
        // for processing data
    }

    public void ServiceResult(HttpContext context, object result) 
    {
        // system calls this method, which is then passed back to Startup object.
        Startup.output(context, result);
    }
}
  1. 启动应将上下文移交给处理程序以处理请求。

  2. 然后,处理程序将调度到基于URI处理请求的系统的另一部分。处理完成后,其他部分将调用ServerResult。

  3. 基本上工作流是Startup委托设备和设备的上下文返回上下文以及输出结果。如果有断开连接,输出将在另一个函数/ closure / lambda中发生,但不会出现相同的中间件。

  4. 我被阻止在这个中间件上,它迫使我等待它并将其定义为异步,任何进一步的建议如何在asp.net核心世界中实现上述内容。

    P.S。请求拦截可以在任何地方发生,它在中间件中对我不起,就像在我的例子中一样。

    P.P.S 一个想法可能是Startup可以将lambda传递给设备,然后设备可以在请求完成处理后调用。

    我的尝试:

    启动

    public void Configure(IApplicationBuilder app)
    {
        var self = this;
        app.Run(async (context) =>
        {
            await self.Handler.Handle(new Request(context, new Task(() => { })));
        });
    }
    
    public void Result(Request request)
    {
        request.Context.Response.WriteAsync(request.Result); // write the result
        request.Task.Start(); // end waiting for the middleware async
    }
    

    处理程序

    public Task Handle(Request request)
    {
        // delegates to helper objects to process the request
        return request.Task;
    }
    
    public void Result(Request request)
    {
        // helper objects called this function after populating results
        startup.Result(request);
    }
    

1 个答案:

答案 0 :(得分:1)

我不是说这是最好的方式,但由于你缺乏经验并完成工作 - 你可以使用TaskCompletionSource

public class Handler {        
    private TaskCompletionSource<string> _tcs;
    public Task<string> Start(HttpContext context) {
        _tcs = new TaskCompletionSource<string>();
        // shuttles the context to the other parts of the system
        // for processing data
        return _tcs.Task;
    }

    private void Complete(string output) {
        if (_tcs == null)
            throw new Exception("Task has not been started yet");
        // system calls this method, which is then passed back to Startup object.
        _tcs.SetResult(output);
    }
}


public void Configure(IApplicationBuilder app) {
    app.Run(async (context) => {
        var output = await new Handler().Start(context);
        await context.Response.WriteAsync(output);
    });
}