首页 > 解决方案 > 为 IRealTimeNotifier 构建通知数据

问题描述

我正在使用 ASP.NET Boilerplate 并实现了 IRealTimeNotifier,以便在应用程序层中执行某些操作时向用户发送电子邮件。

根据下一页上的示例,我无法构建要传递给 IRealTimeNotifer 的通知数据:

https://aspnetboilerplate.com/Pages/Documents/Notification-System#multiple-notifiers

我的 EmailRealTimeNotifier 与您在页面上看到的完全一样:

public class EmailRealTimeNotifier : IRealTimeNotifier, ITransientDependency
{
    private readonly IEmailSender _emailSender;
    private readonly UserManager _userManager;

    public EmailRealTimeNotifier(
        IEmailSender emailSender,
        UserManager userManager)
    {
        _emailSender = emailSender;
        _userManager = userManager;
    }

    public async Task SendNotificationsAsync(UserNotification[] userNotifications)
    {
        foreach (var userNotification in userNotifications)
        {
            if (userNotification.Notification.Data is MessageNotificationData data)
            {
                var user = await _userManager.GetUserByIdAsync(userNotification.UserId);
                
                _emailSender.Send(
                    to: user.EmailAddress,
                    subject: "You have a new notification!",
                    body: data.Message,
                    isBodyHtml: true
                );
            }
        }
    }
}

然后我将它包含在我的模块 PreInitialize 中:

Configuration.Notifications.Notifiers.Add<EmailRealTimeNotifier>();

我从我的应用程序层调用以下内容:

await _emailNotifier.SendNotificationsAsync(userNotification.ToArray());

注入依赖后:

public class MyAppService : IMyAppService
{
    private readonly EmailRealTimeNotifier _emailNotifier;

    public MyAppService(EmailRealTimeNotifier emailNotifier)
    {
        _emailNotifier = emailNotifier;
    }
}

在将 UserNotification 对象传递给 IRealTimeNotifier 之前,我曾尝试构建它。但是,我在应用程序层的 try-catch 中收到空引用异常错误。

有人可以建议我如何构建此 UserNotification 或指出访问此功能的正确方法吗?


实际调用和堆栈跟踪:

try
{
    var userNotificationList = new List<UserNotification>();
    var userNotification = new UserNotification();
    var notificationData = new NotificationData();
    var messageNotificationData = new MessageNotificationData("Test");

    userNotification.UserId = (long)AbpSession.UserId;
    userNotification.Notification.Data = messageNotificationData;

    userNotificationList.Add(userNotification);

    await _emailNotifier.SendNotificationsAsync(userNotificationList.ToArray());
}
catch (Exception e)
{
    var test = e;
    throw;
}

堆栈跟踪是:

Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:信息:使用参数 (ESMPortal.Users.Dto.UserDto) 执行操作方法 ESMPortal.Users.UserAppService.Update (ESMPortal.Application) - 验证状态:抛出有效异常:'System.NullReferenceException ' 在 ESMPortal.Application.dll 'dotnet.exe' (CoreCLR: clrhost) 中:加载 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.4\System.Diagnostics.StackTrace.dll'。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。“dotnet.exe”(CoreCLR:clrhost):已加载“C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.4\System.Reflection.Metadata.dll”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。'dotnet.exe' (CoreCLR: clrhost):已加载“C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.4\System.IO.MemoryMappedFiles.dll”。跳过加载符号。模块已优化,调试器选项“仅我的代码”已启用。

它有一条消息:

Message = "对象引用未设置为对象的实例。"

我的 RealTimeNotifier 类顶部的断点永远不会被触发。

当我这样做时,上面会遇到异常userNotification.Notification.Data = messageNotificationData;

标签: c#asp.net-coreaspnetboilerplateabp

解决方案


IRealTimeNotifier当您调用时,应该由 ABP 调用_notificationPublisher.PublishAsync

这会在数据库的AbpNotifications表中创建一个通知。

var notificationName = "NotificationName";
var message = "Test";
var userIds = new [] { AbpSession.ToUserIdentifier() };

await _notificationPublisher.PublishAsync(
    notificationName,
    data: new MessageNotificationData(message),
    userIds: userIds
);

在你的情况下,你可以_emailSender直接打电话。

var user = await _userManager.GetUserByIdAsync(AbpSession.UserId.Value);
var message = "Test";

_emailSender.Send(
    to: user.EmailAddress,
    subject: "You have a new notification!",
    body: message,
    isBodyHtml: true
);

推荐阅读