14

FormsAuthentication.SetAuthCookieNullReferenceException - オブジェクト参照が Azure Web サイトの非同期アクション内のオブジェクトのインスタンスに設定されていないことをスローしていることがわかります。

私は以下を見つけました:

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 にデプロイするときにのみ問題が発生します。私は Azure Web サイト ( 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 Web サイトでの動作が異なる理由を知りたいので、質問には答えません。

4

3 に答える 3

22

この問題は Azure に固有のものではありません。FormsAuthentication.SetAuthCookie が呼び出される前に await ステートメントが呼び出されると、非同期アクションでメソッド FormsAuthentication.SetAuthCookie が null 参照例外をスローします。

最も簡単な解決策は、次を使用することです。

        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));
于 2013-03-16T09:36:44.140 に答える
0

現在、.NET 4.5 は Windows Azure Web サイトではサポートされていません。プロジェクトを .NET 4.0 にダウングレードする必要があります。これは、非同期を使用しないようにコードを書き直す必要があることも意味します。

アプリケーションに必要な .NET 4.5 アセンブリのビン展開を試みることができます

于 2012-08-12T19:33:33.717 に答える