C# Web自定义IImageService导致NullReferenceException

C# Web自定义IImageService导致NullReferenceException,c#,imageprocessor,C#,Imageprocessor,我已经尝试在Umbraco和vanilla MVC应用程序中实现自定义IImageService,建议如下: 但我想我可能错过了一步,因为我只得到了这个错误: [NullReferenceException: Object reference not set to an instance of an object.] ImageProcessor.Web.HttpModules.<ProcessImageAsync>d__b.MoveNext() +755 System

我已经尝试在Umbraco和vanilla MVC应用程序中实现自定义IImageService,建议如下:

但我想我可能错过了一步,因为我只得到了这个错误:

[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
[NullReferenceException:对象引用未设置为对象的实例。]
ImageProcessor.Web.HttpModules.d_ub.MoveNext()+755
System.Runtime.CompilerServices.TaskWaiter.ThrowForNonSuccess(任务任务)+92
System.Runtime.CompilerServices.TaskWaiter.HandleNonSuccessAndDebuggerNotification(任务)+58
System.Web.TaskAsyncHelper.EndTask(IAsyncResult ar)+71
System.Web.AsyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()+380
System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤,布尔值&同步完成)+155
下面的DatabaseImageService在Prefix属性和IsFileLocalSevice上被调用,但是我得到了上面的错误。IsValidRequest()和GetImage()从未被调用

代码是

我还尝试在ImageProcessor.Web.config附带的security.config文件中指定此ImageService,但出现了相同的错误

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;
        }
    }
}
名称空间ImageProcessorTest
{
公共类数据库ImageService:IImageService
{
私有字符串前缀=“database.axd”;
公共字符串前缀
{
得到
{
返回此.prefix;
}
设置
{
this.prefix=值;
}
}
公共bool IsFileLocalService
{
得到
{
返回true;
}
}
公共词典设置{get;set;}
公共Uri[]白名单{get;set;}
公共bool IsValidRequest(字符串路径)
{
返回ImageHelpers.IsValidImageExtension(路径);
}
公共异步任务GetImage(对象id)
{
字符串路径=id.ToString();
字节[]缓冲区;
FileInfo FileInfo=新的FileInfo(路径);
如果(!fileInfo.Exists)
{
抛出新的HttpException((int)HttpStatusCode.NotFound,“在”+路径上不存在映像);
}
使用(FileStream file=newfilestream(路径,FileMode.Open,FileAccess.Read,FileShare.Read,4096,true))
{
buffer=新字节[file.Length];
wait file.ReadAsync(缓冲区,0,(int)file.Length);
}
返回缓冲区;
}
}
}
更新1

上面的代码示例在一个普通的MVC应用程序中。配置如下:

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

****
为了说明这一点,我已经完成了以下步骤:

  • 香草MVC应用程序
  • 通过NuGet安装:ImageProcessor ImageProcessor.Web和ImageProcessor.Web.Config
  • 在上面创建了DatabaseImageService类
  • 编辑security.config,如图所示
我在网站“hami-1.jpg”的根目录中有一个图像。我可以使用默认的LocalFileImageService正确地操作它http://localhost:11832/hami-1.jpg?宽度=200

我为自定义IImageService指定的前缀是“database.axd”,因此url应该是:

  • http://localhost:11832/database.axd/hami-1.jpg?宽度=200
  • http://localhost:11832/database.axd?hami-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);
}
private-AppContext\u db=new-AppContext();
私人会员服务会员服务
{
得到
{
如果(ms==null)
{
ms=新会员服务(_db,UmbracoContext.Current);
}
返回ms;
}
}
公共异步任务GetImage(对象id=null)
{
var image=await _db.Images.FindAsync(id);
var currentMember=MembershipService.GetCurrentMember();
如果(图像!=null)
{
var content=image.content;
_db.Dispose();
交换机(图像.隐私)
{
案例模型.Base.Privacy.Private:
if(image.Owner.Id==currentMember.Id | | MembershipService.FindMembersRole(currentMember.UmbracoMember.Username,“法官”).Any())
返回内容;
打破
案例模型.Base.Privacy.Unlisted:
返回内容;
案例模型.Base.Privacy.Public:
返回内容;
}
}
抛出新的HttpException(404,“找不到id为“+id”的图像);
}

我使用最新的NuGet软件包也遇到了同样的问题。我已经通过将我正在使用的NuGet包降级到以下级别来修复了这个问题

图像处理器-v2.2.5

ImageProcessor.Web-v4.3.2


ImageProcess.Web.Config-v1.0.0

该错误是由于您没有初始化服务中的
设置
属性造成的,因此当我们检查是否存在某个属性时

string protocol = currentService.Settings.ContainsKey("Protocol")
异常被抛出

此外,您还错误地将
IsFileLocalService
属性设置为true

在HttpModule中,有一个针对该属性的检查

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

此属性表示文件包含在本地文件系统中。如果将其设置为true而文件不以这种方式存在,则会出现异常

在初始化和调用该类的位置张贴代码。@CathalMF该类是从ImageProcesso中初始化和调用的