【问题标题】:Redirect to dynamically added URL in MVC 5重定向到 MVC 5 中动态添加的 URL
【发布时间】:2017-07-05 17:45:22
【问题描述】:

我的要求是将用户从旧网址重定向到新网址。我的实体如下:

public class HttpRedirect
{
    [Key]
    public int Id { get; set; }

    [Required(ErrorMessage = "Old url is required.")]
    [MaxLength(1000)]
    //[Url]
    [Display(Name = "Old Url")]
    public string OldUrl { get; set; }


    [Required(ErrorMessage = "New url is required.")]
    [MaxLength(1000)]
    //[Url]
    [Display (Name = "New Url")]
    public string NewUrl { get; set; }

}

Url 已注释,以便我可以在 localhost 中工作。

所以当请求旧网址时,我希望将请求转移到新网址 为了在 Application_BeginRequest 事件中的 global.asax 文件中实现这一点,我有以下代码

protected void Application_BeginRequest(object sender, EventArgs e)
{
  //You don't want to redirect on posts, or images/css/js
  bool isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get");
  if (isGet && HttpContext.Current.Request.Url.AbsolutePath.Contains(".") == false)
  {
    string lowercaseURL = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
    string newUrl = new HttpRedirectRepository().RedirectUrl(lowercaseURL);
    if(newUrl != null)
       {
         lowercaseURL = newUrl;
       }
     lowercaseURL = lowercaseURL.ToLower().Trim() + HttpContext.Current.Request.Url.Query;
     Response.Clear();
     Response.Status = "301 Moved Permanently";
     Response.AddHeader("Location", lowercaseURL);
     Response.End();
   }
}

我已经实现了上面的代码来完成 2 个任务。 1. 将网址改为小写 2. 如果请求的 url 有新的 url 可用,则重定向到该 url。

通过我的上述实现,我强烈感觉它可以工作,但通过重定向到 lowercaseURL

会导致无限循环

那么我怎样才能防止多次重定向。例如 我请求 http://localhost:80/mypage 并将其新 url 设置为 http://localhost:80/home 然后当请求 mypage 时,它​​应该重定向到小写的家庭制作 url,并且重定向应该只发生一次。

注意

  1. 我只需要在我自己的域内重定向。
  2. 用户将为旧网址和新网址输入完整的网址。

更新

在@RobertHarvey 的一些提示下,我修改了我的代码,如下所示,这对我有用

protected void Application_BeginRequest(object sender, EventArgs e)
{
  //You don't want to redirect on posts, or images/css/js
  bool isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get");
  if (isGet && HttpContext.Current.Request.Url.AbsolutePath.Contains(".") == false)
  {
    bool redirect = false;
    string requestUrl = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
    //You don't want to change casing on query strings
    string newUrl = new HttpRedirectRepository().RedirectUrl(requestUrl);
    if (newUrl != null)
    {
      requestUrl = newUrl;
      redirect = true;
     }
     if (Regex.IsMatch(requestUrl, @"[A-Z]"))
     {
       requestUrl = requestUrl.ToLower().Trim() + HttpContext.Current.Request.Url.Query;
       redirect = true;
      }
      if (redirect)
      {
        Response.Clear();
        Response.Status = "301 Moved Permanently";
        Response.AddHeader("Location", requestUrl);
        Response.End();
       }
    }
} 

虽然我仍然相信更新的实现有一些限制。我将不胜感激任何进一步的代码增强和案例覆盖。

【问题讨论】:

  • 无限循环意味着,你的 Home 控制器被反复调用?
  • @SivaGopal 是的,因为 beginrequest 也针对重定向的 url 执行,并且该 url 还通过添加响应标头 Location 来响应,这会导致另一个重定向,并且此过程会继续进行。我遇到类似的情况,例如在 Home.aspx 页面加载事件中编写 Response.Redirect("~/Home.aspx")。
  • 你能简单地添加一个if 条件来阻止第二次重定向吗?
  • 你能展示一些你在 Home.aspx 中所做的示例代码吗?
  • @RobertHarvey 我试图通过在会话中写入 url 来做到这一点,但在处理开始请求时会话对象不可用。所以我想我需要在开始请求中引入一些变量。

标签: c# asp.net-mvc asp.net-mvc-5 mvcroutehandler


【解决方案1】:

你的两个“笔记”是矛盾的。如果您只想在您的域内允许重定向,那么记录完整的 URL(包括域)是完全没有必要的,只会使事情复杂化。使旧/新 URL 只是绝对路径。这也解决了您在开发与生产中工作的问题,因为您无需担心数据在正确的环境中具有正确的域。

注意:您的无限重定向是您代码中的错误。你应该重定向到newUrl,而不是lowercaseUrl。在newUrl 为空的情况下,没有重定向,所以在这种情况下你根本不应该重定向。

【讨论】:

  • 这如何解决他的无限重定向问题?
  • @Chris Pratt 用户添加完整的 url 比添加协议和域名以外的内容更容易。虽然我们可以从完整的 ur 中获取绝对 url。使用绝对 url 怎么办?
  • 重定向不需要完整的 URL。只需重定向到路径,就会假定当前的域和协议。
猜你喜欢
  • 2012-03-07
  • 2015-03-15
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 2010-09-26
  • 2014-07-01
  • 1970-01-01
相关资源
最近更新 更多