程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .net core 1.1.0 MVC 控制器接收Json字串 (JObject對象) (二),jsonjobject

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

編輯:關於.NET

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


.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。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved