J’aimerais acheminer les demandes vers différentes actions en fonction de la valeur d’un paramètre JSON particulier.
Par exemple, étant donné les données JSON suivantes:
{ type: "type1", type1data: "type1value" }
et
{ type: "type2", type2data: "type2value" }
J’aimerais pouvoir avoir 2 actions différentes sur mon ApiController:
void CreateType1(ssortingng type1data) { // ... } void CreateType2(ssortingng type2data) { //... }
Comment faire quelque chose comme ça?
Mettre à jour:
Je voudrais la même URL si possible. Quelque chose comme /objects/create
.
Je préférerais de loin utiliser un ApiControllerActionSelector personnalisé.
public class MyActionSelector : ApiControllerActionSelector { public override HttpActionDescriptor SelectAction( HttpControllerContext context) { HttpMessageContent requestContent = new HttpMessageContent( context.Request); var json = requestContent.HttpRequestMessage.Content .ReadAsSsortingngAsync().Result; ssortingng type = (ssortingng)JObject.Parse(json)["type"]; var actionMethod = context.ControllerDescriptor.ControllerType .GetMethods(BindingFlags.Instance | BindingFlags.Public) .FirstOrDefault(m => m.Name == "Create" + type); if (actionMethod != null) { return new ReflectedHttpActionDescriptor( context.ControllerDescriptor, actionMethod); } return base.SelectAction(context); } }
Voici le modèle. Je lui ai donné un nom étrange: Abc.
public class Abc { public ssortingng Type { get; set; } public ssortingng Type1Data { get; set; } }
Voici la méthode d’action.
public void Createtype1(Abc a) { }
Enfin, twigz le sélecteur d’action.
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.Services.Replace(typeof(IHttpActionSelector), new MyActionSelector()); } }
Si vous postez maintenant à http: // localhost: port / api / yourapicontroller, en fonction de la valeur dans le champ type en JSON, la méthode d’action Créer * sera sélectionnée.
Quelque chose comme ça. Pour des raisons de simplicité, cet exemple n’est pas une implémentation async appropriée.
using System.Net.Http; using System.Web.Http; namespace MyApi.Controllers { public class MyType { public ssortingng type {get; set;} } public class MyType1 { public ssortingng type {get; set;} public ssortingng type1data {get; set;} } public class MyType2 { public ssortingng type {get; set;} public ssortingng type2data {get; set;} } public class ObjectsController : ApiController { // // api/objects/create // public void Create() { // buffer the content to allow the dual reads below Request.Content.LoadIntoBufferAsync().Wait(); // get the body as a object so we can access its type property MyType postedObject = Request.Content.ReadAsAsync().Result; // decide switch (postedObject.type) { case "type1": CreateType1(Request.Content.ReadAsAsync().Result.type1data); break; case "type2": CreateType2(Request.Content.ReadAsAsync().Result.type2data); break; default: // 400 Bad Request would be best, I think. break; } } private void CreateType1(ssortingng type1data) { // ... } private void CreateType2(ssortingng type2data) { // ... } } }