本文介绍了与创建两条路线的问题,这将不是在ASP.NET MVC产生404错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图建立我的路由教程项目。我的主要目标是建立两条路线,不会产生在任何情况下404错误。我的意思是,如果路径不对我想路由使用/首页/索引路径。我有两个以下途径 -

I'm trying to build my tutorial project with routing. My main objective is to build two routes which won't generate 404 error in any case. By this I mean that if the path is wrong I want routing to use /Home/Index path. I have two following routes -

    routes.MapRoute("Default", "{controller}/{action}", 
                        new {controller = "Home", action = "Index"}
                        );

    routes.MapRoute("Second", "{*catchall}",
                        new {controller = "Home", action = "Index", id = UrlParameter.Optional}
                        );

当我使用不匹配的第一个路由,这样不存在的路径,它工作正常 -

It works fine when I use nonexistent path which doesn't matches the first route, like this -

但是,如果确实如此,那么我有以下 -

But if it does, then I have the following -

我明白为什么它发生的原因。然而在present一刻,我只设法找到解决办法的某种。添加以下code到Web.config文件 -

I understand the reason why it happens. However at the present moment, I only managed to find 'some sort' of a solution. Adding the following code to web.config file -

<customErrors mode="On">
      <error statusCode="404" redirect="~/Home/Index"/>
</customErrors>

不过,我不认为它是解决这一问题的最好办法。因为,据我可以理解,它只是捕获所有的错误并重定向到正确的路径,实际上并没有使用路由。因此,我不认为我需要这个全球性的处理。

However, I don't think that it is the best way to solve this problem. Because, as far as I can understand, it simply catches all errors and redirects it to the correct path, without actually using routing. So I don't think I need this global handling.

所以可能有人请给我一个提示,或为我提供很好的解决了我的问题。谢谢你。

So could somebody please give me a hint or provide me with a good solution to my problem. Thank you.

推荐答案

好吧,你并没有真正定义什么错误的路由,所以这里是我的定义:

Well, you didn't really define what "wrong" routing is, so here is my definition:


  1. 控制器或动作没有在项目中存在。

  2. 如果一个id获得通过,必须存在于操作方法。

我以前的限制做到这一点。 AFAIK,这是不可能用一个约束上的可选参数。这意味着,为了使 ID 参数可选,你需要3条路线。

Routes

I used constraints to do this. AFAIK, it is not possible to use a constraint on an optional parameter. This means that in order to make the id parameter optional, you need 3 routes.

routes.MapRoute(
   name: "DefaultWithID",
   url: "{controller}/{action}/{id}",
   defaults: new { controller = "Home", action = "Index" },
   constraints: new { action = new ActionExistsConstraint(), id = new ParameterExistsConstraint() }
);

routes.MapRoute(
   name: "Default",
   url: "{controller}/{action}",
   defaults: new { controller = "Home", action = "Index" },
   constraints: new { action = new ActionExistsConstraint() }
);

routes.MapRoute(
    name: "Second",
    url: "{*catchall}",
    defaults: new { controller = "Home", action = "Index" }
);

ActionExistsConstraint

public class ActionExistsConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.IncomingRequest)
        {
            var action = values["action"] as string;
            var controller = values["controller"] as string;

            var thisAssembly = this.GetType().Assembly;

            Type[] types = thisAssembly.GetTypes();

            Type type = types.Where(t => t.Name == (controller + "Controller")).SingleOrDefault();

            // Ensure the action method exists
            return type != null && type.GetMethod(action) != null;
        }

        return true;
    }
}

ParameterExistsConstraint

public class ParameterExistsConstraint : IRouteConstraint
{
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.IncomingRequest)
        {
            var action = values["action"] as string;
            var controller = values["controller"] as string;

            var thisAssembly = this.GetType().Assembly;

            Type[] types = thisAssembly.GetTypes();

            Type type = types.Where(t => t.Name == (controller + "Controller")).SingleOrDefault();
            var method = type.GetMethod(action);

            if (type != null && method != null)
            {
                // Ensure the parameter exists on the action method
                var param = method.GetParameters().Where(p => p.Name == parameterName).FirstOrDefault();
                return param != null;
            }
            return false;
        }

        return true;
    }
}

这篇关于与创建两条路线的问题,这将不是在ASP.NET MVC产生404错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 23:30