Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 创建自定义301重定向页面_Asp.net Mvc_Asp.net Mvc 4_Asp.net Mvc Routing_Url Routing_Httpresponse - Fatal编程技术网

Asp.net mvc 创建自定义301重定向页面

Asp.net mvc 创建自定义301重定向页面,asp.net-mvc,asp.net-mvc-4,asp.net-mvc-routing,url-routing,httpresponse,Asp.net Mvc,Asp.net Mvc 4,Asp.net Mvc Routing,Url Routing,Httpresponse,我正在尝试使用自定义路由(从RouteBase派生的类)编写301重定向方案,类似于。我正在使用reflector查看RedirectPermanent()方法中的HttpResponse类,注意到该代码既设置了状态,又输出了一个简单的HTML页面 this.StatusCode = permanent ? 0x12d : 0x12e; this.RedirectLocation = url; if (UriUtil.IsSafeScheme(url)) {

我正在尝试使用自定义路由(从RouteBase派生的类)编写301重定向方案,类似于。我正在使用reflector查看RedirectPermanent()方法中的HttpResponse类,注意到该代码既设置了状态,又输出了一个简单的HTML页面

    this.StatusCode = permanent ? 0x12d : 0x12e;
    this.RedirectLocation = url;
    if (UriUtil.IsSafeScheme(url))
    {
        url = HttpUtility.HtmlAttributeEncode(url);
    }
    else
    {
        url = HttpUtility.HtmlAttributeEncode(HttpUtility.UrlEncode(url));
    }
    this.Write("<html><head><title>Object moved</title></head><body>\r\n");
    this.Write("<h2>Object moved to <a href=\"" + url + "\">here</a>.</h2>\r\n");
    this.Write("</body></html>\r\n");
如何将视图的输出写入响应流

其他信息

在过去,我们在从mydomain.com到www.mydomain.com的301重定向中遇到了问题,随后从用户那里收到了大量关于SSL证书无效的报告。搜索引擎做了他们的工作,但是用户有问题,直到我切换到302重定向。我实际上无法复制它,但我们收到了大量的报告,因此必须采取一些措施


我计划让视图执行元重定向和javascript重定向,以帮助提高可靠性,但对于那些仍停留在301页面上的用户,我希望他们感到宾至如归。我们已经有自定义404和500页,为什么不也有自定义主题301页?

假设您可以访问
HttpContextBase
以下是如何将控制器操作的内容呈现给响应:

private void RedirectPermanent(string destinationUrl, HttpContextBase httpContext)
{
    var response = httpContext.Response;

    response.Clear();
    response.StatusCode = 301;
    response.RedirectLocation = destinationUrl;

    // Output a Custom View Here (HomeController/SomeAction in this example)
    var routeData = new RouteData();
    routeData.Values["controller"] = "Home";
    routeData.Values["action"] = "SomeAction";
    IController homeController = new HomeController();
    var rc = new RequestContext(new HttpContextWrapper(context), routeData);
    homeController.Execute(rc);

    response.End();
}

这将在
HomeController
上向响应呈现
SomeAction

假设您有权访问
HttpContextBase
以下是如何向响应呈现控制器操作的内容:

private void RedirectPermanent(string destinationUrl, HttpContextBase httpContext)
{
    var response = httpContext.Response;

    response.Clear();
    response.StatusCode = 301;
    response.RedirectLocation = destinationUrl;

    // Output a Custom View Here (HomeController/SomeAction in this example)
    var routeData = new RouteData();
    routeData.Values["controller"] = "Home";
    routeData.Values["action"] = "SomeAction";
    IController homeController = new HomeController();
    var rc = new RequestContext(new HttpContextWrapper(context), routeData);
    homeController.Execute(rc);

    response.End();
}

这将在
HomeController
上对响应执行
SomeAction

结果表明,我只是过度思考了问题,解决方案比我预想的要简单得多。我真正需要做的就是使用routeData将请求推送到另一个控制器操作。让我不高兴的是需要附加到请求中的额外301状态信息

    private RouteData RedirectPermanent(string destinationUrl, HttpContextBase httpContext)
    {
        var response = httpContext.Response;

        response.CacheControl = "no-cache";
        response.StatusCode = 301;
        response.RedirectLocation = destinationUrl;

        var routeData = new RouteData(this, new MvcRouteHandler());
        routeData.Values["controller"] = "Home";
        routeData.Values["action"] = "Redirect301";
        routeData.Values["url"] = destinationUrl;

        return routeData;
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData result = null;

        // Do stuff here...

        if (this.IsDefaultUICulture(cultureName))
        {
            var urlWithoutCulture = url.ToString().ToLowerInvariant().Replace("/" + cultureName.ToLowerInvariant(), "");

            return this.RedirectPermanent(urlWithoutCulture, httpContext);
        }

        // Get the page info here...

        if (page != null)
        {
            result = new RouteData(this, new MvcRouteHandler());

            result.Values["controller"] = page.ContentType.ToString();
            result.Values["action"] = "Index";
            result.Values["id"] = page.ContentId;
        }

        return result;

    }
我只需要返回RoutedData,这样路由器就可以处理它了

注意,我还添加了一个CacheControl头,以防止IE9和Firefox以无法清除的方式缓存重定向

现在,我有了一个很好的页面,当浏览器无法遵循301时,它会向用户显示一个链接和消息,我会向视图添加一个元重定向和javascript重定向,以引导-很可能浏览器会遵循其中之一

有关更全面的解决方案,请参见


事实证明,我只是过度思考了这个问题,解决方案比我想象的要简单得多。我真正需要做的就是使用routeData将请求推送到另一个控制器操作。让我不高兴的是需要附加到请求中的额外301状态信息

    private RouteData RedirectPermanent(string destinationUrl, HttpContextBase httpContext)
    {
        var response = httpContext.Response;

        response.CacheControl = "no-cache";
        response.StatusCode = 301;
        response.RedirectLocation = destinationUrl;

        var routeData = new RouteData(this, new MvcRouteHandler());
        routeData.Values["controller"] = "Home";
        routeData.Values["action"] = "Redirect301";
        routeData.Values["url"] = destinationUrl;

        return routeData;
    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        RouteData result = null;

        // Do stuff here...

        if (this.IsDefaultUICulture(cultureName))
        {
            var urlWithoutCulture = url.ToString().ToLowerInvariant().Replace("/" + cultureName.ToLowerInvariant(), "");

            return this.RedirectPermanent(urlWithoutCulture, httpContext);
        }

        // Get the page info here...

        if (page != null)
        {
            result = new RouteData(this, new MvcRouteHandler());

            result.Values["controller"] = page.ContentType.ToString();
            result.Values["action"] = "Index";
            result.Values["id"] = page.ContentId;
        }

        return result;

    }
我只需要返回RoutedData,这样路由器就可以处理它了

注意,我还添加了一个CacheControl头,以防止IE9和Firefox以无法清除的方式缓存重定向

现在,我有了一个很好的页面,当浏览器无法遵循301时,它会向用户显示一个链接和消息,我会向视图添加一个元重定向和javascript重定向,以引导-很可能浏览器会遵循其中之一

有关更全面的解决方案,请参见


哪些浏览器不支持301重定向?@jrummell:我知道有很多插件(随着tinyurl等的发展)会停止重定向。尽管浏览器支持它,但出于安全原因,用户选择退出。这是为了保护用户免受网络钓鱼吗?@jrummell:phishing并试图将用户转发到具有0天攻击的站点。(我个人有我的,以避免跳跃超过1)。@NightOwl:视图是固定的,基于重定向路线还是其他什么?你应该能够启动一个新的ViewContext并将其转储(假设你知道要显示什么)。哪些浏览器不支持301重定向?@jrummell:我知道有很多插件(随着tinyurl等的发展)会停止重定向。尽管浏览器支持它,但出于安全原因,用户选择退出。这是为了保护用户免受网络钓鱼吗?@jrummell:phishing并试图将用户转发到具有0天攻击的站点。(我个人有我的,以避免跳跃超过1)。@NightOwl:视图是固定的,基于重定向路线还是其他什么?您应该能够启动一个新的ViewContext并将其转储(假设您知道要显示什么)。正如上面我的方法签名所示,它接受HttpContextBase作为参数。然而,我很好奇请求上下文调用是否会再次击中路由器(请记住,此重定向代码本身将位于路由器中)。我不太确定,尝试它将为您提供一个明确的答案。没有乐趣。在尝试解析布局页面上的某些链接时,我得到了一个“System.Threading.LockRecursionException:此模式下不允许递归读取锁获取”。它是从MVC框架的RouteCollectionExtensions.FilterRouteCollectionByArea()方法中抛出的,该方法由ActionLink()调用。这看起来很有希望。正如上面我的方法签名所示,它接受HttpContextBase作为参数。然而,我很好奇请求上下文调用是否会再次击中路由器(请记住,此重定向代码本身将位于路由器中)。我不太确定,尝试它将为您提供一个明确的答案。没有乐趣。在尝试解析布局页面上的某些链接时,我得到了一个“System.Threading.LockRecursionException:此模式下不允许递归读取锁获取”。它是从MVC框架的RouteCollectionExtensions.FilterRouteCollectionByArea()方法中抛出的,该方法由ActionLink()调用。