如何在AJAX调用中从Web服务重定向到登录页面?

时间:2009-03-04 14:05:11

标签: asp.net ajax web-services authentication redirect

我使用jQuery来调用Web服务(* .asmx)方法。 Web服务使用FormsAuthentication来确定是否对调用用户进行了身份验证。我无法从Web方法返回重定向状态代码,例如

[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内部服务器错误。我尝试了不同的代码。什么是推荐的方式去这里?我需要从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 个答案:

答案 0 :(得分:7)

您不应该从Web服务重定向。它应该返回一个值来指示是否应该重定向(这可能是一个返回Authenticate的单独string方法,如果它为空,则表示它已经过身份验证,如果它不是'它将包含重定向网址)然后在javascript中,您可以通过设置window.location属性来检查返回值并进行相应的重定向。

顺便说一句,访问Web服务不应该要求身份验证。

答案 1 :(得分:3)

我没有专门针对asp.net的经验,但总的来说我喜欢使用具有“成功”,“内容”,“错误类型”等属性的ajaxResponse对象。在这种情况下,需要登录的响应将成功“假”和错误“登录”,或者您选择的任何内容。然后,javascript代码根据这些属性决定如何处理返回的对象,向用户显示登录表单或重定向到新页面。

答案 2 :(得分:1)

我所做的就是完全摆脱状态代码,然后返回null。如果没有文件,则方法返回空列表,总页数为0.但如果用户未经过身份验证,则返回null,在这种情况下,我使用window.location重定向浏览器到登录页面。

答案 3 :(得分:0)

在网络服务中抛出异常。在调用者中捕获并根据需要重定向。

答案 4 :(得分:0)

实际上,如果您发布到webservices(ajax或不是)的帖子包含值为“application / json; charset = utf-8”的“Content-Type”标头,则ASMX堆栈将向您发送一个json格式化字符串,通常你期望的重定向,包括状态代码401(未授权),但是,如果你不发送任何内容类型标题,你很可能将浏览器重定向到登录页面作为响应状态代码OK和使用ajax,您将获得登录页面html作为响应。

希望这有助于澄清。

此致