webapi返回json格式优化

Posted 叶长种-.Net软件工程师

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了webapi返回json格式优化相关的知识,希望对你有一定的参考价值。

一、设置webapi返回json格式

  在App_Start下的WebApiConfig的注册函数Register中添加下面这代码

config.Formatters.Remove(config.Formatters.XmlFormatter);

 

二、设置返回Json键值统一为小写

   新建一个类并继承自DefaultContractResolver,重写ResolvePropertyName方法,

   

复制代码
 public class UnderlineSplitContractResolver : DefaultContractResolver
 {
     protected override string ResolvePropertyName(string propertyName)
     {
         //return CamelCaseToUnderlineSplit(propertyName);
         return propertyName.ToLower();
     }
 }
复制代码

在WebApiConfig.Register方法中添加配置代码

// 对 JSON 数据使用混合大小写。跟属性名同样的大小.输出
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new UnderlineSplitContractResolver();

三、在返回的JSON格式中出现两个很不开心的问题

看图:

第一个问题是为null的字符串,这里也返回了null,感觉返回""感觉好一点

第二个问题,lastupdate是时间格式,这种格式化看着有点不爽,如果是"2016-03-25 17:19:17"感觉就好点了

解决如下:

在解决第二个问题时我们新建的类UnderlineSplitContractResolver里面重写CreateProperties方法:

复制代码
 //解决API NULL 和时间格式问题
 protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
 {
     return type.GetProperties
.Select(p => { var jp = base.CreateProperty(p, memberSerialization); if (jp.PropertyType == typeof(System.String)) jp.ValueProvider = new NullToEmptyStringValueProvider(p); if (jp.PropertyType.ToString().Contains("System.DateTime")) jp.Converter = new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }; return jp; }).ToList(); }
复制代码
NullToEmptyStringValueProvider类继承IValueProvider,代码如下:
复制代码
    /// <summary>
    /// 解决返回json数据null问题
    /// </summary>
    public class NullToEmptyStringValueProvider : IValueProvider
    {
        PropertyInfo _MemberInfo;
        public NullToEmptyStringValueProvider(PropertyInfo memberInfo)
        {
            _MemberInfo = memberInfo;
        }
        public object GetValue(object target)
        {
            object result = _MemberInfo.GetValue(target);
            //if (result == null) 
            //    result = "";
            if (_MemberInfo.PropertyType == typeof(string) && result == null)
                result = "";
            return result;
        }
        public void SetValue(object target, object value)
        {
            _MemberInfo.SetValue(target, value);
        }
    }
复制代码

此时问题已经解决,返回的json如下:

看起来是不是舒服多了?

四、整理一下代码

 新建一个文件InitAPI.cs,代码如下:

复制代码
  public class InitAPI
    {
        public static void Init(HttpConfiguration config)
        {
            //HttpConfiguration config = GlobalConfiguration.Configuration;
            config.Formatters.Remove(config.Formatters.XmlFormatter);


            // 解决json序列化时的循环引用问题
            config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            // 对 JSON 数据使用混合大小写。驼峰式,但是是javascript 首字母小写形式.
            //config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new  CamelCasePropertyNamesContractResolver();
            // 对 JSON 数据使用混合大小写。跟属性名同样的大小.输出
            config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new UnderlineSplitContractResolver();
        }
    }

    public class UnderlineSplitContractResolver : DefaultContractResolver
    {


        protected override string ResolvePropertyName(string propertyName)
        {
            //return CamelCaseToUnderlineSplit(propertyName);
            return propertyName.ToLower();
        }
        private string CamelCaseToUnderlineSplit(string name)
        {
            return name.ToLower();
        }



        //解决API NULL 和时间格式问题
        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            return type.GetProperties()
                   .Select(p =>
                   {
                       var jp = base.CreateProperty(p, memberSerialization);
                       if (jp.PropertyType == typeof(System.String))
                           jp.ValueProvider = new NullToEmptyStringValueProvider(p);
                       if (jp.PropertyType.ToString().Contains("System.DateTime"))
                           jp.Converter = new IsoDateTimeConverter() { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
                       return jp;
                   }).ToList();
        }



    }
    /// <summary>
    /// 解决返回json数据null问题
    /// </summary>
    public class NullToEmptyStringValueProvider : IValueProvider
    {
        PropertyInfo _MemberInfo;
        public NullToEmptyStringValueProvider(PropertyInfo memberInfo)
        {
            _MemberInfo = memberInfo;
        }
        public object GetValue(object target)
        {
            object result = _MemberInfo.GetValue(target);
            //if (result == null) 
            //    result = "";
            if (_MemberInfo.PropertyType == typeof(string) && result == null)
                result = "";
            return result;
        }
        public void SetValue(object target, object value)
        {
            _MemberInfo.SetValue(target, value);
        }
    }
复制代码
在WebApiConfig中直接调用InitAPI.Init(config),代码如下:
复制代码
 public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API 配置和服务

            // Web API 路由
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
               name: "DefaultApi",
               routeTemplate: "api/{controller}/{id}",
               defaults: new { id = RouteParameter.Optional }
           );

            InitAPI.Init(config);
        }
    }
复制代码

 

结束

以上是关于webapi返回json格式优化的主要内容,如果未能解决你的问题,请参考以下文章

WebAPI返回JSON的正确格式

在WebApi中返回一个JSON格式的数据,如何到客户端就变了

webapi 返回json

WebAPI 如何以 JSON 格式填充空结果

.net中 webapi 返回结果为json格式

.net中 webapi 返回结果为json格式