NancyFx 动态词典
NancyFx DynamicDictionary
我正在尝试了解 NancyFX 中的 DynamicDictionary,它看起来很酷。有人知道博客 post 或类似的博客吗?
我需要一个 propertybag 来传递对象,我不知道对象的内容,因为它们作为 JSON 来自我的系统之外。但是根据这些对象的内容,比如我需要做的某些属性的存在。
我可以只传递动态对象,但我认为这有点太模糊了。不太喜欢。
我需要嵌套字典来完整表示对象图。
动态字典只是一个带有字典的 ExpandoObject。所以它仍然可以像字典一样访问。
例如,在 MVC 中,您可以像这样访问表单属性:
var name = Request["name"];
或
var name = Request.Form["name"];
当 Nancy 收到请求时,您可以通过点符号访问它。或者通过 class 索引器。
var name = parameters.name;
var name = parameters["name"];
当您发送查询字符串或表单名称的值不能用点表示法时,这很方便。
var firstName = parameters["first-name"];
值也是动态的,因此它可以由嵌套对象组成。这使您可以执行以下操作:
var firstName = parameters.contact.firstname;
因此,如果您将 JSON 有效负载传递给请求,那么您可以使用点表示法访问整个结构。
但是您可能会发现大多数使用 Nancy 的开发人员只使用此方法访问 Route 值或 QueryString 值。
Get["/products/{id:int}/"] = parameters => {
int id = parameters.id;
};
所以回到最初的问题:
是否有博客post或任何doco:没有。
为什么存在:对于糖语法。
我可以用它做我想做的事吗: 绝对可以!
你能告诉我如何使用它吗: 不,但是应该不难。只需查看 Nancy 中的模型绑定即可弄清楚。不难。
只是根据 OP 的回答进行的编辑。
当您访问点表示法时,继续的点表示法将仅适用于更多的动态类型。
这意味着使用 var
将导致异常,因为编译器处理 var
和 dynamic
的方式。
当你这样做时:
var person = parameters.person;
var name = person.name;
parameters
当前是 dynamic
并实现了 TryGetMember
,这在内部查找值字典并尝试 return 值。
当您为 person
变量定义对象为 var
时。编译器假定对象上存在之后的任何内容,因此它在 person
变量上查找 name
。
由于 name
不作为 person
的成员存在,它将抛出。
要解决此问题,必须将变量分配为 dynamic
。所以例子变成:
dynamic person = parameters.person;
var name = person.name;
这会起作用。
所以我开始使用 DynamicDictionary,它非常酷且易于使用。现在只有一件事让我烦恼。那就是如果我嵌套 DynamicDictionaries.
看下面的例子:
private void TestNestedDynamicDictionary()
{
dynamic dictionary = new DynamicDictionary();
dynamic nestedDictionary = new DynamicDictionary();
nestedDictionary.Add("name", "Peter");
dictionary.Add("person", nestedDictionary);
var person = dictionary.person;
var name = person.name;
Console.WriteLine(name);
}
尝试使用 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
访问 person.name
时失败:
DynamicDictionaryValue' does not contain a definition for 'name'
如果我像这样进行显式转换就可以了。
var person = (DynamicDictionary)dictionary.person;
任何关于我如何让它表现得像开箱即用的 DynamicDictionary 的输入...除了在返回之前检查 DynamicDictionaryValue 并在那里进行转换,我认为这很混乱。
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
object value;
if (!dictionary.TryGetValue(binder.Name, out value))
{
result = new DynamicDictionaryValue(null);
return true;
}
var dictVal = value as DynamicDictionaryValue;
if (null != dictVal && dictVal.Value is DynamicDictionary)
{
result = dictVal.Value;
}
else
{
result = value;
}
return true;
}
我正在尝试了解 NancyFX 中的 DynamicDictionary,它看起来很酷。有人知道博客 post 或类似的博客吗?
我需要一个 propertybag 来传递对象,我不知道对象的内容,因为它们作为 JSON 来自我的系统之外。但是根据这些对象的内容,比如我需要做的某些属性的存在。
我可以只传递动态对象,但我认为这有点太模糊了。不太喜欢。
我需要嵌套字典来完整表示对象图。
动态字典只是一个带有字典的 ExpandoObject。所以它仍然可以像字典一样访问。
例如,在 MVC 中,您可以像这样访问表单属性:
var name = Request["name"];
或
var name = Request.Form["name"];
当 Nancy 收到请求时,您可以通过点符号访问它。或者通过 class 索引器。
var name = parameters.name;
var name = parameters["name"];
当您发送查询字符串或表单名称的值不能用点表示法时,这很方便。
var firstName = parameters["first-name"];
值也是动态的,因此它可以由嵌套对象组成。这使您可以执行以下操作:
var firstName = parameters.contact.firstname;
因此,如果您将 JSON 有效负载传递给请求,那么您可以使用点表示法访问整个结构。
但是您可能会发现大多数使用 Nancy 的开发人员只使用此方法访问 Route 值或 QueryString 值。
Get["/products/{id:int}/"] = parameters => {
int id = parameters.id;
};
所以回到最初的问题:
是否有博客post或任何doco:没有。
为什么存在:对于糖语法。
我可以用它做我想做的事吗: 绝对可以!
你能告诉我如何使用它吗: 不,但是应该不难。只需查看 Nancy 中的模型绑定即可弄清楚。不难。
只是根据 OP 的回答进行的编辑。
当您访问点表示法时,继续的点表示法将仅适用于更多的动态类型。
这意味着使用 var
将导致异常,因为编译器处理 var
和 dynamic
的方式。
当你这样做时:
var person = parameters.person;
var name = person.name;
parameters
当前是 dynamic
并实现了 TryGetMember
,这在内部查找值字典并尝试 return 值。
当您为 person
变量定义对象为 var
时。编译器假定对象上存在之后的任何内容,因此它在 person
变量上查找 name
。
由于 name
不作为 person
的成员存在,它将抛出。
要解决此问题,必须将变量分配为 dynamic
。所以例子变成:
dynamic person = parameters.person;
var name = person.name;
这会起作用。
所以我开始使用 DynamicDictionary,它非常酷且易于使用。现在只有一件事让我烦恼。那就是如果我嵌套 DynamicDictionaries.
看下面的例子:
private void TestNestedDynamicDictionary()
{
dynamic dictionary = new DynamicDictionary();
dynamic nestedDictionary = new DynamicDictionary();
nestedDictionary.Add("name", "Peter");
dictionary.Add("person", nestedDictionary);
var person = dictionary.person;
var name = person.name;
Console.WriteLine(name);
}
尝试使用 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException
访问 person.name
时失败:
DynamicDictionaryValue' does not contain a definition for 'name'
如果我像这样进行显式转换就可以了。
var person = (DynamicDictionary)dictionary.person;
任何关于我如何让它表现得像开箱即用的 DynamicDictionary 的输入...除了在返回之前检查 DynamicDictionaryValue 并在那里进行转换,我认为这很混乱。
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
object value;
if (!dictionary.TryGetValue(binder.Name, out value))
{
result = new DynamicDictionaryValue(null);
return true;
}
var dictVal = value as DynamicDictionaryValue;
if (null != dictVal && dictVal.Value is DynamicDictionary)
{
result = dictVal.Value;
}
else
{
result = value;
}
return true;
}