我使用的大多数路由都基于标准MVC3应用程序中定义的默认路由:
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
但是,如果我的路由是“/ Book / Update / 1”并且由于用户在没有1的情况下手动键入地址而保持“1”,则抛出空参数错误。显然我的路线需要这个1并且不是可选的,但我不会为我的每一个动作定义一个自定义路线。如果我打开自定义错误,我不确定这是什么类型的错误,重定向到正确的HTML错误页面。
问题: 我如何处理这个错误,就像404一样?我没有看到这种方法有任何问题,因为现实是在路线中留下一个Id号码与找不到的404号码相同。
或者我在设计路线时遗漏了什么?似乎很直接给我。
感谢。
更新 我很欣赏下面给出的答案。它们都是合理的方法。为了更清楚我的问题,让我详细说明一下。在我看来,“/ Book / Update / 1”的路线只有一个目的。更新书1.除此之外的任何其他偏差都应该失败并重定向到404.我不认为这与不存在的静态html页面有任何不同。我可能会争论一个不包含在.net中的功能,我只是觉得可能有更简单的方法。
UPDATE2: 应该挖得更深一些。有一个很好的例子here.我发现第二个答案最有帮助。
答案 0 :(得分:2)
public ActionResult Update(int? id)
{
if (!id.HasValue) return HttpNotFound();
//Debug.Assert(id.Value != null);
...
}
答案 1 :(得分:0)
我也有这个问题,我所做的是创建一个可重复使用的动作过滤器,我在其中指定所需的参数。
动作过滤器:
public class RequiredActionParameters : ActionFilterAttribute
{
private readonly IEnumerable<string> _parameters;
public RequiredActionParameters(params string[] parameters)
{
_parameters = parameters;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!filterContext.IsChildAction && !filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
{
foreach (var parameter in _parameters)
{
if (filterContext.ActionParameters[parameter] == null)
{
filterContext.Result = new RedirectResult("/Error/NotFound");
break;
}
}
}
}
}
关于控制器中的操作:
[RequiredActionParameters("restaurantId", "testId")]
public ActionResult Details(long restaurantId, long testId)
{
View();
}
我使用错误日志工具elmah对其进行了测试,并且没有报告任何错误。
答案 2 :(得分:0)
我认识的那个聚会晚了,但希望这可能对其他人有帮助。我在上面回答了杰米(Jamie)的问题,并对其进行了扩展,使其更易于使用,因此您无需单独列出所有参数,无需从不同操作中进行不同的重定向,并自动考虑可为空的类型参数。
public class RequiredActionParametersAttribute : ActionFilterAttribute
{
private readonly string _redirectUrlConfigKey;
public RequiredActionParametersAttribute(string redirectUrlConfigKey)
{
_redirectUrlConfigKey = redirectUrlConfigKey;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (string.IsNullOrWhiteSpace(_redirectUrlConfigKey))
return;
var redirectUrl = ConfigurationManager.AppSettings[_redirectUrlConfigKey];
if (string.IsNullOrWhiteSpace(redirectUrl))
return;
var actionDescriptor = filterContext.ActionDescriptor;
var parameterDescriptors = actionDescriptor.GetParameters();
foreach (var parameter in filterContext.ActionParameters)
{
if (parameter.Value == null)
{
var parameterDescriptor = parameterDescriptors.First(p => p.ParameterName == parameter.Key);
if (!IsNullableType(parameterDescriptor.ParameterType))
{
filterContext.Result = new RedirectResult(redirectUrl);
break;
}
}
}
}
private static bool IsNullableType(Type type)
{
return Nullable.GetUnderlyingType(type) != null;
}
}
然后采取行动
[RequiredActionParameters("DetailsPageExceptionRedirect")]
public ActionResult Details(int param1, int param2, bool param3, int? param4)
您可以将针对不同操作的不同重定向添加到配置文件,并将config键传递到操作过滤器。然后它将检查每个参数的存在,如果它为null,则检查它是否为可为null的类型,否则,将重定向到您指定的位置。