2

基本的にいくつかのモバイルアプリケーションから消費されるWCFレスフルサービスを開発しています。POST を介して、DataContract オブジェクト [実際にはオブジェクトのリストを送信する必要があります] と別の単一の ID を文字列として送信しようとしています。私の質問は、DataContract オブジェクトと単一の文字列を受け入れるように関数を定義する可能性があるかどうかです。

以下は私のコードです: インターフェイス宣言:

[ServiceContract]
    public interface IService1
    {

        [OperationContract]
        [WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "GetDataUsingDataContract/{id}")]
        CompositeType GetDataUsingDataContract(string id, CompositeType composite );


    }

    [DataContract]
    public class CompositeType
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }

関数の実際の定義:

public CompositeType GetDataUsingDataContract(string id, CompositeType composite )
        {

            if (composite == null)
            {
                throw new ArgumentNullException("composite");
            }
            if (composite .BoolValue)
            {
                composite .StringValue += "- Suffix and the id is"+id;
            }
            return report;
        }

Fiddlerから送信しようとしているjsonオブジェクトは

{"BoolValue":true,"StringValue":"sdfsdfsf"}

リクエスト送信時の Fiddler スナップ 出力の Fiddler スナップ 上記は、サービスをテストしているフィドラーからのスナップです。グーグルで数回調べた後、クライアントが実際にWebサービス参照を使用してDataContractタイプを取得し、リクエストボディとして送信する前にjsonにシリアル化する次のリンクを取得しました。しかし、Fiddler からの私のテストが成功しないのはなぜですか?! http://dotnetmentors.com/wcf/wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract.aspx

誰でも何か提案できますか?

web.config は次のとおりです。

<?xml version="1.0"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="JSONWebService.Service1" behaviorConfiguration="JSONWebService.Service1Behavior">
        <endpoint address="../Service1.svc"
            binding="webHttpBinding"
            contract="JSONWebService.IService1"
            behaviorConfiguration="webBehaviour" />
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="JSONWebService.Service1Behavior">

          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="webBehaviour">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>

</configuration>
4

1 に答える 1

12

このシナリオを機能させるには、いくつかの作業を行う必要があります。

最初に、サービス コントラクトで、この例に示すように、 Wrappedに設定されたWebInvoke属性のBodyStyleパラメーターを使用して、複数のパラメーターを持つメソッドをマークする必要があります( http://dotnetmentors.com/でリンクしたサンプルから適応)。wcf/wcf-rest-service-to-get-or-post-json-data-and-retrieve-json-data-with-datacontract.aspx ):

[OperationContract]
[WebInvoke(UriTemplate = "/PlaceOrder",
    RequestFormat = WebMessageFormat.Json,
    ResponseFormat = WebMessageFormat.Json, Method = "POST",
    BodyStyle = WebMessageBodyStyle.Wrapped)]
bool PlaceOrder(string id, OrderContract order);

この属性パラメーターを配置したら、クライアントで複数の Web メソッド パラメーターを 1 つの文字列にラップする必要があります。次の例は、C# でこれを行う方法を示しています。

  var requestdata = new
  {
    id = order.OrderID,
    order = order
  };
  string data2 = JsonConvert.SerializeObject(requestdata);

匿名メソッドのフィールド名は、Web メソッドのパラメーター名と一致することに注意してください。

参考までに、これが生成する JSON は次のようになります。ここでは、JSON 文字列内のidオブジェクトとorderオブジェクトを確認できます。

{"id":"10560","order":{"OrderID":"10560","OrderDate":"06/09/2013 12:29:04","ShippedDate":"16/09/2013 12:29:04","ShipCountry":"Uganda","OrderTotal":"781"}}

例を使用して、Fiddler でこの形式の JSON をテストできるはずです。


答えを拡張して他のデータ型を処理する

boolDateTimeプロパティを含むDataContractを使用します。

[DataContract]
public class OrderContract
{
  [DataMember]
  public string OrderID { get; set; }

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

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

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

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

  [DataMember]
  public bool Shipped { get; set; }

  [DataMember]
  public DateTime DeliveredDate { get; set; }
}

ここでの問題は、DateTimeを処理し、JSON が WCF RESTful サービスで逆シリアル化できる形式であることを確認することです。これを機能させるために、クライアントで次のコードを使用しました。

OrderContract order = new OrderContract
{
  OrderID = "10560",
  OrderDate = DateTime.Now.ToString(),
  ShippedDate = DateTime.Now.AddDays(10).ToString(),
  ShipCountry = "India",
  OrderTotal = "781",
  Shipped = true,
  DeliveredDate = DateTime.Now
};

DataContractJsonSerializer ser =
        new DataContractJsonSerializer(typeof(OrderContract));
MemoryStream mem = new MemoryStream();
ser.WriteObject(mem, order);
string data =
    Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);

var requestdata = new
{
  id = order.OrderID,
  order = order
};
JsonSerializerSettings microsoftDateFormatSettings = new JsonSerializerSettings
{
  DateFormatHandling = DateFormatHandling.MicrosoftDateFormat
};
string data2 = JsonConvert.SerializeObject(requestdata, microsoftDateFormatSettings);
WebClient webClient = new WebClient();
webClient.Headers["Content-type"] = "application/json";
webClient.Encoding = Encoding.UTF8;
webClient.UploadString("http://localhost:61966/OrderService.svc/PlaceOrder", "POST", data2);

JSON シリアライザーの設定に注意してください。これにより、次の JSON が生成されます。

{"id":"10560","order":{"OrderID":"10560","OrderDate":"10/09/2013 16:15:30","ShippedDate":"20/09/2013 16:15:30","ShipCountry":"India","OrderTotal":"781","Shipped":true,"DeliveredDate":"\/Date(1378826130655+0100)\/"}}
于 2013-09-06T11:35:46.720 に答える