JSON对象在WCF REST POST上具有空数组属性

时间:2012-11-12 04:35:18

标签: jquery arrays json wcf rest

我正在将一个JSON对象发布到WCF中的REST API。 string和int属性很好,但IList类型的属性为null,即使它们是在JSON中指定的。

以下是JSON对象在字符串化后的样子:

{
    "Id":"1",
    "Name":"Group One ertqer",
    "Description":"This is group 1 estrfasd",
    "SecurityPrincipals":"[
        {
            "Id": "1",
            "DisplayName": "User One",
            "UserName": "user.one",
            "Sid": "null",
            "Fqdn": "gmd.lab" 
         } ,
        {
            "Id": "2",
            "DisplayName": "User Two",
            "UserName": "user.two",
            "Sid": "null",
            "Fqdn": "gmd.lab" 
         }
     ]",
    "SecurityPermissions":"[
        {
            "Id": "2",
            "Name": "Access Service Catalog"
        } ,
        {
            "Id": "1",
            "Name": "Access Portal"
        }
    ]"
}

这是我用来POST对象的jQuery AJAX代码:

var securitygroup = {
    group: {
        Id: $("#csm-security-groupid").val(),
        Name: $("#csm-security-groupname").val(),
        Description: $('#csm-security-groupdesc').val(),
        "SecurityPrincipals[]": principals,
        "SecurityPermissions[]": permissions
    }
};

$.ajax({
    url: 'http://localhost:809/RestDataServices/RestDataService.svc/SecurityGroups/SecurityGroup',
    contentType: "application/json; charset=utf-8",
    data: JSON.stringify(securitygroup),
    dataType: 'json',
    type: 'POST',
    async: true,
    success: function (data, success, xhr) {
        alert('Group saved - ' + success);
    },
    error: function (xhr, status, error) {
        alert('Error! - ' + xhr.status + ' ' + error);
    }
});

这是REST操作合同:

[OperationContract]
[WebInvoke(Method = "POST",
    RequestFormat = WebMessageFormat.Json,
    BodyStyle = WebMessageBodyStyle.Bare,
    UriTemplate = "SecurityGroups/SecurityGroup")]
void SaveSecurityGroup(SecurityGroup group);

SecurityGroup的数据合约:

[DataContract]
public class SecurityGroup
{
    [DataMember]
    public int Id { get; set; }

    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public string Description { get; set; }

    [DataMember]
    public IList<SecurityPermission> SecurityPermissions { get; set; }

    [DataMember]
    public IList<SecurityPrincipal> SecurityPrincipals { get; set; }

}

最后,这是REST服务的web.config的相关部分:

  <system.serviceModel>
    <services>
      <service name="RestDataServices.RestDataService" behaviorConfiguration="DefaultBehavior">
        <endpoint address="" binding="webHttpBinding" contract="RestDataServices.IRestDataService" behaviorConfiguration="web"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="DefaultBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
    <directoryBrowse enabled="true"/>
    <httpProtocol>
     <customHeaders>
       <add name="Access-Control-Allow-Origin" value="*" />
     </customHeaders>
   </httpProtocol>
  </system.webServer>

所以我尝试了很多不同的东西:

1)尝试包裹和打开 2)最初数据合同具有List&lt;&gt;属性,而不是IList&lt;&gt;,但显然不起作用 3)我在StackExchange上搜索了大约十几个其他问题,但似乎没有一个问题与我的问题有关。

我宁愿不必创建自定义格式化程序......我猜我只是做错了会变得非常简单。

对此有任何帮助将非常感激。我已经花了大约6个小时在这上面,我即将放弃并将这些阵列作为单独的电话发布。

2 个答案:

答案 0 :(得分:1)

好的,答案是我需要以不同的方式做两件事。

1)我在我的JSON数组分配中添加了引号和方括号,因为我收到了400 - 没有它们的错误请求。这是我的null数组/列表属性的来源。

var securitygroup = {
    group: {
        Id: $("#csm-security-groupid").val(),
        Name: $("#csm-security-groupname").val(),
        Description: $('#csm-security-groupdesc').val(),
        "SecurityPrincipals[]": principals, //bad
        "SecurityPermissions[]": permissions //bad
    }
};

2)一旦我删除了SecurityPrincipals和SecurityPermissions属性上的“”和[],我又得到了400 - 错误请求。我注意到我的整数属性都有引号,所以我强制它们使用parseInt作为整数。我也强迫“null”为正确的空值。以下是JSON构建代码的样子,现在:

var principals = [];
$("li[data-type='permission']").each(function () {
    principals.push(
        {
            Id: parseInt(this.id),
            DisplayName: this.getAttribute('data-name'),
            UserName: this.getAttribute('data-username'),
            Sid: this.getAttribute('data-sid') == "null" ? null : this.getAttribute('data-sid'),
            Fqdn: this.getAttribute('data-fqdn')
        }
    );
});

//permissions for the current group
var permissions = [];
$("input[type='checkbox']").each(function () {
    if (this.getAttribute("checked") == "checked") {
        permissions.push(
            {
                Id: parseInt(this.getAttribute('data-id')),
                Name: this.getAttribute('data-name')
            }
        );
    }
});

var securitygroup = {
    group: {
        Id: parseInt($("#csm-security-groupid").val()),
        Name: $("#csm-security-groupname").val(),
        Description: $('#csm-security-groupdesc').val(),
        SecurityPrincipals: principals,
        SecurityPermissions: permissions
    }
};

答案 1 :(得分:0)

删除[,之后]之前的引号。

JSON中没有列表(或iLists?)。

[]表示一个数组。

请参阅http://www.json.org/