简体   繁体   English

将JSON反序列化为C#-复选框中的值

[英]Deserialize JSON to C# - Values from Checkboxes

I'm attempting to send form values over AJAX to a C# web service. 我正在尝试通过AJAX将表单值发送到C#Web服务。 Then, using JavaScriptSerializer.Deserialize, convert the JSON to a C# class. 然后,使用JavaScriptSerializer.Deserialize将JSON转换为C#类。 Below is the class: 下面是课程:

[Serializable]
[DataContract(Name = "PostParameters")]
public class TagData
{
    public TagData()
    {
    }

    [DataMember(Name = "TargetId")]
    public string TargetId { get; set; }
    [DataMember(Name = "TargetType")]
    public string TargetType { get; set; }
    [DataMember(Name = "Tags")]
    public List<string> Tags { get; set; }
}

Here is the method being called: 这是被调用的方法:

[WebMethod]
public string UpdateTags(string PostParameters)
{
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    var tagData = serializer.Deserialize<TagData>(PostParameters);
}

This works when more than one checkbox is checked. 当选中多个复选框时,此方法有效。 The Tags property is successfully populated. 标签属性已成功填充。 However, when less than two items are checked, there is a conversion error. 但是,当检查少于两个项目时,会出现转换错误。 The serializer cannot convert the single string value to a List object. 序列化程序无法将单个字符串值转换为List对象。

Here is how the JSON is sent with one checkbox checked: {"Tags":"14","TargetId":"36946","TargetType":"Officer"} 选中以下一个复选框后,发送JSON的方式如下: {"Tags":"14","TargetId":"36946","TargetType":"Officer"}

Here is how the JSON is sent with more than one checkbox checked: {"Tags":["12","5","2"],"TargetId":"36946","TargetType":"Officer"} 这是发送JSON并选中多个复选框的方式: {"Tags":["12","5","2"],"TargetId":"36946","TargetType":"Officer"}

I attempted changing the Tags property in my C# class to a string array: public string[] Tags { get; set; } 我试图将C#类中的Tags属性更改为字符串数组: public string[] Tags { get; set; } public string[] Tags { get; set; } public string[] Tags { get; set; } however, this resulted in the JSON not being mapped at all. public string[] Tags { get; set; } ,但这导致JSON根本没有被映射。

I also attempted adding [] to the checkbox input names like so: <input type="checkbox" name="tags[]" /> 我还尝试将[]添加到复选框输入名称中,如下所示: <input type="checkbox" name="tags[]" />

This sent the JSON across as so, with one checkbox checked: {"Tags[0]":"14","TargetId":"36946","TargetType":"Officer"} 这样就发送了JSON,并选中了一个复选框: {"Tags[0]":"14","TargetId":"36946","TargetType":"Officer"}

and more than one checkboxes checked: {"Tags[0]":"14","Tags[1]":"19","TargetId":"36946","TargetType":"Officer"} 并选中了多个复选框: {"Tags[0]":"14","Tags[1]":"19","TargetId":"36946","TargetType":"Officer"}

This seems like it would work with the string array property, but it won't map for either that or the List property. 这似乎可以与字符串数组属性一起使用,但不会映射到该属性或List属性。 The Tags property will always be null because it's unable to map. Tags属性将始终为null,因为它无法映射。

UPDATE - Here's where the JSON is generated 更新-这是生成JSON的地方

var params = $.toJSON({ 'PostParameters': JSON.stringify($inputs.serializeObject()) });

and here's the serializeObject() function: 这是serializeObject()函数:

serializeObject: function () {
    var obj = {},
    names = {};

    $.each(this.serializeArray(), function (i, o) {
        var n = o.name,
        v = o.value;

        if (n.includes('[]')) {
            names.n = !names.n ? 1 : names.n + 1;
            var indx = names.n - 1;
            n = n.replace('[]', '[' + indx + ']');
        }

        obj[n] = obj[n] === undefined ? v
          : $.isArray(obj[n]) ? obj[n].concat(v)
          : [obj[n], v];
    });

    return obj;    
}

Any help is appreciated. 任何帮助表示赞赏。

edit you client side code to send an array of one element in case of one checkbox is selected 编辑您的客户端代码,以在选中一个复选框的情况下发送一个元素数组
JSON with one checkbox checked: 选中了一个复选框的JSON:
{"Tags":["14"],"TargetId":"36946","TargetType":"Officer"}

I was able to solve this using Rick Strahl's example here: https://weblog.west-wind.com/posts/2010/Sep/07/Using-jQuery-to-POST-Form-Data-to-an-ASPNET-ASMX-AJAX-Web-Service 我可以在这里使用Rick Strahl的示例来解决此问题: https : //weblog.west-wind.com/posts/2010/Sep/07/Using-jQuery-to-POST-Form-Data-to-an-ASPNET- ASMX的AJAX的Web服务

Essentially, create a NameValue class: 本质上,创建一个NameValue类:

public class NameValue
{
    public string name { get; set; }
    public string value { get; set; }
}

Use these extension methods to get form values from the collection: 使用以下扩展方法从集合中获取表单值:

public static class NameValueExtensionMethods
{
    /// <summary>
    /// Retrieves a single form variable from the list of
    /// form variables stored
    /// </summary>
    /// <param name="formVars"></param>
    /// <param name="name">formvar to retrieve</param>
    /// <returns>value or string.Empty if not found</returns>
    public static string Form(this  NameValue[] formVars, string name)
    {
        var matches = formVars.Where(nv => nv.name.ToLower() == name.ToLower()).FirstOrDefault();
        if (matches != null)
            return matches.value;
        return string.Empty;
    }

    /// <summary>
    /// Retrieves multiple selection form variables from the list of 
    /// form variables stored.
    /// </summary>
    /// <param name="formVars"></param>
    /// <param name="name">The name of the form var to retrieve</param>
    /// <returns>values as string[] or null if no match is found</returns>
    public static string[] FormMultiple(this  NameValue[] formVars, string name)
    {
        var matches = formVars.Where(nv => nv.name.ToLower() == name.ToLower()).Select(nv => nv.value).ToArray();
        if (matches.Length == 0)
            return null;
        return matches;
    }
}

Post the data using JSON.stringify only: 仅使用JSON.stringify发布数据:

data: JSON.stringify({ formVars: arForm })

and accepting a parameter to my web method as a NameValue array: 并接受我的网络方法的参数作为NameValue数组:

public string UpdatTags(NameValue[] formVars)

This works when multiple checkboxes are checked, a single checkbox is checked, or no checkboxes are checked. 当选中多个复选框,选中一个复选框或不选中任何复选框时,此方法有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM