【发布时间】:2017-05-12 12:47:05
【问题描述】:
在 Web API 中,我创建了一个自定义 MediaTypeFormatter 来创建具有特定模式的 JSON 输出,这使得标准序列化不适合。并不是说上面的上下文可能是相关的,但我需要使用我指定的模式将对象和 IEnumerable 转换为 JSON。
在伪代码中:
If object is a collection
foreach item in collection
Write the name/type of the item (will be same for all)
foreach property of item
Write the property name, type, and value
Else
foreach property of object
Write the property name, type, and value
我最感兴趣的部分是通过反射获取类属性名称/值。
例如,这是从控制器发送的:
return new MyPerson { .FirstName = "Bob", .DateOfBirth = Convert.ToDateTime("1979-03-01") }
...将输出为(粗略的示例,因为 JSON 很容易更改以制作必要的架构):
{ "MyPerson" : {"FirstName": {"value": "Bob", "Type": "string"}}, "DateOfBirth": {"value": "1979-03-01", "Type": "date"}}
同样,一个集合将被迭代以产生类似的输出:
return new IEnumerable<Foo>() {
new Foo() { Param1 = "aaa", Param2 = "bbb" },
new Foo() { Param1 = "ccc", Param2 = "ddd" }
}
...生产
{ "FooCollection": [
{ "Foo" : {"Param1": {"value": "aaa", "Type": "string"}}, {"Param2": {"value": "bbb", "Type": "string"}} },
{ "Foo" : {"Param1": {"value": "ccc", "Type": "string"}}, {"Param2": {"value": "ddd", "Type": "string"}} }
]}
我尝试消化许多与此挑战相关的其他示例 (1,2),但我正在努力适应它们。这是我设法得到的:
private void WriteStream(Type type, object value, Stream stream, HttpContentHeaders contentHeaders)
{
using (StringWriter _stringWriter = new StringWriter()) {
if (!(value is ICollection))
{
foreach (PropertyInfo p in value.GetProperties())
{
_stringWriter.Write(GetPropertyData(p));
}
}
else
{
foreach (object o in value)
{
foreach (PropertyInfo p in o.GetProperties())
{
_stringWriter.Write(GetPropertyData(p));
}
}
}
// output omitted for brevity...
}
}
public function GetPropertyData(PropertyInfo p) {
return string.Format("{name: '{0}', type: '{1}', value: '{2}'},",
p.Name,
p.PropertyType.ToString(),
p.GetValue(p).ToString())
}
【问题讨论】:
-
"写属性名、类型和值" - 我在你的 Json 示例中看不到类型。另外,如果属性不是基本类型(int、float、string 等)怎么办?
-
抱歉,RTFM 过载让我头晕目眩。修改后的问题。所有属性类型都是基本的(字符串、int、double 或 bool),尽管我很想知道如果它们不是基本类型该怎么办(尽管可能是另一个问题)
-
实用程序可用于从 C# 类或 JSON 生成 JSON 模式。我觉得你在这里有点想重新发明轮子。
-
你能举一个这样的例子吗?我已经使用 NewtonSoft et al 进行一般序列化,但在这种情况下,模式必须是明确的,并且不是标准的。 JSON 生成不是问题,而是如何使用反射检查对象。
标签: c# .net reflection asp.net-apicontroller