FormsAuthentication.SetAuthCookie抛出NullReferenceException异常在异步操作

问题描述 投票:14回答:3

我发现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本地我只遇到问题。我使用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

UPDATE

我发现它的工作原理,如果手动设置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上的网站

asp.net-mvc-3 asp.net-mvc-4 asp.net-4.0 async-await
3个回答
20
投票

这个问题不是特定于Azure的 - 方法FormsAuthentication.SetAuthCookie将抛出一个空引用异常在异步操作时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));

1
投票

你也可以改变这种方式,它给你

public ActionResult Index()
{
    var t1 = Task.Run(() => HttpClient().GetAsync("http://www.google.com"));
    t1.Wait();
    FormsAuthentication.SetAuthCookie("test", true);
    return View();
}

这样的工作,我和我的想法得到了从GlennMorton 1回答

谢谢。


0
投票

在目前,.NET 4.5在Windows Azure网站支持。您将需要降级的项目.NET 4.0这也将意味着你将需要重写代码,不使用异步。

你可以尝试仓部署由应用程序所需的.NET 4.5组件

© www.soinside.com 2019 - 2024. All rights reserved.