Building Notification Data for IRealTimeNotifier

旧时模样 提交于 2020-07-10 08:47:17

问题


I'm using ASP.NET Boilerplate and have implemented an IRealTimeNotifier in order to email users when certain actions are performed in the application layer.

I'm having trouble building the notification data to pass to the IRealTimeNotifer as per the example on the following page:

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

My EmailRealTimeNotifier is exactly as you see on the page:

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
                );
            }
        }
    }
}

I have then included this in my module PreInitialize:

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

I call the following from my application layer:

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

After injecting the dependency:

public class MyAppService : IMyAppService
{
    private readonly EmailRealTimeNotifier _emailNotifier;

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

I have tried to build the UserNotification object prior to passing it to the IRealTimeNotifier. However, I get a null reference exception error in the try-catch of my application layer.

Could someone please suggest how I could build this UserNotification or indicate the correct way of accessing this feature?


Actual call and stack trace:

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;
}

Stacktrace is:

Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executing action method ESMPortal.Users.UserAppService.Update (ESMPortal.Application) with arguments (ESMPortal.Users.Dto.UserDto) - Validation state: Valid Exception thrown: 'System.NullReferenceException' in ESMPortal.Application.dll 'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.4\System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.4\System.Reflection.Metadata.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'dotnet.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\2.2.4\System.IO.MemoryMappedFiles.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

It has a message of:

Message = "Object reference not set to an instance of an object."

The breakpoint at the top of my RealTimeNotifier class is never triggered.

The above hits the exception when I do userNotification.Notification.Data = messageNotificationData;.


回答1:


IRealTimeNotifier is meant to be called by ABP when you call _notificationPublisher.PublishAsync.

This creates a notification in AbpNotifications table in the database.

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

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

In your case, you can call _emailSender directly.

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
);


来源:https://stackoverflow.com/questions/56824021/building-notification-data-for-irealtimenotifier

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!