3

我想了解 NancyFX 中的 DynamicDictionary,它看起来很酷。有谁知道博客文章或类似的文章,通过它的内部?

我需要一个属性包来传递对象,我不知道它们的内容,因为它们以 JSON 的形式来自我的系统外部。但是基于这些对象的内容,比如某些属性的存在,我需要做一些事情。

我可以传递动态对象,但我认为这有点太模糊了。真的不喜欢这样。

我需要嵌套字典来完全表示对象图。

4

2 回答 2

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

所以回到最初的问题:

是否有博客文章或任何文档:没有

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

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

你能告诉我如何使用它吗:不,但它应该不难。只需查看 Nancy 中的模型绑定即可弄清楚。这不是太难。


只是根据 OP 的回答进行编辑。

当您访问点符号时,继续点符号将仅适用于进一步的动态类型。

这意味着var由于使用的方式会导致异常,var并由dynamic编译器处理。

当你这样做时:

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

parametersis current dynamicand implements TryGetMember,这在内部查找值字典并尝试返回值。

当您将对象定义varperson变量时。编译器假定对象上存在之后的任何内容,因此它会nameperson变量上查找。

由于name不存在作为成员person它会抛出。

要解决此问题,必须将变量分配为dynamic。所以例子变成了:

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

这将起作用。

于 2015-04-06T08:33:07.790 回答
1

所以我开始使用 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;
}
于 2015-04-06T10:50:19.823 回答