MVC est designé pour des applications web standard qui servent des pages HTML.
Web API est designé pour des applications REST qui servent des objets sérialisés (JSON, XML).
L'extension pour Firefox RESTED permet de tester les requêtes.
Global.asax.cs
protectedvoidApplication_Start()
{
// return json by default (ajouter à la fin de la méthode)
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(newJsonMediaTypeFormatter());
App_Start/WebApiConfig.cs
// return html by default instead of xml
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(newMediaTypeHeaderValue("text/html"));
Permet de redéfinir la manière dont sera déserialisé l'url.
TestController.cs
// association 1, fonctionne seulement si ComplexType est passé en paramètre// api/test?ct=1,2publicIHttpActionResultGet([ModelBinder(typeof(ComplexTypeModelBinder))] ComplexType ct) { }
// api/test?cts[0]=1,2&cts[1]=3,4publicIHttpActionResultGet([FromUri] IEnumerable<ComplexType> cts) { }
// api/test?ComplexTypes[0]=1,2&ComplexTypes[1]=3,4publicIHttpActionResultGet([FromUri] Containercontainer) { }
// association 2, fonctionne si ComplexType est passé en paramètre mais aussi s'il est un sous-élément du paramètre
[ModelBinder(typeof(ComplexTypeModelBinder))]
publicclassComplexType
{
publicint Prop1 { get; set; }
publicint Prop2 { get; set; }
}
publicclassContainer
{
publicIEnumerable<ComplexType> ComplexTypes { get; set; }
}
WebApiConfig.cs
publicstaticvoidRegister(HttpConfigurationconfig)
{
// association 3, fonctionne seulement si ComplexType est passé en paramètre// la méthode du controller ne doit pas contenir FromUri
config.ParameterBindingRules.Add(
typeof(ComplexType),
descriptor => descriptor.BindWithModelBinding(newComplexTypeModelBinder()));
// association 4, fonctionne si ComplexType est passé en paramètre mais aussi s'il est un sous-élément du paramètre// la méthode du controller doit contenir FromUri
config.Services.Insert(typeof(ModelBinderProvider), 0, newComplexTypeModelBinderProvider());
}
Use JsonConverter to build a custom uri with parameters.
varhttpClient = newHttpClient();
// demande explicitement du xml ("application/xml") ou du json ("application/json")
httpClient.DefaultRequestHeaders.Accept.Add(newMediaTypeWithQualityHeaderValue("application/xml"));
// requête en une ligne utilisant Result, ce qui brise l'asyncstringcontent = httpClient.GetAsync(url).Result.Content.ReadAsStringAsync().Result;
// requête en 2 temps avec test du status codeHttpResponseMessageresponse = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
// XMLvardoc = XDocument.Load(awaitresponse.Content.ReadAsStreamAsync());
varns = (XNamespace)"http://schemas.datacontract.org/2004/07/WebAPITest.Models";
foreach (var name in doc.Descendants(ns + "Name"))
{
Console.WriteLine(name.Value);
}
// récupération du contenu comme un stringstringcontent = await response.Content.ReadAsStringAsync();
// désérialisation du contenu// ReadAsAsync<T> nécessite l'assembly System.Net.Http.Formatting// disponible dans le paquet NuGet Microsoft.AspNet.WebApi.Client// et le using System.Net.Http;MyDtomyDto = await response.Content.ReadAsAsync<MyDto>();
}
else
{
// retourne un Task<T> avec un contenu nullreturnawait Task.FromResult<MyDto>(null);
}
By default, most exceptions are translated into an HTTP response with status code 500, Internal Server Error.
// HttpResponseException permet de spécifier le code d'erreur, ici 404thrownewHttpResponseException(HttpStatusCode.NotFound);
// spécifie en plus le Content et la ReasonPhrasevarresponseMessage = newHttpResponseMessage(HttpStatusCode.NotFound)
{
Content = newStringContent("Error content."),
ReasonPhrase = "Error reason."
}
thrownewHttpResponseException(responseMessage);
publicstaticclassWebApiConfig
{
publicstaticvoidRegister(HttpConfigurationconfig)
{
/* ... */// plusieurs ExceptionLogger peuvent être ajoutés, permet juste de loguer
config.Services.Add(typeof(IExceptionLogger), newMyExceptionLogger());
// un seul ExceptionHandler, permet de modifier la réponse
config.Services.Replace(typeof(IExceptionHandler), newGlobalExceptionHandler());
<configuration><appSettings><addkey="owin:AutomaticAppStartup"value="false" /></appSettings><system.webServer><!-- choice 1: Pipe all request to the .NET pipeline --><modulesrunAllManagedModulesForAllRequests="true" /><!-- choice 2: Pipe only the Swagger request to the specific middlewares --><handlers><addname="NSwag"path="swagger"verb="*"type="System.Web.Handlers.TransferRequestHandler"preCondition="integratedMode,runtimeVersionv4.0" /></handlers></system.webServer>
Url: http://localhost:{port}/swagger
Right-click on the project → Properties → Web → Start Action → Specific Page → /swagger
Visual Studio et un projet Web API
New Project → ASP.NET Web Application → Template: Empty → cocher Web API
Clique-droit sur le dossier Controllers → Add Controller → Web API 2 Controller - Empty