Ответ 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.