Tim*_*Dog 93 javascript c# asp.net-mvc json expandoobject
我非常喜欢在运行ExpandoObject
时编译服务器端动态对象,但是在JSON序列化期间我遇到了麻烦.首先,我实例化对象:
dynamic expando = new ExpandoObject();
var d = expando as IDictionary<string, object>;
expando.Add("SomeProp", SomeValueOrClass);
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.在我的MVC控制器中,我想将其作为JsonResult发送,所以我这样做:
return new JsonResult(expando);
Run Code Online (Sandbox Code Playgroud)
这将JSON序列化到下面,由浏览器使用:
[{"Key":"SomeProp", "Value": SomeValueOrClass}]
Run Code Online (Sandbox Code Playgroud)
但是,我真正喜欢的是看到这个:
{SomeProp: SomeValueOrClass}
Run Code Online (Sandbox Code Playgroud)
我知道我可以实现这个,如果我使用dynamic
而不是ExpandoObject
- JsonResult
能够将dynamic
属性和值序列化为单个对象(没有Key或Value业务),但我需要使用的原因ExpandoObject
是因为我不知道所有的直到运行时我想要的对象属性,据我所知,我不能动态地添加属性dynamic
而不使用ExpandoObject
.
我可能不得不在我的javascript中筛选"关键","价值"业务,但我希望在将其发送给客户之前解决这个问题.谢谢你的帮助!
Mik*_*nen 67
使用JSON.NET,您可以调用SerializeObject来"展平"expando对象:
dynamic expando = new ExpandoObject();
expando.name = "John Smith";
expando.age = 30;
var json = JsonConvert.SerializeObject(expando);
Run Code Online (Sandbox Code Playgroud)
将输出:
{"name":"John Smith","age":30}
Run Code Online (Sandbox Code Playgroud)
在ASP.NET MVC控制器的上下文中,可以使用Content-method返回结果:
public class JsonController : Controller
{
public ActionResult Data()
{
dynamic expando = new ExpandoObject();
expando.name = "John Smith";
expando.age = 30;
var json = JsonConvert.SerializeObject(expando);
return Content(json, "application/json");
}
}
Run Code Online (Sandbox Code Playgroud)
小智 36
您还可以创建一个特殊的JSONConverter,它只适用于ExpandoObject,然后在JavaScriptSerializer的实例中注册它.这样你就可以序列化expando的数组,expando对象的组合和...直到找到另一种没有正确序列化的对象("你想要的方式"),然后你创建另一个转换器,或者添加另一个类型到这个.希望这可以帮助.
using System.Web.Script.Serialization;
public class ExpandoJSONConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
var result = new Dictionary<string, object>();
var dictionary = obj as IDictionary<string, object>;
foreach (var item in dictionary)
result.Add(item.Key, item.Value);
return result;
}
public override IEnumerable<Type> SupportedTypes
{
get
{
return new ReadOnlyCollection<Type>(new Type[] { typeof(System.Dynamic.ExpandoObject) });
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用转换器
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new JavaScriptConverter[] { new ExpandoJSONConverter()});
var json = serializer.Serialize(obj);
Run Code Online (Sandbox Code Playgroud)
ajb*_*ajb 25
以下是我为实现您所描述的行为所做的工作:
dynamic expando = new ExpandoObject();
expando.Blah = 42;
expando.Foo = "test";
...
var d = expando as IDictionary<string, object>;
d.Add("SomeProp", SomeValueOrClass);
// After you've added the properties you would like.
d = d.ToDictionary(x => x.Key, x => x.Value);
return new JsonResult(d);
Run Code Online (Sandbox Code Playgroud)
成本是您在序列化之前制作数据的副本.
Tim*_*Dog 11
我通过编写一个将ExpandoObject转换为JSON字符串的扩展方法解决了这个问题:
public static string Flatten(this ExpandoObject expando)
{
StringBuilder sb = new StringBuilder();
List<string> contents = new List<string>();
var d = expando as IDictionary<string, object>;
sb.Append("{");
foreach (KeyValuePair<string, object> kvp in d) {
contents.Add(String.Format("{0}: {1}", kvp.Key,
JsonConvert.SerializeObject(kvp.Value)));
}
sb.Append(String.Join(",", contents.ToArray()));
sb.Append("}");
return sb.ToString();
}
Run Code Online (Sandbox Code Playgroud)
这使用了优秀的Newtonsoft库.
然后JsonResult看起来像这样:
return JsonResult(expando.Flatten());
Run Code Online (Sandbox Code Playgroud)
这将返回给浏览器:
"{SomeProp: SomeValueOrClass}"
Run Code Online (Sandbox Code Playgroud)
我可以在javascript中使用它(在这里引用):
var obj = JSON.parse(myJsonString);
Run Code Online (Sandbox Code Playgroud)
我希望这有帮助!
我能够使用JsonFx解决同样的问题.
dynamic person = new System.Dynamic.ExpandoObject();
person.FirstName = "John";
person.LastName = "Doe";
person.Address = "1234 Home St";
person.City = "Home Town";
person.State = "CA";
person.Zip = "12345";
var writer = new JsonFx.Json.JsonWriter();
return writer.Write(person);
Run Code Online (Sandbox Code Playgroud)
输出:
{"FirstName":"John","LastName":"Doe","Address":"1234 Home St","City":"Home Town","State":"CA","Zip":"12345 "}