Pregunta

Estoy usando jQuery para llamar a los métodos del servicio web (* .asmx). El servicio web utiliza FormsAuthentication para determinar si el usuario que llama está autenticado. No puedo devolver un código de estado de redireccionamiento desde el método web, por ejemplo,

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

La redirección no funciona, siempre obtengo 500 errores internos del servidor cuando hago esto. Probé diferentes códigos. ¿Cuál sería la manera recomendada de ir aquí? Necesito leer la información de redireccionamiento desde JavaScript y cargar la nueva página (o tal vez mostrar una forma AJAX de control de inicio de sesión).

Realmente me devuelvo un objeto JSON, que se parece a esto:

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

Intenté ejecutar el depurador, pero no muestra que se haya ingresado ningún método. Como puedes ver, el StackTrace es nulo ...

Cuando se invoca en Fiddler como una solicitud POST estándar (no XMLHttpRequest), en realidad devuelve una excepción:

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

Solución 3

Lo que hice fue deshacerme del código de estado y devolver null . Un método devuelve una lista vacía si no hay archivos, con un recuento total de páginas de 0. Pero si el usuario no está autenticado, devuelve null , en ese caso yo uso window.location para redirigir el navegador a la página de inicio de sesión.

Otros consejos

No debes redireccionar desde el servicio web. Debe devolver un valor para indicar si debe o no redirigir ( Este podría ser un método Authenticate separado que devuelve una cadena , si es nulo, significa que es autenticado, si no lo está, contendrá la URL de redireccionamiento ) Luego, en javascript, puede verificar el valor de retorno y redirigir adecuadamente configurando la propiedad window.location .

Por cierto, el acceso al servicio web no debe requerir autenticación.

No tengo experiencia específica con asp.net pero en general me gusta usar un objeto ajaxResponse que tiene propiedades como "éxito", "contenido", "errortype". Una respuesta requerida de inicio de sesión en este caso tendría un éxito de " false " y errortype " inicio de sesión " ;, o lo que elija. El código javascript luego decide cómo manejar el objeto devuelto según estas propiedades, mostrando al usuario un formulario de inicio de sesión o redirigiéndolo a una nueva página.

Lanzar una excepción en el servicio web. Capture esto en la persona que llama y redirija según sea necesario.

De hecho, si su publicación en los servicios web (ajax o no) contiene un " Tipo de contenido " encabezado con valor " application / json; charset = utf-8 " ;, luego la pila ASMX te enviará de vuelta una cadena con formato json con una excepción del supuesto redireccionamiento que normalmente esperas, incluido el código de estado 401 (no autorizado), pero si no envías ningún encabezado de tipo de contenido , bien, obtendrá una redirección del navegador a la página de inicio de sesión como respuesta con el código de estado OK y utilizando ajax, obtendrá la página de inicio de sesión html como respuesta.

Espero que esto ayude a aclarar.

Saludos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top