ImageProcessor.Web 自定义 IImageService 导致 NullReferenceException
ImageProcessor.Web custom IImageService causes NullReferenceException
我尝试按照此处的建议在 Umbraco 和普通 MVC 应用程序中实现自定义 IImageService:
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() 永远不会被调用。
的副本
我也尝试在 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;
}
}
}
更新 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 应用程序
- 已安装:ImageProcessor ImageProcessor.Web 和 ImageProcessor.Web.Config 通过 NuGet
- 创建了上面的 DatabaseImageService class
- 如图所示编辑 security.config
我在站点的根目录中有一个图像 "hami-1.jpg"。我可以使用默认的 LocalFileImageService http://localhost:11832/hami-1.jpg?width=200 .
正确操作它
我为我的自定义 IImageService 指定的前缀是 "database.axd" 所以 url 应该是: ?
- http://localhost:11832/database.axd/hami-1.jpg?width=200
- http://localhost:11832/database.axd?hami-1.jpg?width=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);
}
我在使用最新的 NuGet 包时遇到了同样的问题。我现在通过将我正在使用的 NuGet 包降级为以下版本来解决这个问题。
ImageProcessor - v2.2.5
ImageProcessor.Web - v4.3.2
ImageProcess.Web.Config - v1.0.0
错误是由于您没有在您的服务中初始化 Settings
属性 所以当我们检查某个 属性
是否存在时
string protocol = currentService.Settings.ContainsKey("Protocol")
抛出异常
此外,您错误地将 IsFileLocalService
属性 设置为 true。
在 HttpModule 中有一个针对 属性 的检查。
requestPath = currentService.IsFileLocalService
? HostingEnvironment.MapPath(request.Path)
: request.Path;
这属性表示该文件包含在本地文件系统中。如果你将它设置为 true 而文件不以这种方式存在,你将得到一个异常。
我尝试按照此处的建议在 Umbraco 和普通 MVC 应用程序中实现自定义 IImageService:
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() 永远不会被调用。
的副本我也尝试在 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;
}
}
}
更新 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 应用程序
- 已安装:ImageProcessor ImageProcessor.Web 和 ImageProcessor.Web.Config 通过 NuGet
- 创建了上面的 DatabaseImageService class
- 如图所示编辑 security.config
我在站点的根目录中有一个图像 "hami-1.jpg"。我可以使用默认的 LocalFileImageService http://localhost:11832/hami-1.jpg?width=200 .
正确操作它我为我的自定义 IImageService 指定的前缀是 "database.axd" 所以 url 应该是: ?
- http://localhost:11832/database.axd/hami-1.jpg?width=200
- http://localhost:11832/database.axd?hami-1.jpg?width=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);
}
我在使用最新的 NuGet 包时遇到了同样的问题。我现在通过将我正在使用的 NuGet 包降级为以下版本来解决这个问题。
ImageProcessor - v2.2.5
ImageProcessor.Web - v4.3.2
ImageProcess.Web.Config - v1.0.0
错误是由于您没有在您的服务中初始化 Settings
属性 所以当我们检查某个 属性
string protocol = currentService.Settings.ContainsKey("Protocol")
抛出异常
此外,您错误地将 IsFileLocalService
属性 设置为 true。
在 HttpModule 中有一个针对 属性 的检查。
requestPath = currentService.IsFileLocalService
? HostingEnvironment.MapPath(request.Path)
: request.Path;
这属性表示该文件包含在本地文件系统中。如果你将它设置为 true 而文件不以这种方式存在,你将得到一个异常。