假设我有以下动作
public ViewResult Products(string color)
{...}
并将 url “产品”映射到此操作的路由。
根据 SEO 提示链接/products?color=red
应该返回
200 好
但是链接/products?someOtherParametr=someValue
404 未找到
所以问题是 - 在这种情况下如何处理不存在的查询参数并返回 404
假设我有以下动作
public ViewResult Products(string color)
{...}
并将 url “产品”映射到此操作的路由。
根据 SEO 提示链接/products?color=red
应该返回
200 好
但是链接/products?someOtherParametr=someValue
404 未找到
所以问题是 - 在这种情况下如何处理不存在的查询参数并返回 404
考虑从 ASP.NET MVC 操作发送 HTTP 404 响应的正确方法是什么?,有一个特别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");
...
}
}
在执行操作方法之前验证这一点。此方法适用于您项目的所有 Controller 或特定的 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 参数,如下面的屏幕所示。
filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
{
{"action", "ActionName"},
{"controller", "ControllerName"},
{"area", "Area Name"},
{"Parameter Name","Parameter Value"}
});
或者
我们可以这样做。下面提到的代码将写在OnActionExecuting
方法覆盖中
filterContext.Result = new HttpStatusCodeResult(404);
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
这适用于 Asp.Net Core。在 Controller ActionMethods 中使用下面的一行代码:
return StatusCode(404, "Not a valid request.");
在 OnActionExecuting 方法中,将 StatusCode 设置为 context.Result,如下例所示:
public override void OnActionExecuting(ActionExecutingContext context)
{
string color = HttpContext.Request?.Query["color"].ToString();
if (string.IsNullOrWhiteSpace(color))
{
// invalid or no color param, return 404 status code
context.Result = StatusCode(200, "Not a valid request.");
}
else
{
// write logic for any common functionality
}
base.OnActionExecuting(context);
}