2011-08-30 33 views
7

我最近在爲客戶實現JSON解決方案時遇到了一個問題。如果操作參數名稱與模型的屬性名稱匹配,則綁定器無法綁定任何屬性。MVC3 Json綁定錯誤?

一個例子:

控制器人民

public ActionResult SetEmails(Person emails){ 
    ... 
    return Content(""); 
} 

因爲參數名被稱爲「電子郵件」以及所謂的「電子郵件」 ..粘結劑失敗Person模型的屬性名相匹配,但不給任何指示,爲什麼..

他們有一個叫做Person

public class Person { 
    public string Name { get; set; } 
    public List<string> Emails { get; set; } 

    public Person() { 
     Emails = new List<string>(); 
    } 
} 
模型

這是一個錯誤,還是一個'功能'?

就像一個側面說明,我的問題更多的是關於如何參數名稱可能會導致活頁夾衝突?這個名字應該不重要,因爲它是定義它的模式以匹配json數據的類類型。爲什麼綁定器會關心你命名的參數或者它是否與參數本身的類類型中的屬性名稱匹配?

+4

你可以發佈調用js代碼,或者至少是你提交的JSON嗎? –

+0

json將是: {「Name」:「John」,「Emails」:[「[email protected]」,「test2 @ test。com)「}} json很好,正如我所說的,一旦我將Email參數名稱從Emails(匹配模型屬性名稱)更改爲任何不匹配,它的工作..我只是覺得它很有趣,不知道爲什麼這不應該工作,或者至少拋出一個異常,而不是一個具有空屬性值的實例化類!? – Mike

回答

2

問題在於,你的字典中有一個含糊不清的問題,兩個元素都被命名爲「emails」(儘管有不同的外殼)。 DefaultModelBinder無法解決此歧義。 (1)如果傳回整個人物模型,將頂層元素的名稱更改爲「person」(這在給定上下文的情況下更有意義),這將消除模糊性,並允許綁定按預期進行,或者(2)如果您只是傳回電子郵件列表,請將您的動作簽名更改爲public ActionResult SetEmails(List<Emails> emails)

我不會打電話給你遇到的錯誤或功能,而是你的設計中遇到的問題。

+0

我將它切換到人,這解決了問題。名稱不是必需的,我只是採用遺留代碼,最後一個想法是爲什麼模型綁定器會失敗,因爲Action參數名稱與參數類類型的屬性名稱匹配。 我不明白爲什麼這會導致任何模糊不清?電子郵件.GetType()。GetProperties()等..匹配他們對json進來..如果一個參數類類型(架構我想)匹配的JSON,很好..什麼是參數南問題?這個名字在綁定過程中如何發揮作用?它的名字並不指定它是類的類型! – Mike

+0

JSON通過'DictionaryValueProvider'綁定,因此這些值通過鍵名關聯。如果有兩個相同名稱的密鑰,那麼該字典將無效。如果這有幫助,請標記爲已回答。 – counsellorben

+1

而這些鍵應該來自類屬性,而不是您給用於綁定模型的參數的名稱。 參數名稱在迭代它的屬性時有什麼相關性? var pi = controller.GetMethod(「action」)。GetParameters(); 在這裏,你需要參數的名稱,或者它如何影響檢索參數的結果,然後你可以得到它的類類型並遍歷它的屬性來綁定數據。 這不是一個具有相同名稱的兩個屬性的問題(無效且不會編譯)。 – Mike

0

我不是說我就像這個答案,但你可以避免改變你的屬性名稱。

用參數的變量名稱(在這種情況下,它是「電子郵件」)包裝您的JSON對象。所以這個工程:

數據:JSON.stringify({電子郵件:{名稱: 「我的名字」,電子郵件: 「[email protected]」, 「[email protected]」]}}) ;

但這並不 - 在ModelBinder的返回null而不是:

數據:JSON.stringify({名稱: 「我的名字」,電子郵件: 「[email protected]」,「 [email protected]「]});

儘管如此,這是相當糟糕的。然而,事情的工作很深入,沒有任何理由我的Web客戶端應該知道控制器中的參數名稱是爲了正確工作。就我而言,這是MVC模型綁定器中的一個錯誤。