Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >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

复制
相关文章
ASP.NET MVC的Action Filter
一年前写了一篇短文ASP.NET MVC Action Filters,整理了Action Filter方面的资源,本篇文章详细的描述Action Filter。Action Filter作为一个可以应用到Controller Action(或者是整个controller)上的属性(Attribute),改变Action执行的行为,当应用于整个Controller上时,Controller上的所有Action都应用了同样设置的Action。 使用Action Filter 可以处理缓存、 验证和错误处理您的
张善友
2018/01/22
1.9K0
ASP.NET MVC的Action Filter
ASP.NET MVC编程——控制器
每一个请求都会经过控制器处理,控制器中的每个方法被称为控制器操作,它处理具体的请求。 1操作输入参数 控制器的操作的输入参数可以是内置类型也可以是自定义类型。 2操作返回结果 结果类型 调用方法 备注 ContentResult Content 文本类型 FileContentResult/FileStreamResult/FilePathResult File 文件类型 HttpStatusCodeResult(HttpNotFou
甜橙很酸
2018/03/30
2.3K0
ASP.NET MVC 过滤器
注意:如果继承自接口,则需要让类实现FilterAttribute,才能作为特性使用。参数类均继承自ControllerContext,主要包含属性请求上下文,路由数据,结果。
李郑
2019/12/11
2.1K0
ASP.NET MVC 过滤器
ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程
开篇:上一篇我们了解了在WebForm模式下一个Page页面的生命周期,它经历了初始化Init、加载Load以及呈现Render三个重要阶段,其中构造了页面控件树,并对页面控件树进行了大量的递归操作,最后将与模板结合生成的HTML返回给了浏览器。那么,在ASP.NET MVC模式下,一个页面的生命周期又经历了哪些步凑呢?别急,本篇漫漫道来!
Edison Zhou
2018/08/20
1.2K0
ASP.Net请求处理机制初步探索之旅 - Part 5  ASP.Net MVC请求处理流程
ASP.NET MVC Preview生命周期分析
做ASP.NET WebForm开发都知道,ASP.NET有复杂的生命周期,学习ASP.NET MVC就要深入理解它的生命周期。今天从CodePlex上下载了ASP.NET Preview 2 的源代码,还有两个程序集Routing与Abstractions并未发布,不过这两个程序集的类并不多,可以用NET反编译工具 Reflector解开来看看,可惜这两个程序集用的是VS2008使用.net 3.5开发的,用了c# 3.0的很多特性,Reflector反编译不完全。 ASP.NET MVC通过HttpMo
张善友
2018/01/30
1.5K0
七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递
通过第一天的学习之后,我们相信您已经对MVC有一些基本了解。 本节所讲的内容是在上节的基础之上,因此需要确保您是否掌握了上一节的内容。本章的目标是在今天学习结束时利用最佳实践解决方案创建一个小型的MV
葡萄城控件
2018/01/10
2.4K0
七天学会ASP.NET MVC (二)——ASP.NET MVC 数据传递
ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门
本篇代码基于以下代码进行调整:https://github.com/ken-io/asp.net-core-tutorial/tree/master/chapter-02
KenTalk
2018/11/09
2.4K0
ASP.NET Core 入门教程 5、ASP.NET Core MVC 视图传值入门
Asp.net mvc 知多少(五)
本系列主要翻译自《ASP.NET MVC Interview Questions and Answers 》- By Shailendra Chauhan,想看英文原版的可访问http://www.dotnettricks.com/free-ebooks自行下载。该书主要分为两部分,ASP.NET MVC 5、ASP.NET WEB API2。本书最大的特点是以面试问答的形式进行展开。通读此书,会帮助你对ASP.NET MVC有更深层次的理解。 由于个人技术水平和英文水平也是有限的,因此错误在所难免,希
圣杰
2018/01/11
3.1K0
Asp.net mvc 知多少(五)
ASP.NET MVC项目的创建
 1、打开【vs】开发工具 选择【ASP.NET Web应用程序(.NET Framework)】 输入名称名称,点击创建、 选择【MVC】项目,取消HTTPS配置,点击创建即可 引入EF 创建三层: 剩下的就是代码编写了。
红目香薰
2022/11/29
8910
ASP.NET MVC项目的创建
MVC 3.0 的新特性 摘要
MVC经过其1.0和2.0版本的发展,现在已经到了3.0的领军时代,随着技术的不断改进,MVC也越来越成熟。使开发也变得简洁人性化艺术化。
Isaac Zhang
2019/09/10
2.8K0
MVC 3.0 的新特性

            摘要
ASP.Net MVC开发基础学习笔记:一、走向MVC模式
  在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/blog/index.aspx的URL,那么我们的WebForm程序会到网站根目录下去寻找blog目录下的index.aspx文件,然后由index.aspx页面的CodeBehind文件(.CS文件)进行逻辑处理,其中或许也包括到数据库去取出数据(其中的经过怎样的BLL到DAL这里就不谈了),然后再由index.aspx页面来呈现给用户。
Edison Zhou
2018/08/20
2.2K0
ASP.Net MVC开发基础学习笔记:一、走向MVC模式
ASP.NET MVC使用Bootstrap系列(5)——创建ASP.NET MVC Bootstrap Helpers
序言 ASP.NET MVC允许开发者创建自定义的HTML Helpers,不管是使用静态方法还是扩展方法。一个HTML Helper本质上其实是输出一段HTML字符串。 HTML Helpers能让我们在多个页面上公用同一段HTML标记,这样不仅提高了稳定性也便于开发者去维护。当然对于这些可重用的代码,开发者也方便对他们进行单元测试。所以,创建ASP.NET MVC Bootstrap Helpers是及其有必要的。 内置的HTML Helpers ASP.NET MVC内置了若干标准HTML Hel
用户1161731
2018/01/11
1.5K0
ASP.NET MVC使用Bootstrap系列(5)——创建ASP.NET MVC Bootstrap Helpers
.NET MVC第三章、三种传值方式
ASP.NET MVC 5源代码中ControllerBase类中ViewData属性的定义:
红目香薰
2022/11/30
5730
.NET MVC第三章、三种传值方式
ASP.Net MVC开发基础学习笔记:一、走向MVC模式
  在传统的WebForm模式下,我们请求一个例如http://www.aspnetmvc.com/blog/index.aspx的URL,那么我们的WebForm程序会到网站根目录下去寻找blog目录下的index.aspx文件,然后由index.aspx页面的CodeBehind文件(.CS文件)进行逻辑处理,其中或许也包括到数据库去取出数据(其中的经过怎样的BLL到DAL这里就不谈了),然后再由index.aspx页面来呈现给用户。
全栈程序员站长
2022/09/06
1K0
ASP.Net MVC开发基础学习笔记:一、走向MVC模式
ASP.NET Core 错误处理(Handle Errors)
链接:cnblogs.com/xiaoxiaotank/p/15586706.html
郑子铭
2021/12/01
2.1K0
ASP.NET Core 错误处理(Handle Errors)
【asp.net core 系列】3 视图以及视图与控制器
在之前的几篇中,我们大概介绍了如何创建一个asp.net core mvc项目以及http请求如何被路由转交给对应的执行单元。这一篇我们将介绍一下控制器与视图直接的关系。
程序员小高
2020/06/03
2.7K0
ASP.NET MVC5高级编程 ——(6)过滤器
1、过滤器(Filters)就是向请求处理管道中注入额外的逻辑。提供了一个简单而优雅的方式来实现横切关注点。
浩Coding
2019/07/03
2.4K0
集成EntLib实现ASP.NET MVC的异常处理
本篇通过自定义ASP.NET MVC的异常筛选器实现了与EntLib的EHAB(Exception Handling Application Block)的集成,使我们可以通过配置的方式来定义异常处理策略,并最终通过错误页面显示被处理过的异常信息。[源代码从这里下载] 我们知道ASP.NET MVC具有一个类型为HandleErrorAttribute的异常筛选器可以起到错误页面的导向作用。在这里我直接让我们自定义的异常筛选器继承它,为此我们定义了如下一个名称为ExtendedHandleErrorAttr
蒋金楠
2018/01/15
7110
集成EntLib实现ASP.NET MVC的异常处理
asp.net mvc HandleErrorAttribute 异常错误处理 无效!
现象:filters.Add(new HandleErrorAttribute()); 使用了全局的异常处理过滤。
旺财的城堡
2018/11/20
1.3K0
ASP.NET MVC 重点教程一周年版 第九回 HtmlHelper
由前篇我们所讲的Helper演化,我们思考,对于这种代码我们是不是也可以用一个Helper来自动绑定数据呢
重典
2022/04/11
9070

相似问题

ASP.NET MVC: Controller ViewData & ViewPage ViewData

12

asp.net mvc ViewData

10

ASP.NET MVC +复杂ViewData

30

ASP.NET MVC ViewData错误

20

ASP.NET MVC ViewData Null

21
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

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

洞察 腾讯核心技术

剖析业界实践案例

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