2016-03-29 6 views
1

Ich habe eine API-Anwendung, die perfekt auf Visual Studio 2015 Debugger funktioniert; Ich versuche, meine Anwendung auf IIS zu veröffentlichen (Ich habe den Server über Systemsteuerung installiert Windows-Funktionen ein-/ausschalten).API App mit NInject funktioniert nicht auf IIS, es funktioniert nur auf Debugger Visual Studio

Meine Anwendung ein Sicherheitssystem muss zu überprüfen, dass jede Anforderung von einem Benutzer registriert ist, jede Anfrage ApiAuthorizationFilter ersten Wurf passiert, lösen Sie das Token, das durch Base64-String zusammengesetzt ist, kommt es im Header als Authorization und gibt die spezifische HttpStatusCode mit JSON.

Die Ausnahme tritt nach Bereitstellung, wenn ich einen Test für die Anwendung ausführen, die IIS wirft NullReferenceException um Filter.ApiAuthorizationFilter, aber wenn ich die gleiche Anwendung auf Visual Studio ausführen - es funktioniert.

Dies ist die Fehlermeldung:

500: Interner Serverfehler "Message": "Ein Fehler ist aufgetreten" "ExceptionMessage": "Objektverweis nicht auf eine Instanz eines Objekts festgelegt." "Exception": "System.NullReferenceException" "Stacktrace": "in API.CARDS.Models.Filter.ApiAuthorizationFilter.OnAuthorization (HttpActionContext Action) bei System.Web.Http.Filters.AuthorizationFilterAttribute.OnAuthorizationAsync (HttpActionContext Action, CancellationToken CancellationToken) --- Ende des Stack-Trace vom vorherigen Speicherort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task-Task) unter System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task-Task) unter System.Web .Http.Filters.AuthorizationFilterAttribute.d__2.MoveNext() --- Ende des Stack-Trace vom vorherigen Speicherort, an dem die Ausnahme ausgelöst wurde --- bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (Task-Task) unter System.Runtime.CompilerServices. TaskAwaiter.HandleNonSuccessAndDebuggerNotification (Task-Task) unter System.Web.Http.Dispatcher.HttpControllerDispa tcher.d__1.MoveNext()“

Hier ist der Code:

ApiAuthorizationFilter

public class ApiAuthorizationFilter : AuthorizationFilterAttribute 
{ 
    [Inject] 
    public IEncryptionSystemService service { get; set; } 

    [Inject] 
    public IUserService userService { get; set; } 

    public override void OnAuthorization(HttpActionContext actionContext) 
    { 
     //Hace una petición (request) al actionContext 
     HttpRequestMessage request = actionContext.Request; 
     try 
     { 
      //Establece la cultura (Ejemplo: es-MX) para los mensajes i18n 
      string culture = actionContext.Request.Headers.AcceptLanguage.ToString(); 
      if (culture.Length == 5) 
      { 
       Thread.CurrentThread.CurrentCulture = new CultureInfo(culture); 
       Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture); 
      } 
      //Crea un token con los valores que se obtienen del actionContext, mismos que serán las credenciales para accesar. 
      string token = actionContext.Request.Headers.GetValues("Authorization").FirstOrDefault().Replace("Credentials", "").Trim(); 
      //Desencripta las credenciales con el servicio del tipo IEncryptionService. 
      string[] userPass = service.DecryptText(token); 
      User model = new User { email = userPass[0], password = userPass[1] }; 
      ////Verifica que sean correctas las credenciales que ser obtuvieron del token. 
      AuthorizationResult result = userService.LoginUser(model); 
      switch (result) 
      { 
       case AuthorizationResult.ACCESS_GRANTED: 
        User user = new User { email = model.email }; 
        ApiIdentity identity = new ApiIdentity(user); 
        ApiPrincipal principal = new ApiPrincipal(identity); 
        Thread.CurrentPrincipal = principal; 
        break; 
       case AuthorizationResult.ACCESS_DENIED: 
        actionContext.Response = request.CreateResponse(HttpStatusCode.NotFound, "ErrorResources.NotFound"); 
        break; 
       case AuthorizationResult.PERMISSION_DENIED: 
        actionContext.Response = request.CreateResponse(HttpStatusCode.Unauthorized, "ErrorResources.Unauthorized"); 
        break; 
      } 
     } 
     catch (Exception e) 
     { 
      throw; 
      //Si existe un error durante la petición, regresa un estatus de InternalServerError (Error interno del Servidor). 
      //actionContext.Response = request.CreateErrorResponse(HttpStatusCode.InternalServerError, string.Format("ErrorResources.AuthenticationError ---- {0}",e.Message)); 

     } 
    } 
} 

Image response from the debugger

Image response from IIS

+0

Veröffentlichen Sie die PDBs, so dass Sie zumindest die Zeilennummer sehen können. Ich vermute, dass deine DI nicht funktioniert. – leppie

+0

Wo kann ich die PDBs finden, wenn mein Visual Studio die Standardkonfiguration hat? und meinst du die Dependency Injection? Ich habe das gleiche Gefühl über das NInject, aber ich weiß nicht, warum es nur auf Debug funktioniert –

Antwort

2

ich die Antwort nach einer großen gefunden Forschung !, Diese Antwort r ist für API-Anwendung mit NInject, Leppie hatte Recht das Problem war um Dependency Injection Configuration.

Zuerst musste ich meine Pakete von NuGet, installiert reinigen musste ich Ninject mit diesen Paketen neu zu installieren.

  • Ninject
  • Ninject.web.WebApi
  • Ninject.web.WebApi.WebHost - ich dieses fehlte, ist diese
  • Ninject für IIS-Unterstützung erforderlich.MVC3
  • Ninject.web.Common
  • Ninject.web.Common.WebHost - Aktualisieren Sie diese eine letzte Version (3.2.3), dies für IIS Unterstützung erforderlich ist

Nach dieser Kontrolle Ihre Klasse NInjectWebCommon.cs, die in dem Verfahren CreateKernel() genannt hatte ich diese Linie

GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); 

Sie müssen es entfernen, weil thi s wird werfen

Fehler Aktivieren ModelValidatorProvider von ModelValidatorProvider zu NinjectDefaultModelValidatorProvider mit Bindung

Wenn alles in Ordnung ist! Ihre Anwendung wird unter IIS Server ausgeführt.

diese Dateien sind meine letzte Konfiguration ninject im App_Start Ordner

NinjectWebCommon.cs

public static class NinjectWebCommon 
{ 
    private static readonly Bootstrapper bootstrapper = new Bootstrapper(); 

    /// <summary> 
    /// Starts the application 
    /// </summary> 
    public static void Start() 
    { 
     DynamicModuleUtility.RegisterModule(typeof(OnePerRequestHttpModule)); 
     DynamicModuleUtility.RegisterModule(typeof(NinjectHttpModule)); 
     bootstrapper.Initialize(CreateKernel); 
    } 

    /// <summary> 
    /// Stops the application. 
    /// </summary> 
    public static void Stop() 
    { 
     bootstrapper.ShutDown(); 
    } 

    /// <summary> 
    /// Creates the kernel that will manage your application. 
    /// </summary> 
    /// <returns>The created kernel.</returns> 
    private static IKernel CreateKernel() 
    { 
     var kernel = new StandardKernel(); 
     try 
     { 
      kernel.Bind<Func<IKernel>>().ToMethod(ctx =>() => new Bootstrapper().Kernel); 
      kernel.Bind<IHttpModule>().To<HttpApplicationInitializationHttpModule>(); 

      RegisterServices(kernel); 

      // GlobalConfiguration.Configuration.DependencyResolver = new NinjectDependencyResolver(kernel); 
      return kernel; 
     } 
     catch 
     { 
      kernel.Dispose(); 
      throw; 
     } 
    } 

    /// <summary> 
    /// Load your modules or register your services here! 
    /// </summary> 
    /// <param name="kernel">The kernel.</param> 
    private static void RegisterServices(IKernel kernel) 
    { 
     // kernel.BindFilter<ApiAuthorizationFilter>(FilterScope.Controller, 0).WhenControllerHas<ApiAuthorizationFilter>(); 

     NInjectHelper.SetupKernel(kernel); 
     kernel.Bind<IEncryptionSystemService>().To<EncryptionSystemService>(); 
     kernel.Bind<IUserService>().To<UserService>(); 
     kernel.Bind<IRoleService>().To<RoleService>(); 
     kernel.Bind<IStatusService>().To<StatusService>(); 
     kernel.Bind<ICardService>().To<CardService>(); 
     kernel.Bind<ICardTypeService>().To<CardTypeService>(); 


    } 

} 

NinjectResolver.cs

public class NinjectResolver : NinjectScope, IDependencyResolver 
{ 
    private IKernel _kernel; 

    public NinjectResolver(IKernel kernel) 
     : base(kernel) 
    { 
     _kernel = kernel; 
    } 

    public IDependencyScope BeginScope() 
    { 
     return new NinjectScope(_kernel.BeginBlock()); 
    } 
} 

NinjectScope.cs

public class NinjectScope : IDependencyScope 
{ 
    protected IResolutionRoot resolutionRoot; 

    public NinjectScope(IResolutionRoot kernel) 
    { 
     resolutionRoot = kernel; 
    } 

    public object GetService(Type serviceType) 
    { 
     IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true); 
     return resolutionRoot.Resolve(request).SingleOrDefault(); 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
     IRequest request = resolutionRoot.CreateRequest(serviceType, null, new Parameter[0], true, true); 
     return resolutionRoot.Resolve(request).ToList(); 
    } 

    public void Dispose() 
    { 
     IDisposable disposable = (IDisposable)resolutionRoot; 
     if (disposable != null) disposable.Dispose(); 
     resolutionRoot = null; 
    } 
} 

WICHTIG! Für SQL Server-Benutzer Wie können Sie auf meiner ApiFilterConfiguration sehen Ich habe diese Linie AuthorizationResult result = userService.LoginUser(model); diese Userservice ist eine Klasse, die ich mit der Methode Loginuser (Modell) erstellt haben diese Methode wird ein Modell aus der anfordern Headers und geht zu SQL SERVER zu überprüfen, ob der Benutzer existiert.

Wenn Sie SQL Server mit Standardkonfiguration wie mir installiert, vielleicht haben Sie ein anderes Problem haben, die Null Referenz nach einem wirft konsultieren, lesen Sie in diesem Thema Login failed for user IIS APPPOOL\AppPool4.5 or APPPOOL\ASP.NET vielleicht müssen Sie für IIS ein Login erstellen auf Ihrem SQLSERVER

Verwandte Themen