.net core 1.1.0 MVC 控制器接收Json字串 (JObject對象) (二)

來源:互聯網
上載者:User

標籤:指定   home   value   amp   .net   lstat   select   first   ref   

.net core 1.1.0 MVC 控制器接收Json字串 (JObject對象) (二)

 

.net core 1.1.0 MVC 控制器接收Json字串 (JObject對象) (一)

上一篇主要是以Form索引值對提交的資料,轉為Json方式處理,有時我們直接以Body字串提交,我們要解決以下兩種方式提交的取值問題:

JObject

$(‘#btn_add‘).click(function (e) {        var a = $(‘#tb_departments‘).bootstrapTable(‘getSelections‘);        var post = "{‘str1‘:‘foovalue‘, ‘str2‘:‘barvalue‘}";// JSON.stringify(a);        $.ajax({            type: "POST",            url: "/Home/bout",            contentType: "application/json",//必須有            dataType: "json", //表示傳回值類型,不必須            data: post,//相當於 //data: "{‘str1‘:‘foovalue‘, ‘str2‘:‘barvalue‘}",            success: function (data) {                //擷取資料ok           alert(JSON.toString(data));            }        });    });

 JArray

 

 $(‘#btn_delete‘).click(function (e) {        var a = $(‘#tb_departments‘).bootstrapTable(‘getSelections‘);        var post = JSON.stringify(a);        $.ajax({            type: "POST",            url: "/Home/About",          contentType: "application/json",//必須有            dataType: "json", //表示傳回值類型,不必須            data: post,//相當於 //data: "{[{‘str1‘:‘foovalue‘, ‘str2‘:‘barvalue‘},{‘str1‘:‘foovalue‘, ‘str2‘:‘barvalue‘}]}",            success: function (data) {                //擷取資料ok              alert(data.id + "--" +data.userName);            }        });    });

 

在.net core 中沒有用於取Body值的ValueProvider,編一個,這是基於原廠模式的ValueProvider,先上代碼 實現IValueProviderFactory介面:

 public class JObjectValueProviderFactory : IValueProviderFactory    {        public Task CreateValueProviderAsync(ValueProviderFactoryContext controllerContext)        {            if (controllerContext == null) throw new ArgumentNullException("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;//不是"application/json"類型不處理交給原有的            }            var bodyText = string.Empty;            using (var reader = new StreamReader(controllerContext.ActionContext.HttpContext.Request.Body))            {                bodyText = reader.ReadToEnd().Trim();//取得Body            }            if (string.IsNullOrEmpty(bodyText)) { return Task.CompletedTask; }//為空白不處理            else            {//添加JObject一ValueProviders以便處理值                controllerContext.ValueProviders.Add(                new JObjectValueProvider(bodyText.EndsWith("]}") ?//是不是組            JArray.Parse(bodyText) as JContainer ://是Jarray            JObject.Parse(bodyText) as JContainer));// JObject            }            return Task.CompletedTask;        }    }

對應的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);        }    }

 在Startup中註冊:

 services.AddMvc(options =>               {                   options.ValueProviderFactories.Add(new JObjectValueProviderFactory());//取值                   options.ModelBinderProviders.Insert(0, new JObjectModelBinderProvider());//加入Jobject綁定               });

 由於新增//Jarray類型對.net core 1.1.0 MVC 控制器接收Json字串 (JObject對象) (一)   JObjectModelBinderProvider做了改動

 public class JObjectModelBinderProvider : IModelBinderProvider    {        public IModelBinder GetBinder(ModelBinderProviderContext context)        {            if (context == null) throw new ArgumentNullException(nameof(context));            if (context.Metadata.ModelType == (typeof(JObject)))//同時支Body持資料JObject,和Form索引值對            {                return new JObjectModelBinder(context.Metadata.ModelType);            }            if (context.Metadata.ModelType == (typeof(JArray)))//Jarray支援            {                return new JObjectModelBinder(context.Metadata.ModelType);            }            return null;        }    }

 同樣也必須對JObjectModelBinder相應修改以增加對JObject,JArray支援,當然也可以另外寫

 public class JObjectModelBinder : IModelBinder    {        public JObjectModelBinder(Type type)        {            if (type == null)            {                throw new ArgumentNullException("type");            }        }        public Task BindModelAsync(ModelBindingContext bindingContext)        {            if (bindingContext == null) throw new ArgumentNullException("bindingContext");            ValueProviderResult result = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);//調用取值 ValueProvider            try            {                if (bindingContext.ModelType == typeof(JObject))                {                    JObject obj = new JObject();                    if (bindingContext.ActionContext.HttpContext.Request.ContentType == "application/json")//json                    {                        if (result.ToString().StartsWith("["))//是否是組?                        {                            obj =(JObject) JArray.Parse(result.ToString()).First;//取首值。                            bindingContext.Result = (ModelBindingResult.Success(obj));                            return Task.CompletedTask;                        }                        else                        {                            obj = JObject.Parse(result.ToString());//不是組直接取值                        }                    }                    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.ModelName, 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("["))//是否是組?                        {                            JArray array = new JArray();                            array = JArray.Parse(result.ToString());//取首值。                            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.CompletedTask;                }                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;            }        }    }


控制器寫法Form索引值對、JObject、Jarry方式一樣   public IActionResult bout(JArray data)

 

在客戶用戶端有區別,JObject、Jarry資料必須指定: contentType: "application/json",//必須有

當以json內容為數組時提交,控制器接收類型為JObject,只取第一個JObject。

.net core 1.1.0 MVC 控制器接收Json字串 (JObject對象) (二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.