0

I have a model that contains an interface based property, which the concrete implementation being discoverable via another property of the model.

public class SubscriptionViewModel
{
    public Guid Id { get; set; }
    ...
    public SubscriptionTypeEnum SubscriptionType { get; set; } // <- Determines the concrete class
    public ISubscriptionCriteria SubscriptionCriteria { get; set; } //<- Property based on interface class
    ...
}

When the interface based property is present the model in the controller comes through as null. If removed, everything binds as expected.

[HttpPost("api/[controller]/[action]")]
public async Task Post([FromBody]SubscriptionViewModel model)
{
    ...
}

This will be because the controller doesn't know which solid implementation to use for the interface.

Any ideas how I can solve this? It looks like this might be achievable using a custom IModelBinderProvider or BindingBehaviorAttribute?

I guess I could have a SuperSubscriptionCriteria implementation that contains all possible properties used by concrete implementations of ISubscriptionCriteria and then rely on AutoMapper to convert them to the real implementations. But this seems like a hack and would require on-going maintenance as new ISubscriptionCriteria implementations are added.

4
  • What is the purpose of having ISubscriptionCriteria as property in ViewModel? I'm just curious. Commented Jul 18, 2017 at 22:08
  • Depending upon the type of subscription there's several different criteria types available, specific to certain subscriptions. In this case subscriptions are email alerts about permit data - www.permitwatch.co.nz Commented Jul 18, 2017 at 22:10
  • How does actual implementation get assign to ISubscriptionCriteria? Normally, MVC's ViewMode doesn't have external dependencies, unless you are using it as MVVM's View Model. Commented Jul 18, 2017 at 22:15
  • AutoMapper is used to populate the ViewModel from other classes, one of my previous q's might give more detail - stackoverflow.com/questions/38953348 Commented Jul 18, 2017 at 22:25

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.