是否可以从控制器调用的一个或多个 ASP.NET 控制器类中触发事件?

Can Events Be Triggered from Within an ASP.NET Controller Class or Classes Called by the Controller?

提问人:mr_ed87 提问时间:6/14/2023 更新时间:6/14/2023 访问量:128

问:

我正在使用一个 ASP.NET 核心 Web API 项目。该项目已经布置好了它的 API 结构,目前不能轻易更改。但是,我收到了一位客户的异常请求,该客户询问我是否可以在客户端调用特定 API 端点时触发自定义脚本或电子邮件。我立即想到了使用事件,因为我知道您可以使用它们从一个对象(类)生成由其他对象处理的警报。我首先向控制器调用的帮助程序类添加一个事件。只有控制器中的特定操作方法才会调用此帮助程序类来执行诸如将记录保存到数据库或向其他资源发出 HTTP 请求等操作。我添加的事件使用 EventHandler 委托类型。我按照 Microsoft 的建议创建了一个继承自 EventArgs 的自定义类。我遇到的问题是,控制器调用的帮助程序类中的大多数方法都是异步的。因此,我的问题是,ASP.NET 核心 Web API 项目是否支持触发和处理事件?如果是这样,正确的方法是什么。这是我的控制器代码:

[ApiController]
[Route("[controller]")
public class MyController : ControllerBase{
    //properties go here
    
    [HttpGet("/Records/{id}")]
    public async Task<IActionResult> Get(int id){
        //Set variables and do other stuff here
        //Do something else here
        HelperClass serveRequest = new HelperClass();
        serveRequest.DoSomethingMethod(param1, param2, param3);
    }
}

如上所示,Get 操作方法从我的帮助程序类调用一个方法 (DoSomethingMethod)。我的帮助程序类的代码如下:

public class HelperClass{
    //class properties here
    
    public event EventHandler<CustomEventArgs> SomethingHappenedEvent;
    
    public HelperClass(){
        //instance initialization code
    }
    
    public async Task<someType> DoSomethingMethod(string param1, string param2, int param3){
        try{
            //Run business logic here
            CustomEventArgs args = new CustomEventArgs(param1, ...);
            SomethingHappenedEvent?.Invoke(this, args);
        } catch (Exception ex){
            throw
        }
    }
}

DoSomethingMethod 创建 CustomEventArgs 类的实例,然后尝试在下一行中调用(触发)该事件,并向其传递对象引用 (this) 和 CustomEventArgs 对象。最后,以下代码显示了应该处理该事件的类。

public class EventMonitorClass{
    private HelperClass _helperClass;
    
    public EventMonitorClass(HelperClass helperClass){
        _helperClass = helperClass;
        _helperClass.SomethingHappenedEvent += _helperClass_SomethingHappenedEvent;
        //Other initialization code here
    }
    
    private void _helperClass_SomethingHappenedEvent(object sender, CustomEventArgs e){
        //Event handling code here
    }
}

我在此类的构造函数中注册了该事件,并定义了事件处理程序方法,该方法与与事件关联的委托类型具有相同的签名。我遵循了向应用程序添加事件的标准过程,但每次在 Visual Studio 中运行代码时,我都看不到事件触发或事件处理程序被调用。我在这里缺少什么吗?任何为我指明正确方向的线索将不胜感激。

我尝试创建自定义委托类型以及使用 EventHandler 委托类型。我尝试使用 Task.Wait() 和类似的结构将异步方法更改为同步运行。

C# asp.net 异步 事件 ASP.NET-WEB-API

评论

0赞 Jeremy Lakeman 6/14/2023
那么可能应该是一个单例服务,你把它注入到你的控制器中?但是,您可以只定义一个接口和一个默认实现。您的一个客户会覆盖该实施来执行他们的电子邮件或其他操作。但是,您想在发送电子邮件时阻止呼叫者请求吗?或者您是否应该将这些电子邮件排队,在这种情况下,您将如何记录/处理任何错误?....HelperClass
0赞 mr_ed87 6/15/2023
更准确地说,HelperClass 做了几件事。它有一个方法,用于从控制器收到的请求中反序列化 JSON 有效负载。它还具有使用 HttpClient 字段调用其他 Web API 的异步方法。我想知道是否可以将事件与异步代码一起使用的一个特殊原因是,HttpClient 客户端类与 System.Net.Http 命名空间中的许多其他类(即 HttpRequestMessage、HttpResponseMessage)一样,主要使用异步方法。
0赞 Jeremy Lakeman 6/15/2023
恕我直言,使用进程队列编写更安全,因此您可以在单个位置捕获和记录异常。但这取决于您希望如何处理失败的电子邮件。BackgroundService

答: 暂无答案