如何在 javascript 扩展样式中扩展动态 C# 对象?
How to extend dynamic c# object in javascript extend style?
** 这是一个自我回答的问题,因为我找到了解决方案,但我没有在这里找到它 **
用例
来自 应用程序 A(C# 后端)的非明确定义的结构化数据必须传递给 应用程序 B(ASP.Net C# 应用程序,其中 SignalR 前端)使用 HTTP,它将使用 SignalR 简单地将消息传递给 javascript 客户端。
数据用于实时登录。
为什么不创建 classes?
因为传入的数据是可以变化的,还没有被Application B解析,所以两端的代码不能共享class(C#/JavaScript).
另外,我希望能够做这样的事情:
var foo = DynamicExtend(
new { propExtendedFromDynamic1 = true },
new { propExtendedFromDynamic2 = true }
);
string jsonText = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
dynamic unserializedFoo = JObject.Parse(jsonText);
使用 expando 对象
由于动态对象不易修改,所以需要使用ExpandoObject。
唯一的缺点是它无法完成具有其他动态属性的原始动态对象,并且仍然使用与 $.extend(true, {p1:1},{p2:2})
相同的引用(如果你知道 jQuery 你就会明白) .
public static dynamic DynamicExtend(params dynamic[] extendedItems)
{
if (extendedItems == null || extendedItems.Length == 0 || extendedItems[0] == null)
throw new Exception("Missing initial dynamic property");
if (extendedItems.Length == 1)
return extendedItems.First();
dynamic r = new ExpandoObject();
// We will need that casted value or the r[propertyName]="someValue" will fail
var dynamicReturnedEditable = (IDictionary<string, object>)r;
// For each dynamic object passed in
foreach (dynamic extensionHolder in extendedItems)
{
var expandoCase = extensionHolder as IDictionary<string, object>;
if (expandoCase == null)
{
// Pour chaque propriété
foreach (var property in ((object)extensionHolder).GetType().GetProperties())
{
// Faire la copie sur l'ExpandoObject (qui gère nativement le rajout de propriété) en utilisant les données extraites de l'objet dynamique
dynamicReturnedEditable[property.Name] = property.GetValue(extensionHolder, null);
}
}
else
{
foreach (var propertyName in expandoCase.Keys)
{
// Faire la copie sur l'ExpandoObject (qui gère nativement le rajout de propriété) en utilisant les données extraites de l'objet dynamique
dynamicReturnedEditable[propertyName] = expandoCase[propertyName];
}
}
}
return r;
}
注意:例如,它不支持由 JObject.Parse(jsonText);
产生的参数,因为它必须从中读取属性。
** 这是一个自我回答的问题,因为我找到了解决方案,但我没有在这里找到它 **
用例
来自 应用程序 A(C# 后端)的非明确定义的结构化数据必须传递给 应用程序 B(ASP.Net C# 应用程序,其中 SignalR 前端)使用 HTTP,它将使用 SignalR 简单地将消息传递给 javascript 客户端。
数据用于实时登录。
为什么不创建 classes? 因为传入的数据是可以变化的,还没有被Application B解析,所以两端的代码不能共享class(C#/JavaScript).
另外,我希望能够做这样的事情:
var foo = DynamicExtend(
new { propExtendedFromDynamic1 = true },
new { propExtendedFromDynamic2 = true }
);
string jsonText = Newtonsoft.Json.JsonConvert.SerializeObject(foo);
dynamic unserializedFoo = JObject.Parse(jsonText);
使用 expando 对象
由于动态对象不易修改,所以需要使用ExpandoObject。
唯一的缺点是它无法完成具有其他动态属性的原始动态对象,并且仍然使用与 $.extend(true, {p1:1},{p2:2})
相同的引用(如果你知道 jQuery 你就会明白) .
public static dynamic DynamicExtend(params dynamic[] extendedItems)
{
if (extendedItems == null || extendedItems.Length == 0 || extendedItems[0] == null)
throw new Exception("Missing initial dynamic property");
if (extendedItems.Length == 1)
return extendedItems.First();
dynamic r = new ExpandoObject();
// We will need that casted value or the r[propertyName]="someValue" will fail
var dynamicReturnedEditable = (IDictionary<string, object>)r;
// For each dynamic object passed in
foreach (dynamic extensionHolder in extendedItems)
{
var expandoCase = extensionHolder as IDictionary<string, object>;
if (expandoCase == null)
{
// Pour chaque propriété
foreach (var property in ((object)extensionHolder).GetType().GetProperties())
{
// Faire la copie sur l'ExpandoObject (qui gère nativement le rajout de propriété) en utilisant les données extraites de l'objet dynamique
dynamicReturnedEditable[property.Name] = property.GetValue(extensionHolder, null);
}
}
else
{
foreach (var propertyName in expandoCase.Keys)
{
// Faire la copie sur l'ExpandoObject (qui gère nativement le rajout de propriété) en utilisant les données extraites de l'objet dynamique
dynamicReturnedEditable[propertyName] = expandoCase[propertyName];
}
}
}
return r;
}
注意:例如,它不支持由 JObject.Parse(jsonText);
产生的参数,因为它必须从中读取属性。