自己写实体可以完美解决这个问题。(支持时间格式自定义)
用匿名类型也可以。
设置上下文方法如下:
(jz为数据库上下文对象)
jz.Configuration.ProxyCreationEnabled = false;
jz.Configuration.LazyLoadingEnabled = false;
不用这个的原因是Virtual属性也会生成。(只是占个位,[]里面没内容,但看着不爽)
我采用的方法是过滤掉Virtual属性的方法:
一个基于Json.net的类
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
namespace AceepSystem.Models.Help
{
public class JsonForEF : DefaultContractResolver
{
string[] props = null;
bool retain;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="props">传入的属性数组</param>
/// <param name="retain">true:表示props是需要保留的字段 false:表示props是要排除的字段</param>
public JsonForEF(string[] props, bool retain = true)
{
//指定要序列化属性的清单
this.props = props;
this.retain = retain;
}
protected override IList<JsonProperty> CreateProperties(Type type,
MemberSerialization memberSerialization)
{
IList<JsonProperty> list =
base.CreateProperties(type, memberSerialization);
//只保留清单有列出的属性
return list.Where(p =>
{
if (retain)
{
return props.Contains(p.PropertyName);
}
else
{
return !props.Contains(p.PropertyName);
}
}).ToList();
}
public static string[] GetVirtualList<T>()
{
var stringType = typeof(T);
var props = stringType.GetProperties();
List<string> test = new List<string>();
foreach (var prop in props)
{
if (prop.GetAccessors()[0].IsVirtual)
{
test.Add(prop.Name);
}
}
return test.ToArray();
}
public static JsonSerializerSettings GetJsonConfig<T>()
{
JsonSerializerSettings jsetting = new JsonSerializerSettings();//过滤掉ef中的导航属性,无残留...
jsetting.ContractResolver = new JsonForEF(
JsonForEF.GetVirtualList<T>()//泛型方法传入当前要序列化的类型
, false);//false为要排除的属性,true为要保留的属性(第一个参数为string[])
jsetting.Converters.Add(new MyDateTimeConvertor());
return jsetting;
}
public class MyDateTimeConvertor : DateTimeConverterBase
{
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return DateTime.Parse(reader.Value.ToString());
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(((DateTime)value).ToString("yyyy/MM/dd HH:mm"));
}
}
}
}
和一个对PropertyInfo的扩展方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
namespace AceepSystem.Models.Help
{
public static class Virtual_Help
{
public static bool? IsVirtual(this PropertyInfo self)
{
if (self == null)
throw new ArgumentNullException("self");
bool? found = null;
foreach (MethodInfo method in self.GetAccessors())
{
if (found.HasValue)
{
if (found.Value != method.IsVirtual)
return null;
}
else
{
found = method.IsVirtual;
}
}
return found;
}
}
}
使用方法如下
string json = JsonConvert.SerializeObject(
list,
Formatting.Indented,
JsonForEF.GetJsonConfig<dic_attribution>()
);//转C#对象为Json数据