Как перенаправить на страницу входа из веб-службы в вызове AJAX? - PullRequest
0 голосов
/ 04 марта 2009

Я использую jQuery для вызова методов веб-службы (* .asmx). Веб-служба использует FormsAuthentication, чтобы определить, аутентифицирован ли вызывающий пользователь. Я не могу вернуть код состояния перенаправления из веб-метода, например

[WebMethod(EnableSession=true)]
public Dictionary<string, object> GetArchivedFiles(int pageSize, int page)
{
    if(HttpContext.Current.User.Identity.IsAuthenticated && Session["UserId"] != null)
        // Do some computing and return a Dictionary.       

    // Method will fall through here if the user is not authenticated.
    HttpContext.Current.Response.StatusCode = (int) HttpStatusCode.Unauthorized;
    return null;
}

Перенаправление не работает, я всегда получаю 500 Internal Server Error при этом. Я пробовал разные коды. Каков будет рекомендуемый путь сюда? Мне нужно прочитать информацию о перенаправлении из JavaScript и загрузить новую страницу (или, возможно, отобразить AJAX-способ управления входом в систему).

На самом деле я возвращаю объект JSON, который выглядит так:

{"Message":"Authentication failed.","StackTrace":null,"ExceptionType":"System.InvalidOperationException"
}

Я попытался запустить отладчик, но он не показывает, что введены какие-либо методы. Как вы видите, StackTrace имеет значение null ...

При вызове в Fiddler в качестве стандартного запроса POST (не XMLHttpRequest) фактически возвращается исключение:

HTTP/1.1 500 Internal Server Error
Server: ASP.NET Development Server/9.0.0.0
Date: Wed, 04 Mar 2009 14:46:02 GMT
X-AspNet-Version: 2.0.50727
Cache-Control: private
Content-Type: text/plain; charset=utf-8
Content-Length: 1739
Connection: Close

System.NotSupportedException: The type System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Object, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] is not supported because it implements IDictionary.
   at System.Xml.Serialization.TypeScope.GetDefaultIndexer(Type type, String memberInfo)
   at System.Xml.Serialization.TypeScope.ImportTypeDesc(Type type, MemberInfo memberInfo, Boolean directReference)
   at System.Xml.Serialization.TypeScope.GetTypeDesc(Type type, MemberInfo source, Boolean directReference, Boolean throwOnError)
   at System.Xml.Serialization.ModelScope.GetTypeModel(Type type, Boolean directReference)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
   at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root)
   at System.Web.Services.Protocols.XmlReturn.GetInitializers(LogicalMethodInfo[] methodInfos)
   at System.Web.Services.Protocols.XmlReturnWriter.GetInitializers(LogicalMethodInfo[] methodInfos)
   at System.Web.Services.Protocols.MimeFormatter.GetInitializers(Type type, LogicalMethodInfo[] methodInfos)
   at System.Web.Services.Protocols.HttpServerType..ctor(Type type)
   at System.Web.Services.Protocols.HttpServerProtocol.Initialize()
   at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response)
   at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)

Ответы [ 5 ]

7 голосов
/ 04 марта 2009

Вы не должны перенаправлять из веб-службы. Он должен возвращать значение, чтобы указать, следует ли вам перенаправить (. Это может быть отдельный Authenticate метод, который возвращает string, если он нулевой, это означает, что он аутентифицирован, если нет содержит URL-адрес перенаправления ) Затем в javascript вы можете проверить возвращаемое значение и соответствующим образом перенаправить, установив свойство window.location.

Кстати, доступ к веб-сервису не должен требовать аутентификации.

3 голосов
/ 04 марта 2009

У меня нет опыта работы с asp.net, но в целом мне нравится использовать объект ajaxResponse, который имеет такие свойства, как «success», «content», «errortype» Ответ, требующий входа в систему, в этом случае будет иметь «false» и ошибочный «login», или что вы выберете. Затем код javascript решает, как обрабатывать возвращенный объект, основываясь на этих свойствах, показывая пользователю форму входа или перенаправляя на новую страницу.

1 голос
/ 06 марта 2009

Я вообще избавился от кода статуса и просто вернул null. Метод возвращает пустой список, если файлов нет, общее количество страниц равно 0. Но если пользователь не аутентифицирован, он возвращает null, в этом случае я использую window.location, чтобы перенаправить браузер на страницу входа .

0 голосов
/ 18 сентября 2009

Фактически, если ваше сообщение для веб-сервисов (ajax или нет) содержит заголовок «Content-Type» со значением «application / json; charset = utf-8», то стек ASMX отправит вам обратно форматированный json строка за исключением предполагаемого перенаправления, которое обычно ожидается, включая код состояния 401 (неавторизованный), но, если вы не отправляете заголовок какого-либо типа содержимого, вы получите перенаправление браузера на страницу входа в качестве ответа с кодом состояния OK и используя ajax, вы получите html-страницу входа в качестве ответа.

Надеюсь, что это поможет уточнить.

Привет

0 голосов
/ 04 марта 2009

Бросить исключение в веб-сервис. Поймай это в вызывающем и перенаправь при необходимости.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...