我正在使用MVC3创建一个网站,我使用剃刀语法创建视图,它们都在azure下运行。
目前我在本地的天蓝色模拟器下运行。
我在网址上有一个视图:'http://localhost:81/Blah/Foo'。
在该视图中,我想让Url接受其他操作。
要实现这一点,我使用:Url.Action(“SomeAction”,“SomeController”,null,this.Request.Url.Scheme)
然而,由于负载平衡,azure仿真器执行端口号,因此会对更改进行请求。
即。当它在81端口运行时,请求可能来自端口82。
这导致创建了一个不正确的网址“http://localhost:82/Blah/Bar”,我收到了一个400,错误的主机名错误。
根据这篇文章http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/9142db8d-0f85-47a2-91f7-418bb5a0c675/中的信息,我发现我可以使用HttpContext.Request.Headers [“Host”]获得正确的主机和端口号。
但是我只能将主机名传递给Url.Action,如果我尝试传递主机名和端口,那么它仍会附加它认为正确的端口,所以我最终得到localhost:81:82。< / p> 编辑:我发现有人遇到同样的问题。他们似乎收集了我所拥有的相同信息(除了他们也包括了一个复制品),但他们没有一个有用的修复,因为我无法手动指定端口号。
我想一个修复就是让我自己的Url.Action重载让我指定端口。
答案 0 :(得分:23)
对于每个来到这里的人来说,他们实际上需要一条绝对的道路并且在负载平衡系统之后,这就是我想出的:
//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;
}
然后,从https://github.com/aarnott/dotnetopenid/blob/v3.4/src/DotNetOpenAuth/Messaging/HttpRequestInfo.cs到http://go4answers.webhost4life.com/Example/azure-messing-port-numbers-creates-28516.aspx
/// <summary>
/// Gets the public facing URL for the given incoming HTTP request.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="serverVariables">The server variables to consider part of the request.</param>
/// <returns>
/// The URI that the outside world used to create this request.
/// </returns>
/// <remarks>
/// Although the <paramref name="serverVariables"/> value can be obtained from
/// <see cref="HttpRequest.ServerVariables"/>, it's useful to be able to pass them
/// in so we can simulate injected values from our unit tests since the actual property
/// is a read-only kind of <see cref="NameValueCollection"/>.
/// </remarks>
internal static Uri GetPublicFacingUrl(HttpRequestBase request, NameValueCollection serverVariables)
{
//Contract.Requires<ArgumentNullException>(request != null);
//Contract.Requires<ArgumentNullException>(serverVariables != null);
// Due to URL rewriting, cloud computing (i.e. Azure)
// and web farms, etc., we have to be VERY careful about what
// we consider the incoming URL. We want to see the URL as it would
// appear on the public-facing side of the hosting web site.
// HttpRequest.Url gives us the internal URL in a cloud environment,
// So we use a variable that (at least from what I can tell) gives us
// the public URL:
if (serverVariables["HTTP_HOST"] != null)
{
//ErrorUtilities.VerifySupported(request.Url.Scheme == Uri.UriSchemeHttps || request.Url.Scheme == Uri.UriSchemeHttp, "Only HTTP and HTTPS are supported protocols.");
string scheme = serverVariables["HTTP_X_FORWARDED_PROTO"] ?? request.Url.Scheme;
Uri hostAndPort = new Uri(scheme + Uri.SchemeDelimiter + serverVariables["HTTP_HOST"]);
UriBuilder publicRequestUri = new UriBuilder(request.Url);
publicRequestUri.Scheme = scheme;
publicRequestUri.Host = hostAndPort.Host;
publicRequestUri.Port = hostAndPort.Port; // CC missing Uri.Port contract that's on UriBuilder.Port
return publicRequestUri.Uri;
}
// Failover to the method that works for non-web farm enviroments.
// We use Request.Url for the full path to the server, and modify it
// with Request.RawUrl to capture both the cookieless session "directory" if it exists
// and the original path in case URL rewriting is going on. We don't want to be
// fooled by URL rewriting because we're comparing the actual URL with what's in
// the return_to parameter in some cases.
// Response.ApplyAppPathModifier(builder.Path) would have worked for the cookieless
// session, but not the URL rewriting problem.
return new Uri(request.Url, request.RawUrl);
}
答案 1 :(得分:1)
如果您只使用Url.Action(“操作”,“控制器”)会发生什么?这应该只生成一个相对的URL,这应该有用。
(或许更好的问题是:你为什么不使用那种重载?)
答案 2 :(得分:0)
我发现这对我有用......
var request = HttpContext.Request;
string url = request.Url.Scheme + "://" +
request.UserHostAddress + ":" +
request.Url.Port;