2016-04-01 9 views
0

Ich habe versucht, im Anschluss an die Beratung eine benutzerdefinierte IImageService sowohl in Umbraco und in einer Vanille-MVC-app Umsetzung hier:ImageProcessor.Web benutzerdefinierte IImageService verursacht Nullreferenceexception

https://github.com/JimBobSquarePants/ImageProcessor/issues/105

Aber ich glaube, ich könnte ein Schritt fehlt da ich nur diese Fehlermeldung erhalten:

[NullReferenceException: Object reference not set to an instance of an object.] 
    ImageProcessor.Web.HttpModules.<ProcessImageAsync>d__b.MoveNext() +755 
    System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +92 
    System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +58 
    System.Web.TaskAsyncHelper.EndTask(IAsyncResult ar) +71 
    System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +380 
    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155 

die DatabaseImageService unten auf dem Präfix Eigenschaft und IsFileLocalSevice aufgerufen wird, aber dann bekomme ich den obigen Fehler. IsValidRequest() und GetImage() werden nie aufgerufen.

Der Code ist eine Kopie von LocalFileImageService.cs

Ich habe auch versucht, diesen Imageservice in der Datei Security.config angeben, die mit ImageProcessor.Web.Config kommt aber der gleiche Fehler auftritt.

namespace ImageProcessorTest 
{ 
    public class DatabaseImageService : IImageService 
    { 
     private string prefix = "database.axd"; 

     public string Prefix 
     { 
      get 
      { 
       return this.prefix; 
      } 

      set 
      { 
       this.prefix = value; 
      } 
     } 

     public bool IsFileLocalService 
     { 
      get 
      { 
       return true; 
      } 
     } 

     public Dictionary<string, string> Settings { get; set; } 

     public Uri[] WhiteList { get; set; } 

     public bool IsValidRequest(string path) 
     { 
      return ImageHelpers.IsValidImageExtension(path); 
     } 

     public async Task<byte[]> GetImage(object id) 
     { 
      string path = id.ToString(); 
      byte[] buffer; 

      FileInfo fileInfo = new FileInfo(path); 

      if (!fileInfo.Exists) 
      { 
       throw new HttpException((int)HttpStatusCode.NotFound, "No image exists at " + path); 
      } 

      using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true)) 
      { 
       buffer = new byte[file.Length]; 
       await file.ReadAsync(buffer, 0, (int)file.Length); 
      } 

      return buffer; 
     } 
    } 
} 

aktualisieren 1

Das Codebeispiel ist oben in einer Vanille MVC App. Die Konfiguration ist wie folgt:

<?xml version="1.0" encoding="utf-8"?> 
<security> 
    <services> 
    <service name="LocalFileImageService" type="ImageProcessor.Web.Services.LocalFileImageService, ImageProcessor.Web" /> 
    <!--Disable the LocalFileImageService and enable this one when using virtual paths. --> 
    <!--<service name="CloudImageService" type="ImageProcessor.Web.Services.CloudImageService, ImageProcessor.Web"> 
     <settings> 
     <setting key="Container" value=""/> 
     <setting key="MaxBytes" value="8194304"/> 
     <setting key="Timeout" value="30000"/> 
     <setting key="Host" value="http://yourhost.com/"/> 
     </settings> 
    </service>--> 
    <service prefix="remote.axd" name="RemoteImageService" type="ImageProcessor.Web.Services.RemoteImageService, ImageProcessor.Web"> 
     <settings> 
     <setting key="MaxBytes" value="4194304" /> 
     <setting key="Timeout" value="3000" /> 
     <setting key="Protocol" value="http" /> 
     </settings> 
     <whitelist> 
     </whitelist> 
    </service> 
    **<service prefix="database.axd" name="DatabaseImageService" type="ImageProcessorTest.DatabaseImageService, ImageProcessorTest" />** 
    </services> 
</security> 

klar zu sein, habe ich die folgenden Schritte getan zu diesem Punkt zu kommen:

  • Vanilla MVC App
  • installiert: ImageProcessor ImageProcessor.Web und ImageProcessor.Web .Config über NuGet
  • die DatabaseImageService Klasse erstellt oben
  • den Security.config Herausgegeben als
  • gezeigt

Ich habe ein Bild in der Wurzel der Website "hami-1.jpg". Ich kann es richtig mit dem Standard LocalFileImageService http: // localhost: 11832/hami-1.jpg? Width = 200 manipulieren.

Das Präfix, das ich für meinen benutzerdefinierten IImageService angegeben habe, lautet "database.axd", also sollte die URL entweder:?

  • http: // localhost: 11832/database.axd/hami-1.jpg width = 200
  • http: // localhost:? 11832/database.axd hami-1.jpg width = 200

? Ich bin mir zu diesem Zeitpunkt nicht sicher, weil ich Beispiele für beides gesehen habe. ?

In jedem Fall, wenn ich Debugging bin ich nicht in den IsValidRequest oder GetImage Methoden keine Haltepunkte treffen. Ich habe einen Breakpoint in IsFileLocalService getroffen.

Es ist ein wirklich einfaches Setup, also bin ich sicher, dass ich etwas vermisse.

Schließlich möchte ich die GetImage Methode mit meinem eigenen ersetzen, die Bilder aus einer Datenbank mit so etwas wie abruft:

private AppContext _db = new AppContext(); 

private MembershipService MembershipService 
{ 
    get 
    { 
     if (ms == null) 
     { 
      ms = new MembershipService(_db, UmbracoContext.Current); 
     } 
     return ms; 
    } 
} 

public async Task<byte[]> GetImage(object id = null) 
{ 
    var image = await _db.Images.FindAsync(id); 
    var currentMember = MembershipService.GetCurrentMember(); 
    if (image != null) 
    { 
     var content = image.Content; 
     _db.Dispose(); 
     switch (image.Privacy) 
     { 
      case Models.Base.Privacy.Private: 
       if (image.Owner.Id == currentMember.Id ||MembershipService.FindMembersInRole(currentMember.UmbracoMember.Username, "Judges").Any()) 
        return content; 
       break; 
      case Models.Base.Privacy.Unlisted: 
       return content; 
      case Models.Base.Privacy.Public: 
       return content; 
     } 
    } 
    throw new HttpException(404, "Image not found for id: " + id); 
} 
+0

Geben Sie den Code ein, in dem Sie diese Klasse initialisieren und aufrufen. – CathalMF

+0

@CathalMF Die Klasse wird in ImageProcessor initialisiert und aufgerufen. Siehe Zeile 330 und 381 von [ImageProcessorConfiguration.cs] (https://github.com/JimBobSquarePants/ImageProcessor/blob/master/src/ImageProcessor.Web/Configuration/ImageProcessorConfiguration.cs) Es wird in der Methode online aufgerufen 722 in [ImageProcessingModule.cs] (https://github.com/JimBobSquarePants/ImageProcessor/blob/master/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs) –

+0

Ist dies das vollständige Codebeispiel im aktuellen Zustand? Es scheint mir, dass Sie immer noch versuchen, eine Datei aus dem lokalen Dateisystem zu laden. Können Sie sowohl Ihre Konfiguration als auch eine Beispiel-URL-Anfrage aufgeben? –

Antwort

1

Der Fehler verursacht wird, nicht Initialisierung der Settings Eigenschaft in Ihrem Service so, wenn wir auf das Vorhandensein einer bestimmten Eigenschaft überprüfen

string protocol = currentService.Settings.ContainsKey("Protocol") 

Die Ausnahme wird ausgelöst.

Zusätzlich setzen Sie die Eigenschaft IsFileLocalService falsch auf true.

Im HttpModule gibt es eine Überprüfung gegen diese Eigenschaft.

requestPath = currentService.IsFileLocalService 
          ? HostingEnvironment.MapPath(request.Path) 
          : request.Path; 

Diese Eigenschaft bedeutet, dass die Datei im lokalen Dateisystem enthalten ist. Wenn Sie es auf True setzen, ohne dass die Datei auf diese Weise vorhanden ist, erhalten Sie eine Ausnahme.

+1

Vielen Dank. Entschuldigung dafür, dass wir das nicht früher markiert haben. Ich habe implementiert und bestätigt, dass es auch mein Problem löst. –

0

Ich war immer das gleiche Problem die neuesten NuGet Pakete verwenden.Ich habe das jetzt behoben, indem ich die NuGet-Pakete, die ich verwende, auf die folgende Stufe herabsetze.

ImageProcessor - v2.2.5

ImageProcessor.Web - v4.3.2

ImageProcess.Web.Config - von Ihnen v1.0.0

Verwandte Themen