R4n*_*c1d 10 c# asp.net asp.net-web-api
我想创建一个图像处理程序,但我在使用Web API 2或只是正常之间撕裂Generic Handler (ashx)
我过去已经实现过,但哪一个是最正确的.我找到了一个旧的SO帖子LINK,但它仍然真的相关吗?
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);
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们需要注册我们的格式化程序(通常是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());
}
}
Run Code Online (Sandbox Code Playgroud)
最后,我们的控制器
public class UsersController : ApiController
{
public IHttpActionResult Get(int id)
{
var user = SomeMethodToGetUsersById(id);
return this.Ok(user);
}
}
Run Code Online (Sandbox Code Playgroud)
添加不同的格式化程序时,您的控制器不必更改.它只是返回你的模型,然后格式化程序在管道中稍后启动.我喜欢格式化程序,因为它提供了如此丰富的API.您可以在WebApi网站上阅读有关格式化程序的更多信息.
正确的是ashx,原因是内容类型.如果您使用Web Api,则响应的内容类型(即媒体格式化程序(格式))是为您的所有服务定义的,即JSON,XML或oData.
//Global Asax, Web Api register methods is used to defined WebApi formatters
Run Code Online (Sandbox Code Playgroud)
config.Formatters.Insert(0, new System.Net.Http.Formatting.JsonMediaTypeFormatter());
但是,图像是二进制文件,因此您需要以原始格式发送图像,而不是以JSON或XML格式发送图像
response.AddHeader("content-type", "image/png");
response.BinaryWrite(imageContent);
response.Flush();
Run Code Online (Sandbox Code Playgroud)
这就是为什么ashx是这项工作的正确工具.
另一个优点是您可以更好地控制输出,而无需为希望通过执行Ashx文件中的操作返回的每种图像类型编写新的"格式化程序"(使WebApi解决此问题的方法):
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.
Run Code Online (Sandbox Code Playgroud)
您可以使用各种类型的游戏:
https://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageformat(v=vs.110).aspx
重要提示:对于我们所有人来说,WebApi和Ashx都可以返回图像.我并没有以任何方式说你无法用WebApi实现这一点我所说的就是为什么我相信Ashx是正确的选择.
| 归档时间: |
|
| 查看次数: |
4827 次 |
| 最近记录: |