Web Api 2或Generic Handler提供图像?

时间:2015-06-17 13:50:09

标签: c# asp.net asp.net-web-api

我想创建一个图片处理程序,但我在使用Web API 2或只是普通Generic Handler (ashx)

之间徘徊

我过去已经实现过,但哪一个是最正确的。 我发现了一篇旧帖子LINK,但它仍然真的相关吗?

3 个答案:

答案 0 :(得分:7)

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 website上阅读有关格式化程序的更多信息。

答案 1 :(得分:6)

正确的是 ashx ,原因是内容类型。如果您使用Web Api,则响应的内容类型a.k.a媒体格式化程序(格式)是为您的所有服务定义的,表示JSON,XML或oData。

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

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

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

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

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.

这就是为什么 ashx 是该工作的正确工具。

另一个优点是,您可以更好地控制输出,而无需为要通过执行类似操作返回的每种图像类型编写新的“格式化程序”(使WebApi解决此问题的方法) Ashx文件:

from("some http client")

        .beanRef("foo", "myMethod")
        .beanRef("foo", "myMethod")
        .filter().method("com.microsoft.applicationinsights.web.internal.WebRequestTrackingFilter", "doFilter");
        .choice()

        .when(isGET).process(someProcessor)
          .when(isPUT).process(someProcessor)
          .when(isPOST).process(someProcessor)
          .when(isDELETE).process(someProcessor)
          .otherwise().setHeader(Exchange.HTTP_RESPONSE_CODE, constant(404));

你可以玩各种各样的类型:

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

  

重要提示:对于我们所有人来说, WebApi Ashx 都可以返回图像。我并没有以任何方式说你无法通过WebApi实现这一点我所说的就是为什么我相信Ashx是正确的选择。

答案 2 :(得分:1)

我是灵活性和定制的忠实粉丝。我个人会去httpHandler。所以要回答你的问题,这实际上取决于你的要求。

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

在选择HttpHandler或Web Api

之前,很少需要了解
  1. 开发时间 - 您是否非常了解以及实施
  2. 的时间更短
  3. 正如ManOVision在他的回答中提到的那样,路由用户/ 1你仍然可以用简单的代码和httphandler来实现,所以你真的不需要Web API。只有你可能必须手动修改代码才能在开发中加一点时间
  4. 灵活性,我个人喜欢这个部分,因为我可以根据用户提供的数据控制响应内容类型。我不需要执行会话检查并重定向到任何页面。我仍然可以控制这种行为,无论我想要什么。您也可以使用Web API,但大部分内容都是在运行时自行采用我们在开发过程中实施的配置。
  5. 渲染网页对于两者都是相同的。虽然httphandler很容易,但为什么要使用Web API?
  6. 可能会有更多的比较(作为一名经理,我认为从管理方面来看,而不是完全从技术角度来看),所以你可能需要权衡你的选择并决定做什么。由于处理程序文件无论如何都是Web API的基础,我认为它为开发人员提供了比web api更强大的功能。就像一个http套接字比httphandler做的更多。