2016-04-01 2 views
0

Я попытался реализации пользовательских IImageService как в Umbraco и в приложении ваниль MVC следуя советам здесь:ImageProcessor.Web пользовательских IImageService вызывает NullReferenceException

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

Но я думаю, что я мог быть пропущен шаг как я только получаю эту ошибку:

[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 

DatabaseImageService ниже вызывается на свойстве Prefix и IsFileLocalSevice, но затем я получаю ошибку выше. IsValidRequest() и GetImage() никогда не вызываются.

код является копией LocalFileImageService.cs

Я также попытался указать это ImageService в файле security.config, который поставляется с ImageProcessor.Web.Config но возникает та же ошибка.

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

Обновление 1

пример кода выше в ванили MVC App. Конфигурация выглядит следующим образом:

<?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> 

Чтобы быть ясно, что я сделал следующие шаги, чтобы добраться до этой точки:

  • Vanilla MVC App
  • Установлено: ImageProcessor ImageProcessor.Web и ImageProcessor.Web .config с помощью NuGet
  • создали класс DatabaseImageService выше
  • редактировали security.config, как показано

У меня есть изображение в корне сайта "hami-1.jpg". Я могу корректно манипулировать им по умолчанию LocalFileImageService http: // localhost: 11832/hami-1.jpg? Width = 200.

Префикс, который я указал для моего собственного ImageService, это «database.axd», поэтому URL-адрес должен быть:?

  • HTTP: // локальный: 11832/database.axd/Хами-1.jpg ширина = 200
  • HTTP: // локальный:? 11832/database.axd Хами-1.jpg ширина = 200

? На данный момент я не уверен, потому что видел примеры того и другого. ?

В любом случае, когда я отлаживаю, я не ударил точки останова в методах IsValidRequest или GetImage. Я попал в точку останова в IsFileLocalService.

Это действительно базовая установка, поэтому я уверен, что это то, что мне не хватает.

В конце концов, я хочу, чтобы заменить метод GetImage с моим собственным, что будет извлекать изображения из базы данных, используя что-то вроде:

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

Отправьте код, в котором вы инициализируете и вызываете этот класс. – CathalMF

+0

@CathalMF Класс инициализируется и вызывается из ImageProcessor. См. Строки 330 и 381 из [ImageProcessorConfiguration.cs] (https://github.com/JimBobSquarePants/ImageProcessor/blob/master/src/ImageProcessor.Web/Configuration/ImageProcessorConfiguration.cs) Он вызывается в методе on line 722 в [ImageProcessingModule.cs] (https://github.com/JimBobSquarePants/ImageProcessor/blob/master/src/ImageProcessor.Web/HttpModules/ImageProcessingModule.cs) –

+0

Является ли это образцом полного кода в текущем состоянии? Похоже, вы все еще пытаетесь загрузить файл из локальной файловой системы. Можете ли вы разместить как свою конфигурацию, так и пример запроса URL? –

ответ

1

Ошибка вызвана вас не инициализируя имущество Settings в вашем сервисе, поэтому, когда мы проверяем наличие определенного имущества

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

Исключение выбрано.

Кроме того, вы неверно устанавливаете для свойства IsFileLocalService значение true.

В HttpModule есть проверка на это свойство.

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

Это свойство означает, что файл содержится в локальной файловой системе. Если вы установите значение true, если файл не будет представлен таким образом, вы получите исключение.

+1

Большое спасибо. Извинения за то, что они не отмечали это раньше, как были в отъезде. Я внедрил и подтвердил, что решает и мою проблему. –

0

я получал один и тот же вопрос, используя последние NuGet пакетов.Я исправил это пока, понизив пакеты NuGet, которые я использую, к следующему.

ImageProcessor - v2.2.5

ImageProcessor.Web - v4.3.2

ImageProcess.Web.Config - v1.0.0