获取没有非标准端口的原始URL(C#)

第一个问题!


环境

MVC,C#,AppHarbor。

问题

我正在调用openid提供程序,并根据域生成绝对回调URL。

在我的本地机器上,如果我点击http://localhost:12345/login ,这可以正常工作

 Request.Url; //gives me `http://localhost:12345/callback` 

但是,在我正在部署的AppHarbor上,因为他们正在使用非标准端口,即使我在“ http://sub.example.com/login ”上点击它

 Request.Url; //gives me http://sub.example.com:15232/callback 

这搞砸了我的回调,因为端口号不在原始源URL中!

我试过了

  • Request.Url
  • Request.Url.OriginalString
  • Request.RawUrl

所有这些都给了我“ http://sub.example.com:15232/callback ”。

另外要清除这不是一个Realm问题,我从DotNetOpenAuth得到的错误信息是

 'http://sub.example.com:14107/accounts/openidcallback' not under realm 'http://*.example.com/'. 

我不觉得我塞满了吗?

现在,我要考虑一些像hacky这样的东西

  • 预处理器命令(#IF DEBUG THEN PUT PORT)
  • string replace(Request.URL.Contains(“localhost”))

所有这些都不是100%的解决方案,但我厌倦了仔细考虑可能是一个我不想要的简单财产。 我也读过这个,但似乎没有一个公认的答案(更多的是关于路径而不是权威)。 所以我把它给你们。

摘要

所以,如果我有http://localhost:12345/login ,我需要从Request上下文获取http://localhost:12345/callback

如果我有“ http://sub.example.com/login ”,我应该得到“ http://sub.example.com/callback ”,无论它在哪个端口。

谢谢! (睡觉时间,早上会回答任何问题)

这是AppHarbor等负载均衡设置中的常见问题 – 我们提供了一个示例解决方法 。

更新:对于许多ASP.NET应用程序来说,更理想的解决方案可能是将aspnet:UseHostHeaderForRequestUrl appSetting设置为true 。 我们(AppHarbor)已经看到几个客户在使用WCF应用程序时遇到问题,这就是为什么我们默认情况下没有启用它,并且为这些情况推荐上述解决方案。 您可以使用AppHarbor的“配置变量”对其进行配置,以在部署时注入appsettings。 可以在本文中找到更多信息。

我最近遇到了一个问题,我将URL与当前URL进行了比较,然后基于此突出显示了导航。 它在本地工作,但不在生产中。

我有http://example.com/path/to/file.aspx作为我的文件,但在查看该文件并运行Request.Url.ToString()它生成了https://example.com:81/path/to/file.aspx负载平衡生产环境中的https://example.com:81/path/to/file.aspx

现在我使用Request.Url.AbsolutePath来给我/path/to/file.aspx ,从而忽略模式,主机名和端口号。

当我需要将它与我使用的每个导航项上的URL进行比较时: New Uri(theLink.Href).AbsolutePath

我最初的想法是获取referrer变量并检查是否包含端口,如果是,请使用它,否则不要。

如果这不是一个选项,因为代理可能会删除referrer头变量,那么您可能需要使用一些客户端脚本来获取该位置并将其传递回服务器。

我猜AppHarbor使用端口转发到IIS服务器,所以即使公共站点在端口80上,IIS也将它托管在另一个端口上,因此它无法知道客户端连接的端口。

就像是

 String port = Request.ServerVariables["SERVER_PORT"] == "80" ? "" : ":" + Request.ServerVariables["SERVER_PORT"]; String virtualRoot = Url.Content("~/"); destinationUrl = String.Format("http://{0}{1}{2}", Request.ServerVariables["SERVER_NAME"], port + virtualRoot, "/callback"); 

如果您在框架中使用UrlBuilder类,则可以轻松解决此问题。 在构建器类上,如果将端口设置为-1,则将删除端口号:

 new UriBuilder("http://sub.example.com:15232/callback"){ Port = -1} 

返回: http : //sub.example.com/callback

要在本地计算机上保留端口号,只需检查Request.IsLocal并且不要将-1应用于端口。

我会把它包装成一个扩展方法来保持它的清洁。

我看到这是一个旧线程。 我有这个问题在IIS 7.5上运行MVC5,前面有一个Apache代理。 在服务器之外,我会得到“空响应”,因为asp.net应用程序通过自定义端口从apache获取Url。

为了让应用程序重定向到子路径而不包括“自定义”端口,请忘记响应/请求对象,并使用Transfer方法。 例如,如果我希望用户自动重定向到登录页面,以防他们未被记录:

 if (!User.Identity.IsAuthenticated) Server.TransferRequest("Account/Login");