gpt4 book ai didi

c# - 捕获 HttpRequestValidationException 并将其添加到 ModelState 的最佳方法是什么?

转载 作者:行者123 更新时间:2023-11-30 17:11:44 25 4
gpt4 key购买 nike

关于属性上的装饰器 [AllowHtml] 甚至是方法上的 [ValidateInput(false)],捕获 的最佳方法是什么HttpRequestValidationException 并将其附加到 ModelState 以在用户端显示为友好错误而不显示错误页面(在 Application_Error 下抛出新页面或使用自定义错误页面.

global.asax 中我有一个陷阱:

protected void Application_Error()
{
// http://romsteady.blogspot.dk/2007/06/how-to-catch-httprequestvalidationexcep.html
// Code that runs when an unhandled error occurs

System.Exception ex = Server.GetLastError();

if (ex is System.Web.HttpRequestValidationException)
{
// I got the exception here, I can do plenty now!

Server.ClearError(); // no need to continue, I know the error
}
}

如何在不使用任何 session /应用程序变量的情况下从此处进入模型状态(考虑此处的云以及所有托管用户请求的不同服务器)?

我在考虑添加到路线或 TempData 但这里不可用...也许是 Cookie 但接缝很黑...

Any ideas?

最佳答案

我曾经通过自定义 ModelBinder 并围绕 base.BindModel 调用抛出 try/catch 来处理这种情况。它很丑陋,但可以完成工作。

我再说一遍,它很丑。

这是一个例子:

public class FooModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
Foo model;
try
{
model = (Foo)base.BindModel(controllerContext, bindingContext);
}
catch (HttpRequestValidationException)
{
// handle here
}
}
}

现在,在用错误填充 ModelState 的勇敢努力中,我有一个助手类,它会尽力维护状态。它的使用(和实现)还有很多不足之处(大量管道、魔术字符串的使用、类型特定、异常消息文本的正则表达式等),因此欢迎提出任何建议。这是最丑陋的部分,imo。

用法:

// from above code snippet
catch (HttpRequestValidationException)
{
// handle any potentially dangerous form values here. Don't want an exception bubbling up to the user
// so handle the HttpRequestValidationException by hand here
// manually populate the model here so that the original values are presented back to the user
model = new Foo()
{
Bar = HandleHttpRequestValidationExceptionHelper.TryAssignment(bindingContext.ModelState, () => bindingContext.ValueProvider.GetValue("Bar").AttemptedValue),
Baz = HandleHttpRequestValidationExceptionHelper.TryAssignment(bindingContext.ModelState, () => bindingContext.ValueProvider.GetValue("Baz").AttemptedValue)
};
}

return model;

助手尽最大努力为用户挖掘出相关的错误信息,但它确实很糟糕。 (注意到主题了吗?)

实现:

public static class HandleHttpRequestValidationExceptionHelper
{
/// <summary>
/// Use TryAssignment in anticipation of a HttpRequestValidationException; it's used to help return error information to the user
/// </summary>
/// <param name="modelStateDictionary">The ModelStateDictionary to add the errors to</param>
/// <param name="action">The attempted value to assign</param>
/// <returns>Either the proper value or the errored value read from the HttpRequestValidationException Message property</returns>
public static string TryAssignment(ModelStateDictionary modelStateDictionary, Func<string> action)
{
try
{
return action();
}
catch (HttpRequestValidationException ex)
{
// in effort to better inform the user, try to fish out the offending form field
var parenthesesMatch = Regex.Match(ex.Message, @"\(([^)]*)\)");
if (parenthesesMatch.Success)
{
var badFormInput = parenthesesMatch.Groups[1].Value.Split('=');
modelStateDictionary.AddModelError(badFormInput[0], badFormInput[1] + " is not valid.");
return badFormInput[1].TrimStart('"').TrimEnd('"');
}
else
{
// if attempt to find the offending field fails, just give a general error
modelStateDictionary.AddModelError("", "Please enter valid information.");
return string.Empty;
}
}
}

/// <summary>
/// Use TryAssignment in anticipation of a HttpRequestValidationException; it's used to help return error information to the user
/// </summary>
/// <typeparam name="T">Type of the value</typeparam>
/// <param name="modelStateDictionary">The ModelStateDictionary to add the errors to</param>
/// <param name="action">The attempted value to assign</param>
/// <returns>Either the proper value or default(T)</returns>
public static T TryAssignment<T>(ModelStateDictionary modelState, Func<T> action)
{
try
{
return action();
}
catch (HttpRequestValidationException ex)
{
// in effort to better inform the user, try to fish out the offending form field
var parenthesesMatch = Regex.Match(ex.Message, @"\(([^)]*)\)");
if (parenthesesMatch.Success)
{
var badFormInput = parenthesesMatch.Groups[1].Value.Split('=');
modelState.AddModelError(badFormInput[0], badFormInput[1] + " is not valid.");
// can't really cast a string to an unknown type T. safer to just return default(T)
}
else
{
// if attempt to find the offending field fails, just give a general error
modelState.AddModelError("", "Please enter valid information.");
}
return default(T);
}
}
}

基本上,在捕获异常时,尝试手动重新绑定(bind)模型,准备捕获每个属性的潜在 HttpRequestValidationException 错误。如果有人被捕获,请使用尽可能具体的消息相应地填充 ModelStateDictionary。

我真的希望该框架能够更轻松地 1) 捕获此异常和 2) 优雅地处理它,而不是把整个床都弄脏。

关于c# - 捕获 HttpRequestValidationException 并将其添加到 ModelState 的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11224901/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com