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

时间:2011-10-06 13:24:29

标签: c# asp.net-mvc port httprequest appharbor

第一个问题!


环境

MVC,C#,AppHarbor。

问题

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

在我的本地计算机上,如果我点击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%的解决方案,但是我厌倦了考虑我可能缺少的一个简单的财产。我也读过this,但似乎没有接受的答案(更多的是关于路径而不是权威)。所以我把它给你们。

摘要

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

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

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

6 个答案:

答案 0 :(得分:21)

这是AppHarbor等负载均衡设置中的常见问题 - 我们提供了example workaround

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

答案 1 :(得分:1)

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

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

现在我使用Request.Url.AbsolutePath给我/path/to/file.aspx,因此忽略了架构,主机名和端口号。

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

这样的东西
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");

答案 4 :(得分:0)

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

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

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

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

我会将其包装成扩展方法以保持其清洁。

答案 5 :(得分:0)

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

为了让应用程序重定向到子路径而不包括" custom" port,忘记Response / Request对象,并使用Transfer方法。例如,如果我希望用户自动重定向到登录页面,以防他们尚未登录:

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