0

JSON オブジェクトを WCF の REST API に POST しています。string プロパティと int プロパティは正常に処理されますが、IList 型のプロパティは JSON で指定されていても null です。

文字列化された後の 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) 元々、データ コントラクトには IList<> ではなく List<> プロパティがありましたが、明らかにそれは機能しませんでした 3) ここ StackExchange で他に約 12 の質問を調べましたが、どれもありませんでしたそれらは私の問題に関連しているようです。

カスタムフォーマッタを作成する必要はありません...非常に単純であることが判明する何か間違ったことをしているだけだと思います。

これに関するヘルプは非常に高く評価されます。私はすでにこれに約 6 時間を費やしており、あきらめて配列自体を別の呼び出しとして投稿しようとしています。

4

2 に答える 2

1

OK、答えは、2 つのことを別の方法で行う必要があるということでした。

1) JSON 配列の割り当てに引用符と角かっこを追加しました。それらがないと 400 - Bad Request が返されたためです。これは、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 - 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 にはリスト (または iLists?) はありません。

[] は配列を示します。

http://www.json.org/を参照

于 2012-11-12T05:23:48.943 に答える