0
\$\begingroup\$

I wrote this to have ASP.NET MVC be able to respond as a web API as well as the normal MVC Razor pages. I wanted Newtonsoft deserialization for models based on already parsed values:

public class CustomJsonModelBinder<T> : DefaultModelBinder where T : class { public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) { if (!controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase)) { return base.BindModel(controllerContext, bindingContext); } if (bindingContext.ModelType != typeof(T)) { return base.BindModel(controllerContext, bindingContext); } //Get the DictionaryValueProvider, the one with all the JSON values already read if (!(bindingContext.ValueProvider is ValueProviderCollection valueProviders)) { return base.BindModel(controllerContext, bindingContext); } DictionaryValueProvider<object> dictionaryValueProvider = valueProviders.FirstOrDefault(x => x.GetType() == typeof(DictionaryValueProvider<object>)) as DictionaryValueProvider<object>; if (dictionaryValueProvider == null) { return base.BindModel(controllerContext, bindingContext); } /* get the values and build a temp object for them for proper Newtonsoft Deserialization, which can have formatting attributes and others on the target class */ Dictionary<string, object> valueDictionary = new Dictionary<string, object>(); foreach (var entry in dictionaryValueProvider.GetKeysFromPrefix("")) { var value = bindingContext.ValueProvider.GetValue(entry.Key); valueDictionary.Add(entry.Key, value.RawValue); } string dictionaryInJson = JsonConvert.SerializeObject(valueDictionary); return string.IsNullOrEmpty(dictionaryInJson) ? base.BindModel(controllerContext, bindingContext) : JsonConvert.DeserializeObject<T>(dictionaryInJson); } } 

Usage:

public ActionResult Post(int id,[ModelBinder(typeof(CustomJsonModelBinder<AppointmentRequest>))] AppointmentRequest model) 

I don't like having to repeat the model type twice, but I see no other convenient way.

Please let me know your thoughts!

\$\endgroup\$
1
  • \$\begingroup\$implement IModelBinderProvider to get rid of the ModelBinder attribute. read more\$\endgroup\$
    – iSR5
    CommentedMar 13 at 11:48

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.