NancyFx DynamicDictionary

时间:2015-04-05 18:48:33

标签: c# dynamic nancy propertybag

我试图了解NancyFX中的DynamicDictionary,它看起来很酷。有没有人知道一篇博文或类似文章,它是通过内部的?

我需要一个propertybag来传递对象,我不知道它们的内容,因为它们来自我的系统之外作为JSON。但是基于这些对象的内容,例如我需要做某些属性的存在。

我可以传递动态对象,但我认为这有点过于模糊。不喜欢那样。

我需要嵌套字典,以完全代表对象图。

2 个答案:

答案 0 :(得分:7)

动态字典只是一个包含字典的ExpandoObject。所以它仍然可以像字典一样被访问。

例如,在MVC中,您可以访问Form属性,如下所示:

var name = Request["name"];

var name = Request.Form["name"];

当请求进入Nancy时,您可以通过点表示法访问它。或者通过类索引器。

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;
};

回到最初的问题:

是否有博文或任何doco:没有。

为什么存在:对于糖语法。

我可以将它用于我想要的东西:是绝对的!

你能告诉我如何使用它吗?没有,但它应该不难。只要看看南希的模型绑定就可以搞清楚。这不是太难。


根据OP的答案进行编辑。

当您访问点表示法时,续点符号仅适用于其他动态类型。

这意味着使用var会导致异常,因为编译器处理vardynamic的方式。

当你这样做时:

var person = parameters.person;
var name = person.name;

parameters目前是dynamic并实现TryGetMember,这会在内部查找值字典并尝试返回值。

var变量的对象定义为person时。编译器假定对象之后存在任何内容,因此它在name变量上查找person

由于name不会作为person的成员存在,因此会抛出。{/ p>

要解决此问题,必须将变量指定为dynamic。所以这个例子就变成了:

dynamic person = parameters.person;
var name = person.name;

这样可行。

答案 1 :(得分:0)

所以我开始使用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);
}

尝试使用person.name访问'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException时失败:

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;
}