我试图写使用自定义路线(从RouteBase派生类)类似于301重定向方式处理遗留的URL在MVC的任何水平 。 我被偷看入的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");
这是可取的,因为在我的经验,并不是所有的浏览器都配置为遵循301个重定向(尽管搜索引擎做的)。 所以是有意义的也给用户一个链接页面的情况下,浏览器不会自动去那里。
我想这样做是拿这个去一个新的水平 - 我要输出的MVC视图(其主题页面布局沿)的结果,而不是已经硬编码丑陋通用HTML的响应。 就像是:
private void RedirectPermanent(string destinationUrl, HttpContextBase httpContext)
{
var response = httpContext.Response;
response.Clear();
response.StatusCode = 301;
response.RedirectLocation = destinationUrl;
// Output a Custom View Here
response.Write(The View)
response.End();
}
我怎么能写一个视图响应流的输出?
附加信息
在过去,我们曾与来自mydomain.com 301个重定向问题为www.mydomain.com,并随后得到了很多的来自用户的报告SSL证书是无效的。 搜索引擎做他们的工作,但用户有问题,直到我切换到302重定向。 实际上,我是无法重现它,但我们得到的报告显著号码,这样的东西必须做。
我打算使视图做一元重定向以及JavaScript重定向,以帮助提高可靠性,但对于那些在301页谁仍然最终用户,我希望他们有宾至如归的感觉。 我们已经有了自定义404个500页,为什么不能自定义主题的301页呢?
原来我只是过度思考问题和解决方案就简单多了,比我曾设想。 我真正需要做的是使用的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;
}
我只是需要退回的RouteData,因此它可以由路由器来处理!
还要注意我添加了一个CacheControl头,以防止IE9和Firefox从缓存中无法清除的方式重定向。
现在我有一个显示的链接和消息给用户时,浏览器无法按照301一个漂亮的网页,我会加元重定向和JavaScript重定向到视图启动 - 赔率是浏览器会跟着他们的一个。
也看到这个答案的一个更全面的解决方案。
假设你要访问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();
}
这将使SomeAction
上HomeController
的响应。