【发布时间】:2015-06-17 13:50:08
【问题描述】:
我想创建一个图像处理程序,但我在使用Web API 2 或只是普通的Generic Handler (ashx) 之间纠结
我过去都实现过,但哪一个是最正确的。 我找到了一个旧的 SO 帖子 LINK,但它仍然真的相关吗?
【问题讨论】:
标签: c# asp.net asp.net-web-api
我想创建一个图像处理程序,但我在使用Web API 2 或只是普通的Generic Handler (ashx) 之间纠结
我过去都实现过,但哪一个是最正确的。 我找到了一个旧的 SO 帖子 LINK,但它仍然真的相关吗?
【问题讨论】:
标签: c# asp.net asp.net-web-api
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 标头和质量,因此您的客户可以要求带有 Accept 标头的 Users/1 首先要求 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 上阅读有关格式化程序的更多信息。
【讨论】:
<img src='/api/image/getImg' /> 的输出是什么?我认为根据您上面的示例的答案是它不起作用
src='/api/image/getImg.jpg'。然后这将路由到 JpegFormatter。任何能够设置标头的客户端都可以简单地将 Accept 标头放入 image/jpeg 并运行格式化程序。
正确的是ashx,原因是内容类型。如果您使用 Web Api,则响应的内容类型(即媒体格式化程序(格式))是为所有服务定义的类型,即 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
重要提示:我们都清楚WebApi 和Ashx 都可以返回图像。我并不是说 WebApi 无法实现这一点,我只是说为什么我相信 Ashx 是正确的选择。
【讨论】:
我非常喜欢灵活性和定制化。我个人会选择httpHandler。所以要回答你的问题,这真的取决于你的要求。
首先,WebAPI 是从 http (GET/POST) 调用到 Web 服务的演变的结果,并且需要能够以比 Web 服务更低的成本传输数据。 HttpHandlers 早在 web apis 之前就使用了相同的概念。基本上,web api 只不过是一个没有用户界面的 http 页面(如果你愿意的话)。
在选择 HttpHandler 或 Web Api 之前需要了解的几件事
可能会有更多比较(作为一名经理,我认为也是从管理方面而不是完全技术角度),因此您可能需要权衡您的选择并决定要做什么。由于处理程序文件无论如何都是 Web API 的基础,我会说它为开发人员提供了比 Web API 更多的功能。就像 http 套接字比 httphandler 做的更多。
【讨论】: