Asp.net 如何获取Url.Action以使用正确的端口号?

Asp.net 如何获取Url.Action以使用正确的端口号?,asp.net,asp.net-mvc-3,azure,Asp.net,Asp.net Mvc 3,Azure,我正在使用MVC3创建一个网站,我正在使用razor语法创建视图,所有这些都在azure下运行 目前我正在本地azure模拟器下运行 我在url“”处有一个视图 在该视图中,我想获取另一个操作的Url 为了实现这一点,我使用:Url.Action(“SomeAction”,“SomeController”,null,this.Request.Url.Scheme) 但是,由于负载平衡,azure emulator不会更改端口号,因此会在更改时发出请求 i、 e.当它在端口81上运行时,请求可能来

我正在使用MVC3创建一个网站,我正在使用razor语法创建视图,所有这些都在azure下运行

目前我正在本地azure模拟器下运行

我在url“”处有一个视图

在该视图中,我想获取另一个操作的Url

为了实现这一点,我使用:Url.Action(“SomeAction”,“SomeController”,null,this.Request.Url.Scheme)

但是,由于负载平衡,azure emulator不会更改端口号,因此会在更改时发出请求

i、 e.当它在端口81上运行时,请求可能来自端口82

这会导致创建不正确的url“”,我得到一个400错误的主机名错误

根据本文中的信息,我发现我可以使用HttpContext.Request.Headers[“host”]获得正确的主机和端口号

但是我只能将主机名传递给Url.Action,如果我尝试传递主机名和端口,它仍然会附加它认为正确的端口,因此我最终得到localhost:81:82

编辑:我发现有人有同样的问题。他们似乎收集了与我相同的信息(除了他们也包含了一个复制品),但他们没有一个有用的修复程序,因为我无法手动指定端口号


我想一个解决办法是创建自己的Url.Action重载,让我指定端口。

如果只使用Url.Action(“Action”、“Controller”)会发生什么?这应该只是生成一个相对URL,它应该可以工作


(或者一个更好的问题是:你为什么不使用超负荷?

对于来到这里的每一位真正需要绝对路径并支持负载平衡系统的人,我提出了以下建议:

//http://stackoverflow.com/questions/126242/how-do-i-turn-a-relative-url-into-a-full-url
public static string AbsoluteAction(this UrlHelper url, string actionName, string controllerName, object routeValues = null)
{
  Uri publicFacingUrl = GetPublicFacingUrl(url.RequestContext.HttpContext.Request, url.RequestContext.HttpContext.Request.ServerVariables);
  string relAction = url.Action(actionName, controllerName, routeValues);
  //this will always have a / in front of it.
  var newPort = publicFacingUrl.Port == 80 || publicFacingUrl.Port == 443 ? "" : ":"+publicFacingUrl.Port.ToString();
  return publicFacingUrl.Scheme + Uri.SchemeDelimiter + publicFacingUrl.Host + newPort + relAction;
}
然后,从via

//
///获取给定传入HTTP请求的面向公共的URL。
/// 
///请求。
//服务器变量考虑请求的一部分。
/// 
///外部世界用于创建此请求的URI。
/// 
/// 
///虽然该值可以从
///,能够通过考试是很有用的
///在中,我们可以模拟单元测试中的注入值,因为实际属性
///是一种只读类型。
/// 
内部静态Uri GetPublicFacingUrl(HttpRequestBase请求,NameValueCollection服务器变量)
{
//Contract.Requires(请求!=null);
//Contract.Requires(serverVariables!=null);
//由于URL重写,云计算(即Azure)
//还有网络农场等等,我们必须非常小心
/我们考虑传入的URL。我们希望看到URL。
//出现在托管网站面向公众的一侧。
//Url为我们提供了云环境中的内部Url,
//因此,我们使用一个变量(至少从我所知道的)来
//公共URL:
if(serverVariables[“HTTP_HOST”]!=null)
{
//ErrorUtilities.VerifySupported(request.Url.Scheme==Uri.UriSchemeHttps | | request.Url.Scheme==Uri.UriSchemeHttp,“仅支持HTTP和HTTPS协议”);
string scheme=serverVariables[“HTTP\u X\u FORWARDED\u PROTO”]??request.Url.scheme;
Uri hostAndPort=新Uri(scheme+Uri.SchemeDelimiter+serverVariables[“HTTP_HOST”]);
UriBuilder publicRequestUri=新的UriBuilder(request.Url);
publicRequestUri.Scheme=Scheme;
publicRequestUri.Host=hostAndPort.Host;
publicRequestUri.Port=hostAndPort.Port;//CC缺少UriBuilder.Port上的Uri.Port协定
返回publicRequestUri.Uri;
}
//故障转移到适用于非web场环境的方法。
//我们使用Request.Url作为服务器的完整路径,并对其进行修改
//使用Request.RawUrl捕获无Cookie会话“目录”(如果存在)
//和原始路径,以防URL重写正在进行。我们不想这样做
//被URL重写愚弄了,因为我们将实际URL与
//在某些情况下返回参数。
//ApplyAppPathModifier(builder.Path)本来可以用于无cookieless
//会话,但不是URL重写问题。
返回新的Uri(request.Url,request.RawUrl);
}

我发现这对我有用

var request = HttpContext.Request;
string url = request.Url.Scheme + "://" +
             request.UserHostAddress +  ":" +
             request.Url.Port;

奇怪的是,你使用的是负载平衡,所以你试图强迫所有用户连接到他们开始使用的同一台机器?azure emulator是造成端口号混乱的原因。我很乐意禁用它,如果它允许我在本地进行调试:)问题的核心是azure emulator使用不同的端口,我从端口81开始工作,然后它切换到端口82,这给了我一个400坏主机http错误。@BuildStarted-你在这里提出了一个好的观点。我可能看错了。问题不在于它使用了错误的端口号,而是当Azure Emulator在端口81和82之间进行负载平衡时,mvc应用程序(在IIS上运行,在Azure Emulator后面)只在端口81上接受。有趣的是,我们的负载平衡器让所有的机器都在同一个端口上,但由于它们是不同的机器,所以没有冲突。这听起来像是Azure emulator的一个限制,从技术角度来看是有意义的。在过去,我们似乎在生成http和https链接时遇到了问题,这导致显式使用协议参数。然而,在这种情况下,仅仅生成相对链接正是我想要的,我相信它会解决所有问题。非常感谢!为此目的使用推荐人是一个非常糟糕的主意。使用当前url,而不是推荐人url。referer是以前的url,可以为空。这是我发现的最全面的解决方案。谢谢
var request = HttpContext.Request;
string url = request.Url.Scheme + "://" +
             request.UserHostAddress +  ":" +
             request.Url.Port;