2012-08-09 41 views
11

Tôi nhận thấy rằng FormsAuthentication.SetAuthCookie đang ném một NullReferenceException - Tham chiếu đối tượng không được đặt thành thể hiện của đối tượng bên trong một hành động không đồng bộ trên trang web xanh.FormsAuthentication.SetAuthCookie ném NullReferenceException trong hành động không đồng bộ

tôi thấy như sau:

http://connect.microsoft.com/VisualStudio/feedback/details/743350/formsauthentication-setauthcookie-throws-nullreferenceexception-if-called-in-an-async-action-in-mvc4

Tuy nhiên tôi đã có

<appSettings> 
    <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" /> 

bộ và mã của tôi hoạt động tốt tại địa phương tôi chỉ gặp vấn đề khi tôi triển khai đến Azure. Tôi đang sử dụng trang web Azure (https://www.windowsazure.com/en-us/home/scenarios/web-sites/), đó là sự hiểu biết của tôi rằng điều này sử dụng web.config bình thường? Tôi cũng đã cố gắng thêm appsetting qua bảng điều khiển Azure

enter image description here

Và thêm .ConfigureAwait(false); phương pháp chờ đợi của tôi, nhưng đã không có may mắn.

Đoạn mã dưới đây sẽ ném ngoại lệ

public class TestController : Controller 
    { 
     public async Task<ActionResult> Index() 
     { 
      var httpResponse = await new HttpClient().GetAsync("http://www.google.com"); 
      FormsAuthentication.SetAuthCookie("test", true); 
      return View(); 
     } 
    } 

Bất cứ ai cũng biết làm thế nào tôi có thể có được điều này để làm việc?

UPDATE:

Stack Trace:

[NullReferenceException: Object reference not set to an instance of an object.] 
    System.Threading.Tasks.<>c__DisplayClass1c.<GetRethrowWithNoStackLossDelegate>b__1b(Task task) +91 
    System.Threading.Tasks.TaskHelpersExtensions.ThrowIfFaulted(Task task) +15 
    System.Web.Mvc.Async.TaskAsyncActionDescriptor.EndExecute(IAsyncResult asyncResult) +77 
    System.Web.Mvc.Async.<>c__DisplayClass3f.<BeginInvokeAsynchronousActionMethod>b__3e(IAsyncResult asyncResult) +16 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +29 
    System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +59 
    System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +240 
    System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +12 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +31 
    System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +23 
    System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +128 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50 
    System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +26 
    System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14 
    System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +25 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55 
    System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +41 
    System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +25 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55 
    System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +28 
    System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 
    System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__4(IAsyncResult asyncResult) +28 
    System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +25 
    System.Web.Mvc.Async.WrappedAsyncResult`1.End() +55 
    System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +31 
    System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7 
    System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +23 
    System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +59 
    System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 
    System.Web.CallHandlerExecutionStep.OnAsyncHandlerCompletion(IAsyncResult ar) +96 

CẬP NHẬT

tôi thấy nó hoạt động nếu thiết lập Cookie tay

FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(1, "test", DateTime.Now, DateTime.Now.AddMinutes(30), true, null, FormsAuthentication.FormsCookiePath); 
      string encTicket = FormsAuthentication.Encrypt(ticket); 
      Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket)); 

Tôi sẽ không trả lời câu hỏi mặc dù như muốn biết lý do tại sao FormsAuthentication.SetAuthCookie là ném ngoại lệ và tại sao nó hoạt động khác trên Azure Websites

+0

stack trace của ngoại lệ là gì? – svick

+0

Bạn có chắc chắn các trang web hiện đang hỗ trợ ASP.NET 4.5 chưa được phát hành? –

+0

@svick Đã thêm dấu vết ngăn xếp – Tom

Trả lời

15

Vấn đề này là không cụ thể cho Azure - phương pháp FormsAuthentication.SetAuthCookie sẽ ném một ngoại lệ tham khảo null trong một hành động async khi một câu lệnh chờ được gọi trước khi FormsAuthentication.SetAuthCookie được gọi.

Giải pháp đơn giản nhất là sử dụng như sau:

 Response.Cookies.Add(FormsAuthentication.GetAuthCookie("user-1", true)); 

Một thay thế sẽ là để xác định việc tạo ra vé tự hỏi:

 var ticket = new FormsAuthenticationTicket(
      2, 
      "user-1", 
      DateTime.Now, 
      DateTime.Now.AddDays(2), 
      true, 
      String.Empty, 
      "/"); 

     var encTicket = FormsAuthentication.Encrypt(ticket); 

     Response.Cookies.Add(new HttpCookie(".AUTH", encTicket)); 
+0

Bạn có thể cung cấp một số nguồn để giải thích tại sao không đây là trường hợp? Tôi đã gặp vấn đề này nhiều lần, nhưng không thể tìm thấy tài liệu sao lưu. – shortstuffsushi

0

Hiện tại, .NET 4.5 không được hỗ trợ trong Windows Azure Web Sites . Bạn sẽ cần phải hạ cấp dự án của bạn xuống .NET 4.0 cũng sẽ có nghĩa là bạn sẽ cần phải viết lại mã để không sử dụng async.

Bạn có thể cố gắng bin triển khai các hội đồng .NET 4.5 được yêu cầu của ứng dụng của bạn

+0

Ứng dụng đang sử dụng .NET 4 với Gói nhắm mục tiêu Async, tôi nghĩ rằng điểm của Stephen Cleary rằng 'UseTaskFriendlySynchronizationContext' chỉ được hỗ trợ trong .NET 4.5 là lý do nó không thành công và không phải cục bộ – Tom

Các vấn đề liên quan