使用C#返回带有重复键的Json对象

时间:2017-02-22 06:52:01

标签: c# json dictionary key-value keyvaluepair

我正在使用WEB API从客户端应用程序接收请求以保存联系信息,我只需要在数据有错误时发送错误消息,否则没有TODO

早期我使用字典

例如:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table style="width: 95%;" id="mptblBill" class="no-footer dataTable" role="grid">
    
    <tbody>
            
    <tr role="row" class="">
                <td>
                    <select onchange="getPrice(this);" id="ddlItemId_0">
                            <option value="1">Crocin Medicine</option>
                            <option value="3">DCold Total</option>
                            <option value="4">Rice</option>
                    </select>
                </td>
                <td><input type="text" disabled="disabled" class="width100" value="" id="txtItemPrice_0"></td>
                <td><input type="text" onchange="calculateAmount(this);" class="width100" value="" id="txtQuantity_0"></td>
                <td><input type="text" onchange="calculateAmount(this);" class="width100" value="" id="txtDiscount_0"></td>
                <td><input type="text" disabled="disabled" class="width100" value="" id="txtAmount_0"></td>
                <td><input type="button" class="width100" value="+" id="btnAdd_0"></td>
            </tr></tbody>
<thead>
        <tr role="row"><th class="sorting_disabled" rowspan="1" colspan="1" style="width: 216px;">Item Name</th><th class="sorting_disabled" rowspan="1" colspan="1" style="width: 188px;">Item Price</th><th class="sorting_disabled" rowspan="1" colspan="1" style="width: 188px;">Quantity</th><th class="sorting_disabled" rowspan="1" colspan="1" style="width: 188px;">Discount</th><th class="sorting_disabled" rowspan="1" colspan="1" style="width: 188px;">Amount</th><th class="sorting_disabled" rowspan="1" colspan="1" style="width: 109px;">Action</th></tr>
    </thead>
</table>
<table id="calcTable" style="width:100%; margin-left:32%;">
    <tbody>
        <tr>
            <td colspan="6">
                <label class="pullRight">Total Amount Without Tax </label>
            </td>
            <td colspan="2">
                <input type="text" style="width:188px;" value="" disabled="disabled" id="txtTotalWdoutTax">
            </td>
        </tr>
            <tr>
                <td colspan="6"> 
                    <input type="checkbox" onchange="calculateTax(this);" value="12" style="display:inline" id="chkTax_1" class="pullRight"><label style="display:inline" class="pullRight"> VAT - 12 % </label> 
                </td>
                <td colspan="2">
                    <input type="text" style="width:188px;" value="" disabled="disabled" name="txt_1">
                </td>
            </tr>
            <tr>
                <td colspan="6"> 
                    <input type="checkbox" onchange="calculateTax(this);" value="2" style="display:inline" id="chkTax_2" class="pullRight"><label style="display:inline" class="pullRight"> SAT - 2 % </label> 
                </td>
                <td colspan="2">
                    <input type="text" style="width:188px;" value="" disabled="disabled" name="txt_2">
                </td>
            </tr>
        <tr>
            <td colspan="6">
                <label class="pullRight">Total Amount </label>
            </td>
            <td colspan="2">
                <input type="text" style="width:188px;" value="" disabled="disabled" id="txtTotal">
            </td>
        </tr>
    </tbody>
</table>

相应的JSON对象是

Dictionary<string, string> error = new Dictionary<string, string>
{
    {"SaveContactMethod_1", "FirstName Invalid"},
    {"SaveContactMethod_2", "LastName Invalid"},
    {"SaveContactMethod_3", "MiddleName Invalid"},
}

但我需要一个独特的密钥(即重复密钥),所以我将{ "error" : { "SaveContactMethod_1":"FirstName Invalid", "SaveContactMethod_2":"LastName Invalid", "SaveContactMethod_3":"MiddleName Invalid" } } 更改为Dictionary<string, string>

List<KeyValuePair<string, string>>

相应的JSON对象是

List<KeyValuePair<string, string>> error = new List<KeyValuePair<string, string>>
{
    new KeyValuePair<string, string>("SaveContactMethod", "FirstName Invalid"),
    new KeyValuePair<string, string>("SaveContactMethod", "LastName Invalid"),
    new KeyValuePair<string, string>("SaveContactMethod", "MiddleName Invalid"),
}

我的要求:我需要添加一个重复键,我需要像字典一样的Json输出。请帮助我。

预期输出:JSON

{
    "error" : [
        { "key":"SaveContactMethod", "value":"FirstName Invalid" },
        { "key":"SaveContactMethod", "value":"LastName Invalid" },
        { "key":"SaveContactMethod", "value":"MiddleName Invalid" }
    ]
}

2 个答案:

答案 0 :(得分:98)

,这是不可能的。

这将无效* JSON:

{
    "error" : {
        "SaveContactMethod":"FirstName Invalid",
        "SaveContactMethod":"LastName Invalid",
        "SaveContactMethod":"MiddleName Invalid"
    }
}

您可以查看here

Warning:Duplicate key, names should be unique.[Code 23, Structure 9]
Warning:Duplicate key, names should be unique.[Code 23, Structure 13]

<子> * Depending on what you call valid

如果你真的想要走这条路,根据RFC 4627,你可以使用StringBuilder类。

由于您似乎不理解,取决于您所谓的有效意味着什么。

ECMA-262:

  

如果对象中存在重复的名称字符串,   应覆盖相同密钥的词法前置值。

这意味着:如果你得到三个SaveContactMethod,你只需要ECMA脚本(JS)中的"MiddleName Invalid"。使用c#序列化,这甚至是不可能的。你需要为它编写自己的JsonSerializer。

答案 1 :(得分:89)

你有一个经典的&#34; XY&#34;问题。你问过&#34;我怎么做X&#34;但你真的需要做Y而你认为X是到达Y的唯一方法 - 但是X要么是不可能的还是很辛苦通过稍微改变你的要求,你可以以不同的方式来到Y,但是你还没有看到它,因为你已经被困在X.

这是您的X:您想要获得的JSON格式:

{
    "error" : {
        "SaveContactMethod":"FirstName Invalid",
        "SaveContactMethod":"LastName Invalid",
        "SaveContactMethod":"MiddleName Invalid"
    }
}

正如其他人所说的那样,当你将它加载到C#代码中时,它将丢弃所有错误消息。

然而,这是获取所有错误消息的一种非常简单的方法。您只需要更改您希望看起来像的JSON:

{
    "error" : {
        "SaveContactMethod": [
            "FirstName Invalid",
            "LastName Invalid",
            "MiddleName Invalid"
        ]
    }
}

如果您只有一条错误消息,仍然使用列表

{
    "error" : {
        "SaveContactMethod": [
            "FirstName Invalid"
        ]
    }
}

这样,当您将JSON加载到C#代码中时,总是具有相同的类型Dictionary<string,List<string>>,无论是一个错误还是多个错误。

这是你XY问题中的Y.我希望在JSON&#34;中找到重复的键,而不是将你的头撞在墙壁上,找到绕墙的方法:使用一个带有值列表的键。现在,您可以执行真正所需的操作,即从每个错误消息只需一个密钥名称即可获取表单中的所有错误消息。