Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 忽略因缺少控制器参数而导致的异常_C#_.net_Asp.net Mvc_Asp.net Mvc 4 - Fatal编程技术网

C# 忽略因缺少控制器参数而导致的异常

C# 忽略因缺少控制器参数而导致的异常,c#,.net,asp.net-mvc,asp.net-mvc-4,C#,.net,Asp.net Mvc,Asp.net Mvc 4,我有一个面向互联网的网站,它是使用MVC4构建的,我偶尔会收到来自机器人或好奇的用户的错误报告,这些用户发送不完整URL的请求 例如: public class ProductController : Controller { [HttpGet] public void View(int id) { // ... 对/product/view/1的GET请求有效 对/product/view的GET请求无效,因为未指定参数 此类无效请求会引发类似以下

我有一个面向互联网的网站,它是使用MVC4构建的,我偶尔会收到来自机器人或好奇的用户的错误报告,这些用户发送不完整URL的请求

例如:

public class ProductController : Controller
{
    [HttpGet]
    public void View(int id)
    {
        // ...
  • /product/view/1
    的GET请求有效
  • /product/view
    的GET请求无效,因为未指定参数
此类无效请求会引发类似以下情况的异常:

System.ArgumentException: The parameters dictionary contains a null entry
for parameter 'id' of non-nullable type 'System.Int32' for method
'System.Web.Mvc.ActionResult View(Int32)' in 'Foo.ProductController'. An
optional parameter must be a reference type, a nullable type, or be declared
as an optional parameter.

Parameter name: parameters
   at System.Web.Mvc.ActionDescriptor.ExtractParameterFromDictionary(ParameterInfo parameterInfo, IDictionary`2 parameters, MethodInfo methodInfo)
   at System.Web.Mvc.ReflectedActionDescriptor.<>c__DisplayClass1.<Execute>b__0(ParameterInfo parameterInfo)
   ...
System.ArgumentException:参数字典包含空条目
对于方法的“System.Int32”不可为空类型的参数“id”
“Foo.ProductController”中的“System.Web.Mvc.ActionResult视图(Int32)”。一
可选参数必须是引用类型、可为null的类型或已声明的类型
作为可选参数。
参数名称:参数
位于System.Web.Mvc.ActionDescriptor.ExtractParameterFromDictionary(ParameterInfo ParameterInfo,IDictionary`2参数,MethodInfo MethodInfo)
在System.Web.Mvc.ReflectedActionDescriptor.c\uuu DisplayClass1.b\uu0(ParameterInfo ParameterInfo)
...
正如异常消息所述,我可以使
id
参数为空,并在action方法中进行检查,但是我有许多控制器,它们具有许多操作

对于无法将参数绑定到操作参数的任何请求,我想返回一个
BadRequest
/
NotFound
响应,并在代码中的单个位置指定该响应,以应用于所有控制器


如何做到这一点?

您可以使用HandleError属性来处理应用程序中的错误。HandleError属性可以在控制器级别和方法级别指定。我以前用过类似的方法:

[HandleError(ExceptionType = typeof(ArgumentException), View = "MissingArgument")]
public ActionResult Test(int id)
{
    return View();
}
如果您不想在每个方法的基础上捕获异常,可以将该属性放在类级别:

[HandleError(ExceptionType = typeof(ArgumentException), View = "MissingArgument")]
public class HomeController : Controller
{
}
如果要在中心位置处理此问题,可以将其添加到App Start文件夹中的FilterConfig类:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    var error = new HandleErrorAttribute();
    error.ExceptionType = typeof (ArgumentException);
    error.View = "MissingArgument";
    filters.Add(error);
}
MissingArgument视图应位于共享视图文件夹中。 如果要将特定HTTP错误代码发送回客户端,可以将其放在视图中:

@{
    ViewBag.Title = "Error";
    Context.Response.StatusCode = (int) HttpStatusCode.BadRequest;
 }

<h2>Not found</h2>
@{
ViewBag.Title=“错误”;
Context.Response.StatusCode=(int)HttpStatusCode.BadRequest;
}
找不到

一种似乎有效的方法是覆盖控制器中执行的操作(我使用基本控制器,因此将其放在那里)


这样做感觉有点不舒服,因为它可能会在框架的未来版本中中断。但是,如果它确实中断,则站点将恢复为返回500而不是400。

在路由配置中,您可以在其中定义控制器、操作和参数定义,您可以将参数指定为可为null。@AnirudhAgarwal,在尝试将null转换为int@AnirudhAgarwal,唯一可行的方法是,如果我为
id
包含一个默认值,而我不想这样做。如果在操作中定义了
id
,但没有提供,则客户机出错,我想向他们发送404。此外,我有各种不同的控制器,每个控制器都需要在我的路由配置中输入。这里的要点是,我不想在我的操作和配置中进行自定义更改,以防某些用户/机器人发送无效的请求——它们应该集中处理,而不是引发异常,导致我收到错误电子邮件,而我只是删除了这些邮件。我认为问题来自于路由中有可选id和不匹配行动。有了一致的设计,你就不必做任何事情。有趣的可能重复,尽管这将处理所有
ArgumentException
s,而我只想要那些与无法绑定动作参数相关的。另外,我想把这个过滤器放在一个中心位置,而不是每个控制器上(我认为通过一些小的代码更改是可能的。)如果你想把它集中化,就把它放在FilterConfig中。我已经更新了我的答案来显示这一点。谢谢更新。最后,我在我的基本控制器中覆盖了
OnActionExecuted
,并瞄准了确切的错误,而不是所有
ArgumentException
实例。我担心的是,我会禁止在不同情况下引发的合法参数异常的错误日志记录/电子邮件发送。您也可以覆盖OneException方法以获得相同的效果。我不知道这是否重要,但我猜每个调用的操作方法都会调用OnActionExecuted,而OneException只在异常情况下调用。只是一个想法。
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    if (filterContext.Exception == null)
        return;

    // Avoid 'action parameter missing' exceptions by simply returning an error response
    if (filterContext.Exception.TargetSite.DeclaringType == typeof(ActionDescriptor) &&
        filterContext.Exception.TargetSite.Name == "ExtractParameterFromDictionary")
    {
        filterContext.ExceptionHandled = true;
        filterContext.Result = new HttpStatusCodeResult((int)HttpStatusCode.BadRequest);
    }
}