Web Api 2或通用处理程序来提供图像

本文关键字:程序 图像 处理 Api Web | 更新日期: 2023-09-27 17:56:56

我想创建一个图像处理程序,但我在使用Web API 2还是仅使用普通的Generic Handler (ashx) 之间左右为难

我过去都实现过,但哪一个是最正确的。我找到了一个旧的SO帖子链接,但它真的很相关吗?

Web Api 2或通用处理程序来提供图像

WebApi功能齐全,我更喜欢它。另一个答案是正确的,JSON和XML是默认的,但您可以添加自己的MediaFormatter,并为任何模型提供任何内容类型。这允许您执行内容协商,并根据Accept标头或文件扩展名提供不同的内容。让我们假设我们的模型是"用户"。想象一下,请求一个json、xml、jpg、pdf格式的"用户"。有了WebApi,我们可以使用文件扩展名或Accept标头,并要求/Users/1或Users/1.json表示json,Users/1.jpg表示jpg,Users/1-xml表示xml,/Users/1.pdf表示pdf等。所有这些也可以只是/Users/1,具有不同的Accept标头和质量,因此您的客户可以要求Users/1具有Accept标头并首先要求jpg,但又回到png。

以下是如何为.jpg.创建格式化程序的示例

public class JpegFormatter : MediaTypeFormatter
{
    public JpegFormatter()
    {
        //this allows a route with extensions like /Users/1.jpg
        this.AddUriPathExtensionMapping(".jpg", "image/jpeg");
        //this allows a normal route like /Users/1 and an Accept header of image/jpeg
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("image/jpeg"));
    }
    public override bool CanReadType(Type type)
    {
        //Can this formatter read binary jpg data?
        //answer true or false here
        return false;
    }
    public override bool CanWriteType(Type type)
    {
        //Can this formatter write jpg binary if for the given type?
        //Check the type and answer. You could use the same formatter for many different types.
        return type == typeof(User);
    }
    public override async Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content,
        TransportContext transportContext)
    {
        //value will be whatever model was returned from your controller
        //you may need to check data here to know what jpg to get
        var user = value as User;
        if (null == user)
        {
            throw new NotFoundException();
        }
        var stream = SomeMethodToGetYourStream(user);
        await stream.CopyToAsync(writeStream);
    }
}

现在我们需要注册我们的格式化程序(通常是App_Start/WebApiConfig.cs(

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        ...
        //typical route configs to allow file extensions
        config.Routes.MapHttpRoute("ext", "{controller}/{id}.{ext}");
        config.Routes.MapHttpRoute("default", "{controller}/{id}", new { id = RouteParameter.Optional });
        //remove any default formatters such as xml
        config.Formatters.Clear();
        //order of formatters matter!
        //let's put JSON in as the default first
        config.Formatters.Add(new JsonMediaTypeFormatter());
        //now we add our custom formatter
        config.Formatters.Add(new JpegFormatter());
    }
}

最后,我们的控制器

public class UsersController : ApiController
{
    public IHttpActionResult Get(int id)
    {
        var user = SomeMethodToGetUsersById(id);
        return this.Ok(user);
    }
}

当您添加不同的格式化程序时,您的控制器将不必更改。它只是简单地返回您的模型,然后格式化程序稍后在管道中启动。我喜欢格式化程序,因为它提供了如此丰富的api。您可以在WebApi网站上阅读更多关于格式化程序的信息。

正确的是ashx原因是内容类型。如果您使用WebApi,则响应的内容类型(也称为媒体格式化程序(是为所有服务(即JSON、XML或oData(定义的。

//Global Asax, Web Api register methods is used to defined WebApi formatters

config.Formatters.Insert(0, new System.Net.Http.Formatting.JsonMediaTypeFormatter());

然而,图像是二进制的,因此您需要以其原始格式发送图像,而不是以JSON或XML 格式发送

response.AddHeader("content-type", "image/png");

 response.BinaryWrite(imageContent);
 response.Flush();

这就是为什么ashx是适合该工作的工具。

一个额外的优势是,您可以更好地控制您的输出,而无需为您想要返回的每种图像类型编码一个新的"格式化程序"(使WebApi解决此问题的方法(,方法类似于在Ashx文件中:

var png = Image.FromFile("some.png");
png.Save("a.gif", var png = Image.FromFile("some.png");
png.Save("a.gif", ImageFormat.Gif); //Note you can save the new image into a MemoryStream to return it later in the same method.

你可以玩各种类型的游戏:

https://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageformat(v=vs.110(.aspx

重要信息:我们大家都清楚,WebApiAshx都可以返回图像。我并不是说你不能用WebApi实现这一点,我想说的是为什么我相信Ashx是正确的选择。

我非常喜欢灵活性和定制。我个人会选择httpHandler。因此,要回答您的问题,实际上取决于您的要求。

首先,WebAPI是从http(GET/POST(调用到web服务的进化的结果,以及与web服务相比能够以更低的成本传输数据的需求。HttpHandlers早在web api之前就使用了相同的概念。基本上,web api只是一个没有用户界面的http页面(如果你愿意的话(。

在选择HttpHandler或Web Api 之前,需要知道的事情很少

  1. 开发时间-您是否非常清楚这两个方面,以及您需要较少的时间来实现什么
  2. 正如ManOVision在回答中提到的那样,路由用户/1仍然可以用简单的代码和httphandler实现,因此您不需要Web API。只有您可能需要手动更正代码,从而在开发过程中增加一点时间
  3. 灵活性,我个人喜欢这一部分,因为我将能够根据用户提供的数据控制我想要的响应内容类型。我不需要执行会话检查和重定向到任何页面。我仍然可以随心所欲地控制这种行为。web API也可以,但大多数事情都是在运行时根据我们在开发时的配置自行完成的
  4. 渲染网页对两者都是一样的。虽然httphandler很容易,为什么要使用Web API

可能会有更多的比较(作为一名经理,我也从管理的角度考虑,而不是完全从技术的角度(,所以你可能必须权衡你的选择并决定该做什么。由于处理程序文件无论如何都是web API的基础,我想说它比web API给开发人员更多的权力。就像http套接字比httphandler做得更多一样。