So I scoured Stack Overflow as much as I possibly could and couldn't find an answer to this specific issue. Apologies if this has already been asked.
I've found answers to:
- how to pass an object/class to an action
- how to pass an object via the query string to an action
- how to pass an object via json to an action
- how to pass a polymorphic object to an action and have a custom model binder process it
Suppose you have the following code, how can you combine the above techniques into one solution. So I'd like to hit the action on the controller (using the jquery ajax call) with a json object, pass in a view model to the action, and have it determine the the correct polymorphic type (in this case, type of Notification) - possibly by using a custom model binder.
Note: this is example code used to illustrate the issue.
Models:
public class Notification
{
public int ID { get; set; }
public string ApplicationID { get; set; }
public string Description { get; set; }
public System.DateTime DateStamp { get; set; }
}
public class WarningNotification : Notification
{
public string WarningText { get; set; }
}
public class AlertNotification : Notification
{
public string AlertText { get; set; }
public int AlertId { get; set; }
}
View Model:
public class SaveNotificationViewModel
{
public Notification Notification { get; set; }
public string Hash { get; set; }
public List<int> Users { get; set; }
}
Controller action:
public ActionResult Save(SaveNotificationViewModel model)
{
//code inside method irrelevant...
}
Model Binder:
public class NoticationModelBinder : DefaultModelBinder
{
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
{
var typeValue = bindingContext.ValueProvider.GetValue("ModelType");
var type = Type.GetType((string)typeValue.ConvertTo(typeof(string)), true);
if (!typeof(Notification).IsAssignableFrom(type))
{
throw new InvalidCastException("Bad type");
}
var model = Activator.CreateInstance(type);
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
return model;
}
}
Source of initial question that sent me down this rabbit hole and code largely borrowed from: Methodology for passing a mix of: list<>, object and primitives to an ASP MVC controller action