我是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中找到的所有东西都是为了建立一个网站,但我只想创建一个服务器应用程序,因为我已经有了客户端。
答案 0 :(得分:4)
如果您不需要任何特定功能,那么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);
}
}
}