asp.netdotvvm

DotVVM implementing Toastr.js


I want to implement toastr.js in dotvvm. I created an exception filter which catch all the exception errors on the viewmodel:

public class ErrorLoggingActionFilter : ExceptionFilterAttribute
    {

        protected override async Task OnPageExceptionAsync(IDotvvmRequestContext context, Exception exception)
        {

            //context.CustomResponseProperties.Add("Error", exception.Message);

            // Inject JavaScript code to display toastr notification
            // Get the exception message
            string errorMessage = exception.Message;
            // Inject JavaScript code to display toastr notification
            string toastrScript = $"<script>toastr.error('{errorMessage}');</script>";
            context.ResourceManager.AddInlineScript(toastrScript);

            // Mark the exception as handled
            context.IsPageExceptionHandled = true;

            await base.OnPageExceptionAsync(context, exception);
        }


    }

but i'm having hard time adding the toastr.js and implementing it.


Solution

  • You should use OnCommandExceptionAsync instead of OnPageExceptionAsync.

    Additionally, the AddInlineScript requires just the JS code without the <script></script> tags:

    public class ErrorLoggingActionFilter : ExceptionFilterAttribute
    {
        protected override Task OnCommandExceptionAsync(IDotvvmRequestContext context, ActionInfo actionInfo, Exception ex)
        {
            string errorMessage = KnockoutHelper.MakeStringLiteral(ex.Message);
            string toastrScript = $"toastr.error('{errorMessage}');";
            context.ResourceManager.AddInlineScript(toastrScript);
    
            context.IsCommandExceptionHandled = true;
    
            return base.OnCommandExceptionAsync(context, actionInfo, ex);
        }   
    }
    

    Also, be careful when building scripts using the string concatenation. If the error message contains apostrophe, it would end the string literal and interpret the rest as a script code. If an attacker finds a way how to inject their input into the error message, you would make a script injection vulnerability in your app.

    I've added KnockoutHelper.MakeStringLiteral to escape characters in the error message.

    Finally, don't forget to register all script and style dependencies in DotvvmStartup:

    config.Resources.RegisterScriptFile("jquery", "wwwroot/jquery/jquery.min.js");
    config.Resources.RegisterScriptFile("toastr", "wwwroot/toastr.js/toastr.min.js", dependencies: new [] { "jquery", "toastr-css" });
    config.Resources.RegisterStylesheetFile("toastr-css", "wwwroot/toastr.js/toastr.min.css");