0

I have an ASP.NET Core 1.1 API that takes in a DTO parameter called DetParameterCreateDto. The problem I am having is that one of the property names is dynamic (instrument_complete). The name is actually [instrument]_complete where [instrument] is the name of the instrument.

So if the instrument is my_first_instrument then the property name will really be my_first_instrument_complete.

After posting on here and searching the web, it seems like the best solution is to create a custom model binder. I am wondering if there is a way to just custom map the instrument_complete parameter, and set the rest to the default map. I feel like my solution below is not the best solution because of performance of having to map and convert all the parameters, and because creating a new model will not transfer the model state; so will clear any validation errors. I may be wrong but this is what I believe

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; }

    // Other properties here...
}

Custom Model Binder

    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;

    }
Eitan K
  • 837
  • 1
  • 17
  • 39
  • It seems like there would be a much easier solution, just make `Instrument_Complete` an object. – Bender Bending Aug 03 '17 at 13:12
  • 1
    *Why does the property name need to be dynamic?* That's a recipe for disaster. Just post to something like `Complete`, and then you can map that to where it should go later. – Chris Pratt Aug 03 '17 at 13:31
  • @ChrisPratt I completely agree with you, in my opinion it should not be dynamic. However, a 3rd party application is calling this API and that is the way the parameter name is – Eitan K Aug 03 '17 at 18:35
  • Well, I realize that things are sometimes out of our hands as developers, but that frankly makes no sense. It's an Application Programming *Interface*; the API is supposed to dictate how the client works with it, not the other way around. – Chris Pratt Aug 03 '17 at 18:44
  • If it was a design decision made long ago, and you're simply trying to update the API, you should create a new version of it, and then migrate the third party off the old version. Want the new stuff? Change your code. Otherwise, keep using the old API (at least while it's still supported), and make do with what you have. – Chris Pratt Aug 03 '17 at 18:48
  • What where is your question here is it resolve??!?!? – johnny 5 Sep 20 '17 at 04:32

0 Answers0