使用ASP.NET服务器提供图像
本文关键字:图像 服务器 ASP NET 使用 | 更新日期: 2023-09-27 18:26:39
我是ASP.NET的新手,我正在尝试制作一个服务器应用程序,该应用程序在客户端发出HTTP请求时返回存储的映像。我只是不确定从哪里开始。
我对在服务器和客户端之间建立连接的过程很有信心,但我不确定如何处理HTTP请求和响应。我想我必须使用System.Web.HttpRequest和System.Web.HttpResponse.
用例可能如下所示:
客户端向服务器发送一个URL,如http://10.10.180.10:8080/Images/image.jpg
,然后由服务器处理,如果URL等于/Images/image.jpg
,则通过某种输出流返回图像。
我很难找到一个关于如何开始这项工作的好指南。我在ASP.NET中发现的一切都是为了制作一个网站,但我只想制作一个服务器应用程序,因为我已经有了客户端。
如果您不需要任何特定的功能,那么IIS可以很好地提供文件系统中的图像。您甚至可以在此基础上配置基于ASP.NET的身份验证,并根据角色限制访问。
如果你确实需要一个特定的功能(比如添加水印或从数据库中获取图像),那么你需要使用一个HttpHandler。这基本上是一个通过名为ProcessRequest的方法处理HTTP请求的类。在这种方法中,您可以编写适当的代码来获取图像,如果需要,可以对其进行操作,并使用Response对象将字节写入客户端。如果您需要高可伸缩性,建议使用异步HttpHandler。
这是一个完整的处理程序,我们在现实世界的项目中使用它来提供数据库中的图像,并支持缓存。我确信它不是完美和普遍的,但它对我们有效。
using OurProject.Models.Entities;
using System;
using System.Data.Entity;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
namespace OurProject
{
public class PhotoHandler : HttpTaskAsyncHandler
{
private const double CacheDateEpsilonSeconds = 1;
public override bool IsReusable
{
get
{
//the handler does not store any state so the object can be reused
return true;
}
}
public override async Task ProcessRequestAsync(HttpContext context)
{
//get the id of the photo object
int photoID;
if (!Int32.TryParse(context.Request.QueryString["ID"], out photoID))
{
context.Response.StatusCode = 400;
return;
}
var dataContext = new DataContext();
//retrieve the object metadata from the database. Not that the call is async so it does not block the thread while waiting for the database to respond
PhotoInfo photoInfo = await dataContext.PhotoInfos.SingleOrDefaultAsync(pi => pi.BusinessCardID == photoID);
//if the object is not found return the appropriate status code
if (photoInfo == null)
{
context.Response.StatusCode = 404;
return;
}
DateTime clientLastModified;
//check if the image has been modified since it was last served
//if not return 304 status code
if (DateTime.TryParse(context.Request.Headers["If-Modified-Since"], out clientLastModified) &&
clientLastModified.AddSeconds(CacheDateEpsilonSeconds) >= photoInfo.LastModifiedDate)
{
context.Response.StatusCode = 304;
context.Response.StatusDescription = "Not Modified";
return;
}
//set various cache options
context.Response.Cache.SetCacheability(HttpCacheability.Private);
context.Response.Cache.VaryByParams["d"] = true;
context.Response.Cache.SetLastModified(photoInfo.LastModifiedDate);
context.Response.Cache.SetMaxAge(new TimeSpan(365, 0, 0, 0));
context.Response.Cache.SetOmitVaryStar(true);
context.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(365));
context.Response.Cache.SetValidUntilExpires(true);
//Get the actual file data. Again note the async IO call
PhotoFile file = await dataContext.PhotoFiles.SingleAsync(pf => pf.BusinessCardID == photoID);
//serve the image with the appropriate MIME type. In this case the MIME type is determined when saving in the database
context.Response.ContentType = photoInfo.MimeType;
context.Response.BinaryWrite(file.PhotoData);
}
}
}