ASP.Net MVC路线捕获所有*的.aspx请求 [英] ASP.Net MVC route to catch all *.aspx requests

查看:254
本文介绍了ASP.Net MVC路线捕获所有*的.aspx请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此的必须的已经问过,但看完后的这里,<一个href=\"http://stackoverflow.com/questions/7515644/infinite-url-parameters-for-asp-net-mvc-route\">here, <一href=\"http://stackoverflow.com/questions/4001081/asp-net-mvc-catch-all-route-and-default-route\">here和这里我不能推断相关部件,使其工作。我改造老网络形式的网站成为MVC,并想抓住特定的传入的HTTP请求,这样我可以发出永久重定向(保护我们的谷歌排名,避免用户离开因404的)。

而不是拦截的所有的传入的请求,或解析某些 ID 价值,我需要拦截结束(或含)的所有请求在的.aspx 文件的扩展名,例如:

  www.sample.com/default.aspx
www.sample.com/somedir/file.aspx
www.sample.com/somedir/file.aspx?foo=bar

请求到MVC路线应该被忽略(只处理为正常)。

下面是我到目前为止,除了 ASPXFiles 路线从来没有被击中。

 公共类RouteConfig
{
    公共静态无效的RegisterRoutes(RouteCollection路线)
    {
        routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);        //从来没有产生匹配
        routes.MapRoute(
            名称:ASPXFiles
            网址:*的.aspx
            默认:新{控制器=ASPXFiles,行动=索引}
        );        //用于处理所有其他请求(正常工作)
        routes.MapRoute(
            名称:默认,
            网址:{控制器} / {行动} / {ID}
            默认:新{控制器=家,行动=索引,ID = UrlParameter.Optional}
        );
    }
}

}

这类型的路由可能在MVC设置?


解决方案

我展示的右键的办法,使在MVC 301重定向,因为不是所有的浏览器301响应请求重定向正常,而你需要给用户一个选项以继续,而不是由ASP.NET生成的默认对象移动页面。

RedirectAspxPermanentRoute

我们建立一个自定义 RouteBase 子检测当网址的.aspx 结束,路线,我们的 SystemController 设置301重定向。它要求你在地图中的URL(URL以匹配)来路由的值(其被用于生成了MVC的URL)来传递。

 公共类RedirectAspxPermanentRoute:RouteBase
{
    私人只读IDictionary的&LT;字符串对象&gt; urlMap;    公共RedirectAspxPermanentRoute(IDictionary的&LT;字符串对象&gt; urlMap)
    {
        如果(urlMap == NULL)
            抛出新的ArgumentNullException(urlMap);        this.urlMap = urlMap;
    }    公众覆盖的RouteData GetRouteData(HttpContextBase的HttpContext)
    {
        VAR路径= httpContext.Request.Path;
        如果(path.EndsWith(ASPX))
        {
            如果(!urlMap.ContainsKey(路径))
                返回null;            VAR routeValues​​ = urlMap [路径];
            VAR的RouteData =新的RouteData(这一点,新MvcRouteHandler());            routeData.Values​​ [控制器] =系统;
            routeData.Values​​ [行动] =Status301;
            routeData.DataTokens [routeValues​​] = routeValues​​;            返回的RouteData;
        }        返回null;
    }    公众覆盖VirtualPathData GetVirtualPath(RequestContext的的RequestContext,RouteValueDictionary值)
    {
        返回null;
    }
}

注意,第一次检查是的.aspx 扩展,所以逻辑的其余部分将完全跳过如果扩展名不匹配。这将会为您的方案提供最佳的性能。

SystemController

我们设置了 SystemController 来返回一个视图,我们通常会。如果浏览器不因为301重定向,用户将看到的视图。

 使用系统;
使用System.Net;
使用的System.Web;
使用System.Web.Mvc;公共类SystemController:控制器
{
    //
    // GET:/系统/ Status301 /    公众的ActionResult Status301()
    {
        VAR routeValues​​ = this.Request.RequestContext.RouteData.DataTokens [routeValues​​];
        VAR URL = this.GetAbsoluteUrl(routeValues​​);        Response.CacheControl =无缓存;
        Response.Status code =(INT)的HTTPStatus code.MovedPermanently;
        Response.RedirectLocation =网址;        ViewBag.DestinationUrl =网址;
        返回查看();
    }    私人字符串GetAbsoluteUrl(对象routeValues​​)
    {
        VAR urlBuilder =新UriBuilder(Request.Url.AbsoluteUri)
        {
            路径= Url.RouteUrl(routeValues​​)
        };        变种EN codedAbsoluteUrl = urlBuilder.Uri.ToString();
        返回HttpUtility.UrlDe code(EN codedAbsoluteUrl);
    }
}

Status301.cshtml

请按照MVC的约定,并务必把这个在 /查看/系统/ 文件夹中。

由于它是为你的301响应的视图,你可以把它匹配您的网站的其余部分的主题。因此,如果用户在这里结束了,它仍然不是一个坏的经验。

该视图会尝试将用户通过JavaScript的的通过元刷新自动重定向。这两个可以在浏览器被关闭,但机会是用户将使其在那里它们被假定去。如果没有,你应该告诉用户:


  1. 的页面有一个新的位置。

  2. 他们需要点击链接,如果没有自动重定向。

  3. 他们应该更新自己的书签。


  @ {
    ViewBag.Title =页面移动;
}
@section MetaRefresh {
    &LT; META HTTP-当量=刷新内容=10; @ ViewBag.DestinationUrl/&GT;
}&LT; H2类=错误&gt;页面移动与LT; / H&GT;
&所述p为H.;
    该页面已移动。点击以下网址,如果你是
    未在5秒内自动重定向。一定要更新您的书签。
&所述; / P&GT;
&所述; A HREF =@ ViewBag.DestinationUrl&GT; @ ViewBag.DestinationUrl&下; / a取代。&LT;脚本&GT;
    //&LT;! -
    的setTimeout(函数(){
        window.location的=@ ViewBag.DestinationUrl
    },5000);
    // - &GT;
&LT; / SCRIPT&GT;

用法

首先,你需要一节添加到您的 _Layout.cshtml 所以元刷新可以添加到您的网页的头部分。

 &LT;!DOCTYPE HTML&GT;
&LT; HTML LANG =ENGT&;
    &LT; HEAD&GT;
        &LT;间的charset =UTF-8/&GT;
        &LT;标题&GT; @ ViewBag.Title - 我的ASP.NET MVC应用程序和LT; /标题&GT;
        &LT;链接HREF =〜/ favicon.ico的相对=快捷方式图标类型=图像/ X-图标/&GT;
        &LT;! - 收藏此这样的观点可以更新本节 - &GT;
        @RenderSection(MetaRefresh,必需:false)
        &LT; META NAME =视口CONTENT =WIDTH =设备宽度/&GT;
        @ Styles.Render(〜/内容/ CSS)
        @ Scripts.Render(〜/包/ Modernizr的)
    &LT; /头&GT;    &LT;! - 布局code省略 - &GT;&LT; / HTML&GT;

然后添加 RedirectAspxRoute 你的路由配置。

 公共类RouteConfig
{
    公共静态无效的RegisterRoutes(RouteCollection路线)
    {
        routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);        routes.Add(新RedirectAspxPermanentRoute(
            新字典&LT;字符串对象&gt;()
            {
                //旧的URL在左边,右边新路线的值。
                {@/约-us.aspx,新{控制器=家,行动=关于},
                {@/接触us.aspx,新{控制器=家,行动=联系}}
            })
        );        routes.MapRoute(
            名称:默认,
            网址:{控制器} / {行动} / {ID}
            默认:新{控制器=家,行动=索引,ID = UrlParameter.Optional}
        );
    }
}

This must have been asked before, but after reading here, here, here and here I can't extrapolate the relevant parts to make it work. I am revamping an old web forms site into MVC, and want to catch particular incoming HTTP requests so that I can issue a RedirectPermanent (to protect our Google rankings and avoid users leaving due to 404's).

Rather than intercept all incoming requests, or parse for some id value, I need to intercept all requests that end in (or contain) the .aspx file extension, e.g.

www.sample.com/default.aspx
www.sample.com/somedir/file.aspx
www.sample.com/somedir/file.aspx?foo=bar

Requests to the MVC routes should be ignored (just processed as normal).

Here's what I have so far, except the ASPXFiles route is never being hit.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // never generates a match
        routes.MapRoute(
            name: "ASPXFiles",
            url: "*.aspx",
            defaults: new { controller = "ASPXFiles", action = "Index" }
        );

        // Used to process all other requests (works fine)
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

}

Is this type of route possible to set up in MVC?

解决方案

I am showing the right way to make a 301 redirect in MVC, since not all browsers respond to 301 redirect requests properly, and you need to give the user an option to continue rather than the default "Object Moved" page that is generated by ASP.NET.

RedirectAspxPermanentRoute

We build a custom RouteBase subclass that detects when a URL ends with .aspx and routes to our SystemController to setup the 301 redirect. It requires you to pass in a map of URL (the URL to match) to route values (which are used to generate the MVC URL).

public class RedirectAspxPermanentRoute : RouteBase
{
    private readonly IDictionary<string, object> urlMap;

    public RedirectAspxPermanentRoute(IDictionary<string, object> urlMap)
    {
        if (urlMap == null)
            throw new ArgumentNullException("urlMap");

        this.urlMap = urlMap;
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var path = httpContext.Request.Path;
        if (path.EndsWith(".aspx"))
        {
            if (!urlMap.ContainsKey(path))
                return null;

            var routeValues = urlMap[path];
            var routeData = new RouteData(this, new MvcRouteHandler());

            routeData.Values["controller"] = "System";
            routeData.Values["action"] = "Status301";
            routeData.DataTokens["routeValues"] = routeValues;

            return routeData;
        }

        return null;
    }

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        return null;
    }
}

Note that the first check is for the .aspx extension, so the rest of the logic will be entirely skipped if the extension doesn't match. This will provide the best performance for your scenario.

SystemController

We setup the SystemController to return a view as we normally would. If the browser doesn't redirect because of the 301, the user will see the view.

using System;    
using System.Net;
using System.Web;
using System.Web.Mvc;

public class SystemController : Controller
{
    //
    // GET: /System/Status301/

    public ActionResult Status301()
    {
        var routeValues = this.Request.RequestContext.RouteData.DataTokens["routeValues"];
        var url = this.GetAbsoluteUrl(routeValues);

        Response.CacheControl = "no-cache";
        Response.StatusCode = (int)HttpStatusCode.MovedPermanently;
        Response.RedirectLocation = url;

        ViewBag.DestinationUrl = url;
        return View();
    }

    private string GetAbsoluteUrl(object routeValues)
    {
        var urlBuilder = new UriBuilder(Request.Url.AbsoluteUri)
        {
            Path = Url.RouteUrl(routeValues)
        };

        var encodedAbsoluteUrl = urlBuilder.Uri.ToString();
        return HttpUtility.UrlDecode(encodedAbsoluteUrl);
    }
}

Status301.cshtml

Follow the conventions of MVC and be sure to place this in the /Views/System/ folder.

Because it is a view for your 301 response, you can make it match the theme of the rest of your site. So, if the user ends up here, it is still not a bad experience.

The view will attempt to redirect the user automatically via JavaScript and via Meta-Refresh. Both of these can be turned off in the browser, but chances are the user will make it where they are supposed to go. If not, you should tell the user:

  1. The page has a new location.
  2. They need to click the link if not automatically redirected.
  3. They should update their bookmark.


@{
    ViewBag.Title = "Page Moved";
}
@section MetaRefresh {
    <meta http-equiv="refresh" content="5;@ViewBag.DestinationUrl" />
}

<h2 class="error">Page Moved</h2>
<p>
    The page has moved. Click on the following URL if you are 
    not redirected automatically in 5 seconds. Be sure to update your bookmarks.
</p>
<a href="@ViewBag.DestinationUrl">@ViewBag.DestinationUrl</a>.

<script>
    //<!--
    setTimeout(function () {
        window.location = "@ViewBag.DestinationUrl";
    }, 5000);
    //-->
</script>

Usage

First you need to add a section to your _Layout.cshtml so the Meta-refresh can be added to the head section of your page.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>@ViewBag.Title - My ASP.NET MVC Application</title>
        <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <!-- Add this so the view can update this section -->
        @RenderSection("MetaRefresh", required: false)
        <meta name="viewport" content="width=device-width" />
        @Styles.Render("~/Content/css")
        @Scripts.Render("~/bundles/modernizr")
    </head>

    <!-- layout code omitted -->

</html>

Then add the RedirectAspxRoute to your routing configuration.

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.Add(new RedirectAspxPermanentRoute(
            new Dictionary<string, object>() 
            {
                // Old URL on the left, new route values on the right.
                { @"/about-us.aspx", new { controller = "Home", action = "About" } },
                { @"/contact-us.aspx", new { controller = "Home", action = "Contact" }  }
            })
        );

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

这篇关于ASP.Net MVC路线捕获所有*的.aspx请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆