. Net core 1.1.0 MVC controller receives Json strings (JObject object) (2), jsonjobject
. Net core 1.1.0 MVC controller receives Json strings (JObject object) (2)
. Net core 1.1.0 MVC controller receives Json strings (JObject object) (1)
In the previous article, the data submitted by Form key-value pairs is converted to Json for processing. Sometimes we directly submit the data using the Body string. We need to solve the value submission problem in the following two ways:
JObject
$ ('# Btn_add '). click (function (e) {var a =$ ('# tb_ments ments '). bootstrapTable ('getselection'); var post = "{'str1': 'foovalue', 'str2': 'barvalue'}"; // JSON. stringify (a); $. ajax ({type: "POST", url: "/Home/bout", contentType: "application/json", // dataType: "json ", // indicates the type of the returned value. data: post is not required, // equivalent to // data: "{'str1': 'foovalue', 'str2': 'barvalue '}", success: function (data) {// get data OK alert (JSON. toString (data ));}});});
JArray
$ ('# Btn_delete '). click (function (e) {var a =$ ('# tb_ments ments '). bootstrapTable ('getselection'); var post = JSON. stringify (a); $. ajax ({type: "POST", url: "/Home/About", contentType: "application/json", // dataType: "json ", // indicates the type of the returned value. data: post is not required, // equivalent to // data: "{[{'str1': 'foovalue', 'str2': 'barvalue '}, {'str1': 'foovalue', 'str2': 'barvalue'}]} ", success: function (data) {// obtain data OK alert (data. id + "--" + data. userName );}});});
In. net core, there is no ValueProvider used to obtain the Body value. compile one. This is a ValueProvider Based on the factory mode. First, the Code implements the IValueProviderFactory interface:
Public class evaluate: IValueProviderFactory {public Task CreateValueProviderAsync (ValueProviderFactoryContext controllerContext) {if (controllerContext = null) throw new evaluate ("controllerContext"); if (controllerContext. actionContext. httpContext. request. contentType = null) {return Task. completedTask;}; if (! ControllerContext. actionContext. httpContext. request. contentType. startsWith ("application/json", StringComparison. ordinalIgnoreCase) {return Task. completedTask; // It is not of the "application/json" type and cannot be handed over to the original.} var bodyText = string. empty; using (var reader = new StreamReader (controllerContext. actionContext. httpContext. request. body) {bodyText = reader. readToEnd (). trim (); // get the Body} if (string. isNullOrEmpty (bodyT Ext) {return Task. completedTask;} // null do not process else {// Add JObject ValueProviders to process the value controllerContext. valueProviders. add (new JObjectValueProvider (bodyText. endsWith ("]}")? // Whether the group is JArray. Parse (bodyText) as JContainer: // Jarray JObject. Parse (bodyText) as JContainer); // JObject} return Task. CompletedTask ;}}
Corresponding IValueProvider:
internal class JObjectValueProvider : IValueProvider { private JContainer _jcontainer; public JObjectValueProvider(JContainer jcontainer) { _jcontainer = jcontainer; } public bool ContainsPrefix(string prefix) { // return _jcontainer.SelectToken(prefix) != null; return true; } public ValueProviderResult GetValue(string key) { var jtoken = _jcontainer.SelectToken(""); if (jtoken == null) return ValueProviderResult.None; return new ValueProviderResult( jtoken.ToString(), CultureInfo.CurrentCulture); } }
Register in Startup:
Services. addMvc (options => {options. valueProviderFactories. add (new JObjectValueProviderFactory (); // value options. modelBinderProviders. insert (0, new JObjectModelBinderProvider (); // Add Jobject binding });
The newly added // Jarray type changes the Json string received by the. net core 1.1.0 MVC controller (JObject object) (1) JObjectModelBinderProvider
Public class JObjectModelBinderProvider: IModelBinderProvider {public IModelBinder GetBinder (ModelBinderProviderContext context) {if (context = null) throw new ArgumentNullException (nameof (context); if (context. metadata. modelType = (typeof (JObject) // supports JObject for both the Body and Form key-value pairs {return new JObjectModelBinder (context. metadata. modelType);} if (context. metadata. modelType = (typeof (JArray) // Jarray supports {return new JObjectModelBinder (context. metadata. modelType) ;}return null ;}}
You must also modify JObjectModelBinder to add support for JObject and JArray. You can also write
Public class JObjectModelBinder: IModelBinder {public JObjectModelBinder (Type type) {if (type = null) {throw new partition ("type") ;}} public Task BindModelAsync (ModelBindingContext bindingContext) {if (bindingContext = null) throw new ArgumentNullException ("bindingContext"); ValueProviderResult result = bindingContext. valueProvider. getValue (bindingContext. modelName); // call the value Valu EProvider try {if (bindingContext. modelType = typeof (JObject) {JObject obj = new JObject (); if (bindingContext. actionContext. httpContext. request. contentType = "application/json") // json {if (result. toString (). startsWith ("[") // is it a group? {Obj = (JObject) JArray. Parse (result. ToString (). First; // obtain the First value. BindingContext. result = (ModelBindingResult. success (obj); return Task. completedTask;} else {obj = JObject. parse (result. toString (); // not a direct group value} else // form {foreach (var item in bindingContext. actionContext. httpContext. request. form) {obj. add (new JProperty (item. key. toString (), item. value. toString () ;}} if (obj. count = 0) {bindingContext. modelState. tryAddModelError (bindingContext. modelN Ame, bindingContext. modelMetadata. modelBindingMessageProvider. valueMustNotBeNullAccessor (result. toString (); return Task. completedTask;} bindingContext. result = (ModelBindingResult. success (obj); return Task. completedTask;} if (bindingContext. modelType = typeof (JArray) {JArray obj = new JArray (); if (bindingContext. actionContext. httpContext. request. contentType. startsWith ("application/json", StringComparison. OrdinalIgnoreCase) // json {if (result. ToString (). StartsWith ("[") // is it a group? {JArray array = new JArray (); array = JArray. Parse (result. ToString (); // obtain the first value. BindingContext. result = (ModelBindingResult. success (array); return Task. completedTask;} if (obj. count = 0) {bindingContext. modelState. tryAddModelError (bindingContext. modelName, bindingContext. modelMetadata. modelBindingMessageProvider. valueMustNotBeNullAccessor (result. toString (); return Task. completedTask;} bindingContext. result = (ModelBindingResult. success (obj); return Task. completedT Ask;} return Task. CompletedTask;} catch (Exception exception) {if (! (Exception is FormatException) & (exception. InnerException! = Null) {exception = ExceptionDispatchInfo. capture (exception. innerException ). sourceException;} bindingContext. modelState. tryAddModelError (bindingContext. modelName, exception, bindingContext. modelMetadata); return Task. completedTask ;}}}
The Form key-value pair, JObject, and Jarry methods in the controller are the same as those in public IActionResult bout (JArray data)
There is a difference between the client, JObject, Jarry data must be specified: contentType: "application/json", // must have
When the json content is used as an array, the Controller receives JObject of only the first JObject.