@Url.Content не разрешает абсолютный путь на одном сервере, но делает это на другом

В настоящее время у нас есть два разных сервера в одном домене. Но один сервер решает

@Url.Content("~/api/Пользователь")'

as

http://domain.com/virtualdirectory/api/User

где, поскольку другой сервер не разрешает это абсолютно; скорее, он разрешает это относительно как

API/пользователь

Кодовая база такая же, и мы используем MVC4. Я не уверен, где мы ошиблись, или есть ли какие-либо настройки IIS/DNS, которые необходимо выполнить, чтобы исправить это.

Любая помощь приветствуется; спасибо :)


person Salman    schedule 20.01.2014    source источник
comment
Хотя в документах говорится, что это генерирует абсолютный путь, похоже, что внутренняя реализация возвращает URL-адрес, который отлично работает на стороне клиента (он вызывает PathHelpers.GenerateClientUrl). Ваше второе приложение установлено в корне сервера или в виртуальном каталоге?   -  person JotaBe    schedule 20.01.2014
comment
Оба устанавливаются как приложения, их AppPool и разрешения идентичны.   -  person Salman    schedule 20.01.2014


Ответы (1)


Это связано с модулем перезаписи IIS на вашем веб-сервере IIS, который возвращает путь к http://domain.com/virtualdirectory/api/User

Взгляните на часть исходного кода @Url.Content ниже:

private static string GenerateClientUrlInternal(HttpContextBase httpContext, string contentPath)
{
     if (String.IsNullOrEmpty(contentPath))
     {
          return contentPath;
     }

     // can't call VirtualPathUtility.IsAppRelative since it throws on some inputs
     bool isAppRelative = contentPath[0] == '~';
     if (isAppRelative)
     {
           string absoluteContentPath = VirtualPathUtility.ToAbsolute(contentPath, httpContext.Request.ApplicationPath);
           return GenerateClientUrlInternal(httpContext, absoluteContentPath);
     }

     // we only want to manipulate the path if URL rewriting is active for this request, else we risk breaking the generated URL
     bool wasRequestRewritten = _urlRewriterHelper.WasRequestRewritten(httpContext);
     if (!wasRequestRewritten)
     {
            return contentPath;
     }

     // Since the rawUrl represents what the user sees in his browser, it is what we want to use as the base
     // of our absolute paths. For example, consider mysite.example.com/foo, which is internally
     // rewritten to content.example.com/mysite/foo. When we want to generate a link to ~/bar, we want to
     // base it from / instead of /foo, otherwise the user ends up seeing mysite.example.com/foo/bar,
     // which is incorrect.
     string relativeUrlToDestination = MakeRelative(httpContext.Request.Path, contentPath);
     string absoluteUrlToDestination = MakeAbsolute(httpContext.Request.RawUrl, relativeUrlToDestination);
     return absoluteUrlToDestination;
}

Используйте приведенные ниже коды, чтобы проверить, перезаписываются ли URL-адреса ваших веб-серверов:

bool requestWasRewritten = (httpWorkerRequest != null && httpWorkerRequest.GetServerVariable("IIS_WasUrlRewritten") != null);

А также:

private volatile bool _urlRewriterIsTurnedOnCalculated = false;
        private bool _urlRewriterIsTurnedOnValue;
        private object _lockObject = new object();
        private bool IsUrlRewriterTurnedOn(HttpContextBase httpContext)
        {
            // Need to do double-check locking because a single instance of this class is shared in the entire app domain (see PathHelpers)
            if (!_urlRewriterIsTurnedOnCalculated)
            {
                lock (_lockObject)
                {
                    if (!_urlRewriterIsTurnedOnCalculated)
                    {
                        HttpWorkerRequest httpWorkerRequest = (HttpWorkerRequest)httpContext.GetService(typeof(HttpWorkerRequest));
                        //bool urlRewriterIsEnabled = (httpWorkerRequest != null && httpWorkerRequest.GetServerVariable(UrlRewriterEnabledServerVar) != null);
                        bool urlRewriterIsEnabled = (httpWorkerRequest != null && httpWorkerRequest.GetServerVariable("IIS_UrlRewriteModule") != null);

                        _urlRewriterIsTurnedOnValue = urlRewriterIsEnabled;
                        _urlRewriterIsTurnedOnCalculated = true;
                    }
                }
            }
            return _urlRewriterIsTurnedOnValue;
        }

Таким образом, если и requestWasRewrite, и IsUrlRewriterTurnedOn возвращают значение true, это означает, что на одном из ваших веб-серверов включен и работает модуль перезаписи IIS, а на другом — нет.

Дополнительные сведения об исходных кодах ASP.NET MVC см. по этой ссылке:

http://aspnetwebstack.codeplex.com/

Надеюсь, поможет!

person Hatjhie    schedule 20.01.2014