0

我正在将 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"
        }
    ]"
}

这是我用来发布对象的 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<> 属性,而不是 IList<>,但显然这不起作用 3) 我已经在 StackExchange 上提出了大约十几个其他问题,但没有一个它们似乎与我的问题有关。

我宁愿不必创建自定义格式化程序...我猜我只是做错了事情,结果会很简单。

对此的任何帮助将不胜感激。我已经为此花费了大约 6 个小时,我即将放弃并将数组本身作为单独的调用发布。

4

2 回答 2

1

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

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

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 - Bad Request。我注意到我的整数属性在它们周围有引号,所以我使用 parseInt 将它们强制为整数。我还强制将“null”设置为正确的 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
    }
};
于 2012-11-12T18:57:46.423 回答
0

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

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

[] 表示一个数组。

参考http://www.json.org/

于 2012-11-12T05:23:48.943 回答