2017-07-31 6 views
0

J'ai une API ASP.NET Core qui prend un paramètre DTO appelé DetParameterCreateDto qui ressemble à cecinom de la propriété dynamique en entrée API

DTO

public class DetParameterCreateDto 
{ 
    public int Project_Id { get; set; } 
    public string Username { get; set; } 
    public string Instrument { get; set; } 
    public short Instrument_Complete { get; set; } 
} 

Le problème que j'ai est que le paramètre transmis depuis le client a une propriété nommée Instrument_Complete; ce qui est dynamique.

Le nom est réellement [instrument]_complete[instrument] est le nom de l'instrument. Donc, si le nom de l'instrument est my_first_project alors le nom de la propriété du paramètre sera en fait my_first_instrument_complete, ce qui ne correspondra pas correctement au paramètre d'entrée de mon API; il montre toujours une valeur de 0

API Méthode

[HttpPost("create")] 
    public IActionResult CreateDetEntry(DetParameterCreateDto detParameters) 
    { 
     // some stuff in here 
    } 

Mise à jour (8/2)

En utilisant la suggestion de bradley il semble que je peux le faire avec le modèle personnalisé obligatoire. Cependant, je dois définir chaque propriété de modèle à la place de celle que je veux définir instrument_complete (et convertir certains de chaîne). Cela ne semble pas être une solution optimale.

public Task BindModelAsync(ModelBindingContext bindingContext) 
    { 
     if (bindingContext == null) 
     { 
      throw new ArgumentNullException(nameof(bindingContext)); 
     } 

     var instrumentValue = bindingContext.ValueProvider.GetValue("instrument").FirstValue; 

     var model = new DetParameterCreateDto() 
     { 
      Project_Id = Convert.ToInt32(bindingContext.ValueProvider.GetValue("project_id").FirstValue), 
      Username = bindingContext.ValueProvider.GetValue("username").FirstValue, 
      Instrument = instrumentValue, 
      Instrument_Complete = Convert.ToInt16(bindingContext.ValueProvider.GetValue($"{instrumentValue}_complete").FirstValue), 

     bindingContext.Result = ModelBindingResult.Success(model); 
     return Task.CompletedTask; 

    } 
+0

Vous pouvez probablement utiliser un 'ActionFilter' pour localiser le paramètre et modifier son nom avant que' CreateDetEntry' ne soit appelé. –

+1

En fait, un [customBlenderBinder'] personnalisé (http://blog.learningtree.com/creating-a-custom-web-api-model-binder/) serait probablement plus approprié pour changer la façon dont les données sont mappées. –

Répondre

0

DTO params dans l'API Web limitent en particulier lorsque les propriétés sont dynamiques. J'ai résolu un problème similaire auparavant en utilisant JObject. Le vôtre pourrait être quelque chose comme:

[HttpPost("create")] 
public IActionResult CreateDetEntry(JObject detParameters) 
{ 
    //DO something with detParameters 
    ... 
    //Optionally convert it to your DTO 
    var data = detParameters.ToObject<DetParameterCreateDto>(); 
    // or use it as is 
} 
+0

Cela fonctionnera-t-il encore si les données ne sont pas transmises en notation JSON? Je ne pense pas que l'API utilise JSON parce que quand j'avais [[FromBody] 'dans les params cela ne fonctionnait pas. Aussi, est-il préférable d'accepter tous les paramètres? J'aime l'avoir fortement validé –