英文:
DotVVM implementing Toastr.js
问题
我想在dotvvm中实现toastr.js。我创建了一个异常过滤器,用于捕获视图模型上的所有异常错误:
public class ErrorLoggingActionFilter : ExceptionFilterAttribute
{
protected override async Task OnPageExceptionAsync(IDotvvmRequestContext context, Exception exception)
{
//context.CustomResponseProperties.Add("Error", exception.Message);
// 注入JavaScript代码以显示toastr通知
// 获取异常消息
string errorMessage = exception.Message;
// 注入JavaScript代码以显示toastr通知
string toastrScript = $"<script>toastr.error('{errorMessage}');</script>";
context.ResourceManager.AddInlineScript(toastrScript);
// 将异常标记为已处理
context.IsPageExceptionHandled = true;
await base.OnPageExceptionAsync(context, exception);
}
}
但我在添加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.
答案1
得分: 1
你应该使用 OnCommandExceptionAsync
,而不是 OnPageExceptionAsync
。
- "命令异常" 是在命令或静态命令期间发生的异常 - 页面已经在浏览器中加载,用户已经执行了某些操作,导致出现了错误。在这种情况下,在用户当前看到的页面上显示 toastr 通知是有意义的。
- "页面异常" 意味着在加载或渲染页面时出现了问题。如果发生这种异常,toastr 不会对用户有所帮助,因为页面根本无法加载。
另外,AddInlineScript
方法只需要包含 JS 代码,不需要包含 <script></script>
标签:
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);
}
}
另外,在构建脚本时要小心使用字符串连接。如果错误消息包含撇号,它将终止字符串文字,并将其余部分解释为脚本代码。如果攻击者找到一种方法将其输入注入到错误消息中,你的应用程序将存在脚本注入漏洞。我已经添加了 KnockoutHelper.MakeStringLiteral
来转义错误消息中的字符。
最后,不要忘记在 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");
英文:
You should use OnCommandExceptionAsync
instead of OnPageExceptionAsync
.
- The "command exception" is an exception that occurs during a command or a static command - the page is already loaded in the browser, the user has done something, and it produced an error. In such situation, it makes sense to display a toastr notification on the page the user is currently seeing.
- The "page exception" means there was a problem loading or rendering the page. If such exception occurs, the toastr wouldn't help the user anyway because the page cannot be loaded at all.
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");
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论