Web Api 2 или Generic Handler для обслуживания изображений?

Я хочу создать обработчик изображения, но я разорван между использованием Web API 2 или просто нормальным Generic Handler (ashx)

Я реализовал оба в прошлом, но один из них наиболее правильный. Я нашел старую ссылку SO < LINK, но действительно ли она актуальна?

Ответ 1

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 с качеством, чтобы ваши клиенты могли запросить пользователей /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 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.

Ответ 2

Правильный - ashx, причина в типе . Если вы используете Web Api, тип контента a.k.a формат (формат) вашего ответа является тем, который определен для всех ваших сервисов, что означает 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 - правильный выбор.

Ответ 3

Я большой поклонник гибкости и настройки. Я лично поеду за httpHandler. Поэтому, чтобы ответить на ваш вопрос, это действительно зависит от ваших требований.

Первое, что WebAPI является результатом эволюции на всем пути от вызовов HTTP (GET/POST) к веб-службам и необходимости передачи данных за меньшую плату, а не для веб-сервисов. HttpHandlers использовали ту же концепцию долгое время перед веб-apis. В основном веб-apis - это только страница http без его пользовательского интерфейса (если вы хотите).

Немногие вещи нужно знать, прежде чем выбирать HttpHandler или Web Api

  • время разработки - знаете ли вы, что очень хорошо, и что потребуется меньше времени для реализации.
  • Как упоминалось в его ответе Manovision, пользователь маршрутизации /1 вы все равно можете реализовать с помощью простого кода и httphandler, поэтому для этого вам не нужен Web API. только вам, возможно, придется подправить код вручную, добавив немного времени в разработку
  • Гибкость, мне лично нравится эта часть, так как я смогу контролировать тип содержимого ответа, как я хочу, в зависимости от пользователя данных. Мне не нужно выполнять проверки сеанса и перенаправлять на любую страницу. Я все еще могу контролировать это поведение во что бы то ни стало. веб-API также вы можете сделать, но в основном вещи выполняются во время выполнения самостоятельно для конфигурации, которую мы создали в процессе разработки.
  • веб-страница рендеринга одинакова для обоих. Хотя httphandler легко, поэтому зачем использовать веб-API?

Там может быть больше сравнения (как менеджер, я думаю, со стороны руководства, а также не полностью техническая перспектива), поэтому вам, возможно, придется взвесить ваши варианты и решить, что делать. Поскольку файл обработчика в любом случае является основой веб-API, я бы сказал, что он дает больше возможностей разработчику, чем веб-api. так же, как http-сокет будет делать больше, чем httphandler.