Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >ASP.NET MVC:如何为异常过滤器创建ViewData

ASP.NET MVC:如何为异常过滤器创建ViewData
EN

Stack Overflow用户
提问于 2009-08-20 11:50:28
回答 2查看 2.2K关注 0票数 1

我不确定您是否熟悉NerdDinner应用程序。它将一个方法GetRuleViolations()和一个属性IsValid添加到晚餐对象。当对象被保存时,它检查对象是否有效。如果不是,则抛出异常。在控制器中,异常被捕获,视图数据的ModelState中填充了违反规则的情况,视图被重新显示。Html.Validation辅助对象将高亮显示错误。

我想要做的是创建一个类似于HandleExceptionAttribute (它是MVC框架的一部分)的HandleRuleViolationExceptionAttribute。问题是这个属性必须重新填充视图的Modelstate。

视图可以具有其模型的任何对象类型。抛出RuleViolationException填充的代码将RuleViolationException.Object设置为视图的模型。

我在MVC源代码中查找了HandleExceptionAttribute的代码并对其进行了修改:

代码语言:javascript
运行
AI代码解释
复制
    <AttributeUsage(AttributeTargets.Class Or AttributeTargets.Method, _
    Inherited:=True, AllowMultiple:=False)> _
    Public Class HandleRuleViolationExceptionAttribute
        Inherits FilterAttribute
        Implements IExceptionFilter

        Private m_View As String
        Private m_MasterPage As String

        Public Property View() As String
            Get
                Return m_View
            End Get
            Set(ByVal value As String)
                m_View = value
            End Set
        End Property

        Public Property MasterPage() As String
            Get
                Return If(m_MasterPage, String.Empty)
            End Get
            Set(ByVal value As String)
                m_MasterPage = value
            End Set
        End Property

        Public Sub OnException(ByVal filterContext As System.Web.Mvc.ExceptionContext) _
                Implements System.Web.Mvc.IExceptionFilter.OnException
            If filterContext Is Nothing Then 
                Throw New ArgumentException("filterContext is null")
            End If

            'Ignore if the error is already handled.
            If filterContext.ExceptionHandled Then Return

            'Handle only ObjectIsInvalidExceptions.
            If Not TypeOf filterContext.Exception Is ObjectIsInvalidException Then
                Return
            End If

            Dim ex As ObjectIsInvalidException = DirectCast(filterContext.Exception, ObjectIsInvalidException)

            'If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
            'ignore it.
            If (New HttpException(Nothing, ex).GetHttpCode()) <> 500 Then Return

            Dim actionName As String = CStr(filterContext.RouteData.Values("action"))
            Dim viewName As String = If(String.IsNullOrEmpty(View), actionName, View)

            Dim viewData = filterContext.Controller.ViewData
            viewData.Model = ex.Object
            For Each item As String In filterContext.HttpContext.Request.Form.Keys
                viewData.Add(item, filterContext.HttpContext.Request.Form.Item(item))
            Next
            For Each ruleViolation In ex.Object.GetRuleViolations()
                viewData.ModelState.AddModelError(ruleViolation.PropertyName, ruleViolation.ErrorMessage)
            Next
            filterContext.Result = New ViewResult() With _
            { _
                    .ViewName = viewName, _
                    .MasterName = MasterPage, _
                    .ViewData = viewData, _
                    .TempData = filterContext.Controller.TempData _
            }
            filterContext.ExceptionHandled = True
            filterContext.HttpContext.Response.Clear()
            filterContext.HttpContext.Response.StatusCode = 500

            'Certain versions of IIS will sometimes use their own error page when
            'they detect a server error. Setting this property indicates that we
            'want it to try to render ASP.NET MVC's error page instead.
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = True
        End Sub
    End Class

为了填充视图的Model,我遍历请求的表单键,并将键及其值添加到ViewData实例中。它现在可以工作了,然而,我不相信这是做这件事的方式。

在控制器的Action方法中,我可以使用UpdateModel-method更新模型。这也会更新viewStates ModelState。我可以包含一个带有必须更新的属性名称的字符串数组,或者,当将模型作为Action参数时,我可以使用Bind-attribute来加入或排除一些属性(就像我在上面的create-action中所做的那样)。我的方法没有遵守这一点,可能会导致安全问题。

有没有更好的方法在OnException方法中构造ViewData对象,它的工作方式类似于控制器的UpdateModel-方法?有没有办法从ExceptionHandlerAttribute调用UpdateModel-method?

谢谢,纪梵希·哈尼克

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-08-23 03:26:50

明白了!

代码语言:javascript
运行
AI代码解释
复制
Dim methodInfo = GetType(Controller).GetMethod("View", _
        Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance, Nothing, _
        New Type() {GetType(Object)}, Nothing)
Dim controller = DirectCast(filterContext.Controller, Controller)
Dim viewResult As ViewResult = _
        CType(methodInfo.Invoke(controller, New Object() {ex.Object}), ViewResult)

Dim viewData = viewResult.ViewData
For Each ruleViolation In ex.Object.GetRuleViolations()
    viewData.ModelState.AddModelError( _
            ruleViolation.PropertyName, ruleViolation.ErrorMessage)
Next
filterContext.Result = viewResult

在我的例子中,我知道当使用这个HandleRuleViolationsAttribute时,filterContext.Controller总是派生自控制器。在控制器中,通过调用return View(theObject)来设置ModelState。但是视图方法是受保护的,所以在HandleRuleViolationsAttribute中我使用反射调用它,这给了我一个正确初始化了ModelState的ViewResult实例。然后,我可以使用AddModelError- RuleViolations将该方法添加到ModelState中。我将该viewResult赋值给filterContext.Result以显示它。

票数 0
EN

Stack Overflow用户

发布于 2009-08-20 19:12:15

几个快速要点:

  1. 您实际上想要更新控制器的ModelState (视图有权作为属性访问它) 2.您希望将结果设置为在其中传递模型对象的视图,即使它是无效的

从您的描述来看,您似乎应该调用控制器的UpdateModel方法。您可以通过执行以下操作从OnException方法执行此操作:

代码语言:javascript
运行
AI代码解释
复制
filterContext.Controller.UpdateModel(ex.Object)
...
For Each ruleViolation In ex.Object.GetRuleViolations()
            filterContext.Controller.ModelState.AddModelError(ruleViolation.PropertyName, ruleViolation.ErrorMessage)
Next
...
filterContext.Result = filterContext.Controller.View(ex.Object)

您可以考虑在属性上公开一个名为"ViewName“的属性,以便用户可以指定在发生异常时使用的备用视图:

代码语言:javascript
运行
AI代码解释
复制
<HandleRuleViolationException(ViewName:="SomeErrorViewForThisControllerOrAction")>

这是一个相当巧妙的想法。请回来更新帖子,标记答案,或对结果发表评论。我很好奇这是怎么回事!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1308433

复制
相关文章
html表单验证确认密码_简述html5的表单验证
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/17
3.6K0
html表单验证确认密码_简述html5的表单验证
AngularJS 的输入验证机制:内置验证器、自定义验证器和显示验证信息
AngularJS 是一款流行的前端JavaScript框架,提供了强大的表单处理功能。其中一个关键特性是输入验证,即对用户输入进行验证以确保数据的有效性和完整性。本文将详细介绍 AngularJS 的输入验证机制,包括内置验证器、自定义验证器和显示验证信息等内容。
网络技术联盟站
2023/07/05
3920
[译]HTML验证的价值探讨
[译]HTML验证的价值探讨 作者:Nicholas C. Zakas 原文:http://www.nczonline.net/blog/2010/08/17/the-value-of-html-validation/ 这篇文章我已经酝酿了很久,期间还拜读了 Chris Heilmann 关于 Remy Sharp’s site 的这篇大作。我和Chris曾就这个话题多次交换意见,最终我们彼此的观点都有所改变,接受了一些过去无法接受的意见。我曾经在公开的、私下的各种场合直言不讳地表示过,目前的HTML验证状
小李刀刀
2018/03/02
1K0
HTML5-输入验证
HTML5引入了对输入验证的支持。设计者可告知浏览器自己需要什么类型的数据,然后浏览器在提交表单之前会使用这些信息检查用户输入的数据是否有效。其好处是:用户可以立刻得到问题反馈。
奋飛
2021/08/30
1.6K0
HTML5-输入验证
HTML5-输入验证
HTML5引入了对输入验证的支持。设计者可告知浏览器自己需要什么类型的数据,然后浏览器在提交表单之前会使用这些信息检查用户输入的数据是否有效。其好处是:用户可以立刻得到问题反馈。
奋飛
2019/08/15
2.1K0
动手实现一个JSON验证器(上)
分析 既然要验证JSON的有效性,那么必然需要清楚的知道JSON格式,这个在JSON官网已经给我们画出来了: 从官方的图上面可以看出,JSON的组成一共有五部分: object: 以左大括号({)开头
李海彬
2018/03/26
1.5K0
动手实现一个JSON验证器(上)
HTML5表单及其验证
将原本type为text的input控件声明为以上特殊类型,是为了给用户呈现不同的输入界面(移动平台上支持这些不同的输入界面,这里就不细说),而且表单提交时会对其值做进一步的验证。下面展示这些新表单元素,请用支持这些表单元素的浏览器查看,IE对其支持最差。
HUC思梦
2020/09/03
1.8K0
Spring MVC-07循序渐进之验证器 上 (Spring自带的验证框架)
Converter和Formatter作用域Field级。 在MVC应用程序中,它们将String转换或者格式化成另外一种Java类型,比如java.util.Date.
小小工匠
2021/08/17
6720
HTML 交互式表单验证
在 HTML 中创建表单总是有点复杂。你首先得将 HTML 标记编写正确,然后需要确保每一个表单项在提交之前都有一个可用的值,最后还需要在有问题时用提醒来告知用户。   还好 HTML5 引入了一些新
用户1667431
2018/04/18
2.2K0
HTML 交互式表单验证
Alamofire验证器Validation
Alamofire融合Swift本身的特点,使用起来更加简单方便。下面引用官方Demo,发起一个请求并json解析处理。
Light413
2020/04/08
1.6K0
Alamofire验证器Validation
eBPF验证器原理
之前对eBPF验证器的了解仅停留在概念层面,那么验证器究竟是如何保证eBPF程序的安全呢,本文揭开eBPF验证器的检查细节。
Jinrong
2022/07/21
2K0
eBPF验证器原理
Spring Security实战-认证核心验证器验证逻辑AuthenticationProviderManagerAuthenticationProvider
提供了基本的认证逻辑和方法 它包含了一个List<AuthenticationProvider>对象
JavaEdge
2018/12/14
3.5K0
身份验证器是如何验证我们的身份?
​ 我以为我最初遇见他是在宝塔面板上,因为他可以方便的帮助我们进行身份验证。其实我们早就相遇在QQ安全中心手机版的口令里面(此处不确定是否是使用同一种算法,不过原理类似)。当初遇见他,我并不知道他是离线的。我以为谷歌身份验证器肯定是绑定谷歌账号的。后来找了半天,原来他只是个离线的软件。相信有很多同学和我一样的想法:离线身份验证器如何能使我们登录在线的场景?
yumusb
2020/08/28
4.3K0
HTML简单注册界面——含表单验证
最近学习HTML表单,感慨万千。虽然看起来好像不难学,但要是真自己实践起来问题却多多。这里是我写的一个简单的注册页面,只有“注册账号、密码、重输密码”三个文本框,还包含了原生JavaScript验证。(记一下,也希望能给有需要的人一点帮助。)
全栈程序员站长
2022/11/17
5.4K0
HTML简单注册界面——含表单验证
通过RestTemplate设置header&body,绕过证书验证,并获取返回的header&body
但是报缺少安全证书:unable to find valid certification path to requested target
chenchenchen
2021/09/06
1.5K0
Hyperf 初体验-验证器
Hyperf 1.1.0 更新内容比较多,但总的来说框架越来越完善。这次更新新增了 Validation 验证器 基于 Laravel,同时增加了大量的单侧。
hedeqiang
2019/12/18
1.9K0
Django-DRF | 验证器
Django REST框架构建Web API。Django网络应用开发的5项基础核心技术包括模型(Model)的设计,URL 的设计与配置,View(视图)的编写,Template(模板)的设计和Form(表单)的使用。
小团子
2020/02/20
1.7K0
Oauth2.0验证器
周末写的的小网站,功能是验证Oauth2.0授权服务器的可用性,帮助开发者调试Oauth2.0授权服务器,以便把服务器快速搭建出来。
巴法
2019/09/29
9210
Oauth2.0验证器
HTML5新增的表单验证功能
一、HTML5表单的特点: HTML5 表单增加了许多内置的控件和控件属性 XHTML 中需要放在 form 之中的诸如 input/button/select/textarea 等标签元素,在 HTML 5 中完全可以放在页面任何位置,并通过新增的 form 属性指向元素所属表单的 ID 值,即可关联起来。 二、HTML5新增的控件类型: email输入类型:<input type="email" name="email" /> 要求输入格式正确的 email 地址,否则浏览器不允许提交,同时会提示错
Leophen
2019/08/23
2.6K0
点击加载更多

相似问题

W3验证Html错误

14

HTML表单的W3验证

24

用于HTML5的W3验证器

20

Joomla w3验证器

11

w3验证器的HTML开始编码问题

216
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档