2015-04-05 56 views
2

我想了解NancyFX中的DynamicDictionary,它看起來很酷。有沒有人知道博客文章或類似的內容,通過它的內部?NancyFx DynamicDictionary

我需要一個propertybag來傳遞對象,我不知道它們的內容,因爲它們來自我的系統之外的JSON。但基於這些對象的內容,例如存在某些屬性,我需要做些東西。

我只能傳遞動態對象,但是我覺得這有點太模糊。不太喜歡那樣。

我需要嵌套字典,以完全表示對象圖。

+0

您是否檢查過[源文件](https://github.com/NancyFx/Nancy/blob/master/src/Nancy/DynamicDictionary.cs)? – 2015-04-05 21:30:13

+0

是的,我有...似乎做這項工作。我只是想了解它的目的是什麼。如果它不是爲了解決我的問題,我不想使用它。 – 2015-04-05 23:18:09

回答

6

動態字典只是一個帶有字典的ExpandoObject。所以它仍然可以像字典一樣訪問。

例如,在MVC訪問表單屬性,像這樣:

var name = Request["name"]; 

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

當一個請求進入南希您可以通過點符號訪問它。或者通過類索引器。

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:都能跟得上。

它爲什麼存在:對於sugar語法。

我可以把它用於我想要的:絕對是!

你能告訴我如何使用它:不,但它不應該很難。只要看看南希的模型綁定就知道了。這並不難。


只是基於OP的答案編輯。

當您訪問點符號時,續點符號只適用於其他動態類型。

這意味着使用var將會導致異常,因爲編譯器會處理vardynamic

當你這樣做:

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

parameters目前dynamic,並實現TryGetMember,這在內部查找值的字典,並試圖返回值。

當您爲person變量定義對象爲var時。編譯器假定該對象之後的任何內容都存在,因此它在person變量上查找name

由於name不存在作爲person成員它會拋出。

要解決此問題,必須將變量分配爲dynamic。因此,該示例變爲:

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

這會起作用。

+0

謝謝菲爾!我想了很多,昨晚玩了一大堆。我不是創建嵌套的動態,而是將對象嵌套爲DynamicDictionary,以便嵌套字典。這給我一點頭痛,因爲我必須將它從動態轉換爲DynamicDictionary,以便將其實際用作DynamicDictionary。我會看看模型綁定。 NancyFx的代碼結構合理,易於閱讀。非常感動! – 2015-04-06 09:41:52

0

因此,我開始使用DynamicDictionary,它非常酷並且易於使用。現在只有一件事情讓我感到害怕。那就是如果我嵌套DynamicDictionaries。

請看下面的例子:

DynamicDictionaryValue' does not contain a definition for 'name' 

如果我只是做一個明確的轉換這樣的工作原理:

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時失敗。

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

因爲'var'不是動態的。如果您將代碼更改爲'dynamic person = dictionary.person;',那麼您可以訪問'person.name' :)'TryGetMember'只對定義爲'dynamic'的類型起作用,當您使用' var'。 – Phill 2015-04-06 11:49:48

+0

請參閱編輯我的答案以獲取更多信息。 – Phill 2015-04-06 11:56:13

+0

當然...爲什麼我沒有看到。但是,如果我想使用字典部分,並訪問鍵集合,那麼我必須將其轉換爲DynamicDictionary。 – 2015-04-06 21:25:39