Asp.net-Mvc-3

FormsAuthentication.SetAuthCookie 在非同步操作中拋出 NullReferenceException

  • February 9, 2019

我發現這FormsAuthentication.SetAuthCookie是拋出 NullReferenceException - 對象引用未設置為天藍色網站上的非同步操作內的對象實例。

我發現了以下內容:

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

不過我已經有了

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

設置並且我的程式碼在本地執行良好我只在部署到天藍色時遇到問題。我正在使用 Azure 網站(https://www.windowsazure.com/en-us/home/scenarios/web-sites/),我的理解是這通常使用 web.config?我也嘗試通過 Azure 控制面板添加 appsetting

在此處輸入圖像描述

並添加.ConfigureAwait(false);到我期待的方法中,但沒有運氣。

下面的程式碼會拋出異常

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();
       }
   }

有誰知道我怎樣才能讓它工作?

更新:

堆棧跟踪:

[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

更新

如果手動設置 Cookie,我發現它有效

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));

我不打算回答這個問題,因為我想知道為什麼FormsAuthentication.SetAuthCookie拋出異常以及為什麼它在 Azure 網站上的行為不同

此問題並非特定於 Azure - 在呼叫 FormsAuthentication.SetAuthCookie 之前呼叫 await 語句時,FormsAuthentication.SetAuthCookie 方法將在非同步操作中引發空引用異常。

最簡單的解決方案是使用以下內容:

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

另一種方法是自己指定票證創建:

       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));

引用自:https://stackoverflow.com/questions/11882762