2012-08-09 16 views
11

Estoy descubriendo que FormsAuthentication.SetAuthCookie está lanzando una NullReferenceException - Referencia de objeto no establecida en una instancia de un objeto dentro de una acción asíncrona en un sitio web azure.FormsAuthentication.SetAuthCookie throwing NullReferenceException en acción asíncrona

me encontré con lo siguiente:

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

Sin embargo ya tienen

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

conjunto y mi código funciona bien a nivel local sólo experimentar el problema cuando despliego a Azure. Estoy usando Azure Websites (https://www.windowsazure.com/en-us/home/scenarios/web-sites/), entendí que esto usa web.config normalmente? También he intentado añadir el appSetting a través del panel de control Azure

enter image description here

Y añadiendo .ConfigureAwait(false); a mi método esperado, pero no han tenido suerte.

El siguiente código emitir la excepción

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

Alguien sabe cómo puedo conseguir que esto funcione?

ACTUALIZACIÓN:

Seguimiento de la pila:

[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 

ACTUALIZACIÓN

he encontrado que funciona si el establecimiento de la cookie manualmente

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

No voy a responder la pregunta, ya que me gustaría saber por qué FormsAuthentication.SetAuthCookie arroja la excepción y por qué se comporta de manera diferente en Azure Websites

+0

¿Cuál es el seguimiento de pila de la excepción? – svick

+0

¿Estás seguro de que los sitios web actualmente admiten ASP.NET 4.5 inédito? –

+0

@svick Se ha agregado el seguimiento de la pila – Tom

Respuesta

15

Este problema no es específico de Azure - FormsAuthentication.SetAuthCookie el método va a lanzar una excepción de referencia nula en una acción asíncrona cuando una La instrucción await se invoca antes de llamar a FormsAuthentication.SetAuthCookie.

La solución más fácil es utilizar el siguiente:

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

Una alternativa sería especificar la creación de tickets a sí mismo:

 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

¿Podría proporcionar alguna fuente de por qué? ¿este es el caso? He encontrado este problema varias veces, pero no he podido encontrar la documentación de respaldo. – shortstuffsushi

0

En este momento, .NET 4.5 no es compatible con los sitios web de Windows Azure . Tendrá que degradar su proyecto a .NET 4.0, lo que también significará que tendrá que volver a escribir el código para no utilizar asincrónico.

Se podría tratar de bin implementar los ensamblados de .NET 4.5 que son requeridos por su aplicación

+0

La aplicación usa .NET 4 con el Paquete de orientación asíncrono, creo que el argumento de Stephen Cleary de que 'UseTaskFriendlySynchronizationContext' solo es compatible con .NET 4.5 fue la razón por la que falló en azul y no localmente – Tom

Cuestiones relacionadas