且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

别名化自定义ASP MVC路由内的URL

更新时间:2022-12-11 14:07:15

我通常使用以下方法.首先,在顶部附近的Routeconfig中,注册一个新的Routebase(称为LegacyURLRoute):

I generally use a method such as below. Firstly within Routeconfig near the top I register a new Routebase (called LegacyURLRoute):

routes.Add(new LegacyUrlRoute());

其简化版本如下:

public class LegacyUrlRoute : RouteBase
{
    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var request = httpContext.Request;
        var response = httpContext.Response;
        var legacyUrl = request.Url.ToString().ToLower();
        var legacyPath = request.Path.ToString().ToLower();

        Tuple<bool, bool, string> result = DervieNewURL(legacyPath);
        bool urlMatch = result.Item1;
        bool urlMatchGone = result.Item2;
        var newUrl = result.Item3;

        if (urlMatch)
        {//For 301 Moved Permanently
            response.Clear();
            response.StatusCode = (int)System.Net.HttpStatusCode.MovedPermanently;
            response.RedirectLocation = "http://www.example.com" + newUrl;
            response.End();
        }
        else if (urlMatchGone)
        {// 410 Gone
            response.Clear();
            response.StatusCode = (int)System.Net.HttpStatusCode.Gone;
            response.End();
        }
        return null;
    }
    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return null;
    }
}

然后,上面的DervieNewURL可以在数据库中包括查找,但是最近在一个项目中,我已经将其作为HTMLHelper,它还允许我传递直接来自DB列的URL,然后可以对它们进行解析和解析.已适当更新.

The DervieNewURL above can then include the lookup in the DB, but recently on a project I have had that as a HTMLHelper that also allows me to pass in the URL's that come directly from a DB column and these can then be parsed and updated as appropriate.

DervieNewURL的简单示例如下所示,但是显然您将在表中查找,而不是如下进行硬编码.

Simple example of DervieNewURL could be as follows, but you would obviously lookup in a table rather than having bits hard coded as below.

public static Tuple<bool, bool, string> DervieNewURL(string url)
{
    /*
        return type from this function is as follows:
        Tuple<bool1, bool2, string1, string2>
        bool1 = indicates if we have a replacement url mapped
        bool2 = indicates if we have a url marked as gone (410)
        string1 = indicates replacement url
        */
    Tuple<bool, bool, string> result = new Tuple<bool, bool, string>(false, false, null);
    if (!String.IsNullOrWhiteSpace(url))
    {
        string newUrl = null;
        bool urlMatch = false;
        bool urlMatchGone = false;

        switch (url.ToLower())
        {
            case "/badfoldergone/default.aspx": { urlMatchGone = true; } break;
            case "/oldfoldertoredirect/default.aspx": { urlMatch = true; newUrl = "/somecontroller/someaction"; } break;
            default: { } break;
        }
        result = new Tuple<bool, bool, string>(urlMatch, urlMatchGone, newUrl);

    }
    return result;
}

如果您需要通配符匹配,那么我想您可以修改上面的内容或将其构建到数据库调用匹配条件中.

If you require wildcard matches then I guess you could amend the above or build this into the DB call matching criteria.

通过尽早使用此路由,您可以将旧版url重定向到其他路由,然后在请求沿路由表级联时将被触发.最终,您将使用默认路由,类似于:

By employing this route early on you can redirect legacy url's to other routes that will then be triggered as the request cascades down the routing table. Ultimately you will end up at your Default route similar to:

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

如果开发人员具有硬编码的链接,那么您只需要使用将由这些url触发的路由.通过采用上述方法,可以尽早捕获并通过适当的301 Move或410消失添加到数据库列表中.

If developers have hard coded links then you will just need employ routes that will be triggered by these url's. By employing something such as above can capture most early on and add to the list in your DB with appropriate 301 Moved or 410 gone if required.