Pergunta

Eu estou usando jQuery para chamar (* .asmx) métodos de serviço web. A web usos de serviços FormsAuthentication para determinar se o usuário é autenticado chamando. Eu sou incapaz de retornar um código de status de redirecionamento do método web, por exemplo.

[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;
}

O redirecionamento não trabalho, eu sempre chegar 500 Internal Server Error ao fazer isto. Tentei códigos diferentes. Qual seria a maneira recomendada para ir para lá? Eu preciso ler as informações redirecionamento de JavaScript e carregar a nova página (ou talvez exibir uma forma AJAX controle de login).

Eu realmente obter um objeto JSON para trás, que tem esta aparência:

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

Eu tentei executar o depurador, mas não mostra que os métodos são inseridos. Como você pode ver o StackTrace é nulo ...

Quando invocado em Fiddler como um pedido POST padrão (não XMLHttpRequest) ele retorna uma exceção na verdade:

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)
Foi útil?

Solução 3

O que fiz foi para se livrar do código de status em tudo e só retornar null. Um método retorna uma lista vazia se não houver arquivos, com uma contagem de página total de 0. Mas se o usuário não é autenticado, ele retorna null, em tal window.location caso eu uso para redirecionar o navegador para a página de login.

Outras dicas

Você não deve redirecionar a partir do serviço Web. Ele deve retornar um valor para indicar se você deve ou não redirecionar ( Este poderia ser um método Authenticate separado que retorna um string, se é nulo, isso significa que é autenticado, se não for ele vai conter o URL de redirecionamento ) Então, em javascript, você pode verificar o valor de retorno e redirecionar adequadamente, definindo a propriedade window.location.

A propósito, o acesso ao serviço Web não deve exigir autenticação.

Eu não tenho experiência especificamente com o asp.net, mas em I geral como usar um objeto ajaxResponse que tem propriedades como "sucesso", "content", "errortype". Um login resposta necessária neste caso teria um sucesso de "falsa" e errortype "login", ou o que você escolher. O código javascript então decide como lidar com o objeto retornado com base nessas propriedades, mostrando ao usuário um formulário de login ou redirecionando para uma nova página.

lançar uma exceção no webservice. Trave este no chamador e redirecionamento conforme necessário.

Na verdade, se o seu post para os webservices (Ajax ou não) contém um cabeçalho "Content-Type" com valor "application / json; charset = utf-8", em seguida, a pilha ASMX vai mandar de volta um json formatado string com uma exceção do redirecionamento supor que normalmente você esperaria, incluindo código de status 401 (não autorizado), mas, se você não enviar qualquer cabeçalho de tipo de conteúdo, você também obter um redirecionamento do navegador para a página de login como resposta com código de status OK e usando ajax, você vai obter o html página de login como resposta.

Espero que esta ajuda na clarificação.

Saudações

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top