当查询字符串参数不正确时,如何在ASP .NET MVC中返回404页面

时间:2013-08-17 07:30:26

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4

让我们假设我有以下行动

public ViewResult Products(string color)
{...}

和将网址“产品”映射到此操作的路线。

根据SEO提示链接/products?color=red应该返回

  

200 OK

但链接/products?someOtherParametr=someValue

  

404未找到

所以问题是 - 如何处理未来的查询参数并在这种情况下返回404

3 个答案:

答案 0 :(得分:6)

考虑到What is the proper way to send an HTTP 404 response from an ASP.NET MVC action?上接受的答案,有一个特殊的ActionResult可以满足您的期望。

public class HomeController : Controller
{
    public ViewResult Products(string color)
    {
        if (color != "something") // it can be replaced with any guarded clause(s)
            return new HttpNotFoundResult("The color does not exist.");
        ...
    }
}

更新:

public class HomeController : Controller
{
    public ViewResult Products(string color)
    {
        if (Request.QueryString.Count != 1 || 
            Request.QueryString.GetKey(0) != "color")
            return new HttpNotFoundResult("the error message");
        ...
    }
}

答案 1 :(得分:5)

在执行操作方法之前验证这一点。此方法适用于您项目的所有控制器或特定的Action方法。

控制器操作方法

[attr]  // Before executing any Action Method, Action Filter will execute to 
        //check for Valid Query Strings.
public class ActionResultTypesController : Controller
{
    [HttpGet]
    public ActionResult Index(int Param = 0)
    {
        return View();
    }

    [HttpPost]
    public ActionResult Index(MyViewModel obj)
    {
        return View(obj);
    }

}

操作过滤器

public class attr : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.ActionParameters.Count == 0 &&
                  System.Web.HttpContext.Current.Request.QueryString.Count > 0)
        {
              //When no Action Parameter exists and Query String exists. 
        }
        else
        {
            // Check the Query String Key name and compare it with the Action 
            // Parameter name
            foreach (var item in System.Web.HttpContext
                                       .Current
                                       .Request.QueryString.Keys)
            {
                if (!filterContext.ActionParameters.Keys.Contains(item))
                {
                    // When the Query String is not matching with the Action 
                    // Parameter
                }
            }
        }
        base.OnActionExecuting(filterContext);
    }
}

如果你注意上面的代码,我们正在检查Action参数,如下面的屏幕所示。

enter image description here

What can we do in case the QueryString passed does not exists in the Action Method Parameter? We can redirect the user to another page as shown in this link.

filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
                        {
                            {"action", "ActionName"},
                            {"controller", "ControllerName"},
                            {"area", "Area Name"},
                            {"Parameter Name","Parameter Value"}
                        });

或者

我们可以这样做。下面提到的代码将写在OnActionExecuting方法覆盖

filterContext.Result = new HttpStatusCodeResult(404);

答案 2 :(得分:1)

protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var actionParameters = filterContext.ActionParameters.Keys;
    var queryParameters = filterContext
                                  .RequestContext
                                  .HttpContext
                                  .Request
                                  .QueryString
                                  .Keys;

    // if we pass to action any query string parameter which doesn't 
    // exists in action we should return 404 status code

    if(queryParameters.Cast<object>().Any(queryParameter 
                                 => !actionParameters.Contains(queryParameter)))
        filterContext.Result = new HttpStatusCodeResult(404);
}

实际上,如果你不想在每个控制器中写这个,你应该覆盖DefaultControllerFactory