WebApi è completamente in grado e lo preferisco. L'altra risposta è giusta che JSON e XML sono predefiniti, ma è possibile aggiungere il proprio MediaFormatter e servire qualsiasi tipo di contenuto per qualsiasi modello. Ciò consente di eseguire la negoziazione del contenuto e fornire contenuti diversi in base all'intestazione Accept o all'estensione del file. Facciamo finta che il nostro modello sia un "utente". Immagina di chiedere un "Utente" come json, xml, jpg, pdf. Con WebApi, possiamo usare le estensioni di file o l'intestazione Accept e chiedere/Users/1 o Users/1.json per JSON, Users/1.jpg per jpg, Users/1.xml per xml, /Users/1.pdf per pdf, ecc. Tutti questi potrebbero anche essere/Users/1 con diverse intestazioni Accept con qualità in modo che i tuoi clienti possano chiedere gli utenti/1 con un header Accept che chiede prima jpg, ma ricade in png.
Ecco un esempio di come creare un formattatore per .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);
}
}
Ora dobbiamo registrare il nostro formattatore (in genere 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());
}
}
E, infine, il nostro controller
public class UsersController : ApiController
{
public IHttpActionResult Get(int id)
{
var user = SomeMethodToGetUsersById(id);
return this.Ok(user);
}
}
Il controller non dovrà cambiare quando si aggiungono diversi formattatori. Restituisce semplicemente il modello e quindi i formattatori eseguono il kick in un secondo momento nella pipeline. Adoro i formattatori in quanto fornisce una così ricca API. Puoi leggere ulteriori informazioni sui formattatori su WebApi website.
per favore dimmi qual'è l'output di '' quando il formattatore predefinito è JSON? Penso che la risposta basata sul tuo esempio sopra sia che non funzionerà – Dalorzo
Ho risposto a questa stessa domanda sulla tua risposta, ma per rispondere anche a questo: Il formattatore predefinito verrebbe eseguito qui e sarà json. Questo è un problema HTML che non è in grado di esprimere un'intestazione Accept in un tag immagine. Per questo motivo, è necessario aggiungere un'estensione di file 'src = '/ api/image/getImg.jpg''. Questo verrà quindi indirizzato a JpegFormatter. Qualsiasi client in grado di impostare le intestazioni può semplicemente inserire l'intestazione Accept in image/jpeg e il formattatore verrà eseguito. – ManOVision
@ManOVision, grazie per la tua risposta, questo è esattamente come l'ho fatto in passato. E penso che nello scenario che voglio usarlo la tua soluzione è probabilmente la migliore. – R4nc1d