使用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中发现的一切都是为了制作一个网站,但我只想制作一个服务器应用程序,因为我已经有了客户端。

使用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);
        }
    }
}