0

我正在使用 MVC 3 和 vs2010 和 VB.NET。我在我的控制器上使用了“HandleError”,它工作得很好而且很简单,它会自动检测未处理的异常并将用户重定向到我选择的错误页面。但是,有一个问题。

这是我正在使用的操作方法的示例:

    <HandleError>
    Public Function ReportAProblem(DespatchNoteNo As String, DespatchNoteItemId As Long) As ActionResult
        Dim uiview As New PickingReportAProblemVM(DespatchNoteNo, DespatchNoteItemId)

        ' Get the data for ReportAProblem
        GetDataForReportAProblem(uiview)

        Return View(uiview)
    End Function

当用户通过以下方式操作 URL 时,会自动抛出异常,并将用户重定向到我的错误页面:

  • .../?DespatchNoteNo=DN1234&DespatchNoteItemId=A(DespatchNoteItemId 的数据类型不正确)
  • .../?DespatchNoteNo=DN1234&DespatchNoteItem=1(DespatchNoteItemId 的参数名称不正确)

似乎自动抛出了一个异常(如果我错了,请纠正我),它被 HandleError 拾取并且用户被重定向到我的错误页面。

但是,如果用户键入以下内容:

  • .../?DespatchNote=DN1234&DespatchNoteItemId=1(DespatchNote 的参数名称不正确)

似乎没有抛出异常(如果我错了,请纠正我)并且用户没有被重定向到我的错误页面,而是代码继续。

据我所见,当我在调试时,当调用 action 方法时,在上述所有场景中,参数的值都设置为 Nothing。同样,不同之处似乎在于,对于除 String 类型之外的任何类型的参数,都会引发异常,而这似乎不是 String 类型的参数。

我显然稍后会在我的应用程序的服务层再次检查变量的内容,但在上述情况下(即用户一直在操作查询字符串并且应该将他/她的手指砍掉)我不想要代码完全进入服务层,而是将用户重定向到我的错误页面(就像非字符串数据类型发生的情况一样)。

如果用户操纵字符串类型查询字符串参数的名称,有谁知道引发异常的方法?还是我走错了路?

4

2 回答 2

0

这是我想出的解决方法。它并不完美,因为我仍然需要为每个要在操作方法中检查的 String 类型参数编写 1 行代码,但如果这是最接近完美的,我会接受它。

我创建了以下动作过滤器:

Public Class CheckStringParam
    Inherits ActionFilterAttribute

    Public Property Parameter As String
    Public Property InputValue As String

    Public Overloads Overrides Sub OnActionExecuting(filterContext As ActionExecutingContext)
        If Parameter <> String.Empty AndAlso filterContext.ActionParameters.ContainsKey(Parameter) Then
            If filterContext.ActionParameters.TryGetValue(Parameter, InputValue) Then
                If InputValue Is Nothing Then
                    Throw (New ArgumentException)
                End If
            End If
        End If

    End Sub

End Class

它基本上是用参数名称调用的。如果您提供了参数名称并且它存在于操作的上下文中,它将尝试获取其值。如果成功,它会检查它是否设置为Nothing。如果是这样,它会引发异常。然后这将被“HandleError”自动拾取,并且用户被重定向到用户屏幕。

动作方法现在看起来像这样:

<CheckStringParam(Parameter:="DespatchNoteNo")>
<HandleError>
Public Function ReportAProblem(DespatchNoteNo As String, DespatchNoteItemId As Long) As ActionResult
    Dim uiview As New PickingReportAProblemVM(DespatchNoteNo, DespatchNoteItemId)

    ' Get the data for ReportAProblem
    GetDataForReportAProblem(uiview)

    Return View(uiview)
End Function

不需要其他代码,如果他/她确实操纵了 URL 并输入了不正确的参数名称,它将导致用户被重定向。

我很想听听人们的想法。

于 2012-06-26T18:59:40.173 回答
0

这很可能是因为DispatchNoteNo变量是一个字符串。由于 URL 中未提供它,因此它现在是一个空字符串。这里不会抛出异常。所以你有几个选择。

  1. 在您的控制器中检查String.IsNullOrEmpty(DispatchNoteNo),如果为真则重定向。
  2. 使用路由对您有利 -> 使用这些值创建路由。如果缺少一个,则该路线将失败。最后是一个例子,因为我今天早上在语法标记上失败了......

在这里,如果其中一个或两个参数没有定义,或者如果有人删除了其中一个路由约束,则该路由将与请求不匹配。只要您没有将进一步匹配的路由,服务器将返回“没有路由与提供的等等等等匹配”(对不起,不记得确切的措辞)错误

routes.MapRoute("Dispatches",
                    "Controller/ReportAProblem/{DispatchNoteNo}/{DespatchNoteItemId}",
                    new { controller = "Controller", action = "ReportAProblem" }
                );
于 2012-06-26T14:35:13.310 回答