2011-08-14 18 views
6

私は安心してwcfで新しいです。私は問題を見つけることができませんでした、なぜ私のwcf安らかなサービスは '悪い要求'を与える​​。私は.NET 4.0を使用します。JSONリクエストでfiddlerから安心してwcfサービスを呼び出す方法は?

私のサービスは次のとおりです。

[OperationContract(Name="Add")] 
[WebInvoke(UriTemplate = "test/", Method = "POST", 
      ResponseFormat=WebMessageFormat.Json, 
      RequestFormat=WebMessageFormat.Json)] 
public int Add(Number n1) 
{ 
    res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2); 
    return res; 
} 

データは..です

[Serializable] 
    public class Number 
    { 
     public int Number1 { get; set; } 
     public int Number2 { get; set; } 
    } 

私はシオマネキそのリターンから呼び出す 'HTTP/1.1 400不正な要求'

私のフィドラーリクエストヘッダーは:

User-Agent: Fiddler 
Host: localhost:4217 
Content-Type: application/json; charset=utf-8 

と要求体である:

HTTP/1.1 400 Bad Request 
Server: ASP.NET Development Server/10.0.0.0 
Date: Sun, 14 Aug 2011 18:10:21 GMT 
X-AspNet-Version: 4.0.30319 
Content-Length: 5450 
Cache-Control: private 
Content-Type: text/html 
Connection: Close 

しかし、私はC#クライアントプログラムによって、このサービスを呼び出す場合、それはokです:

{"Number1":"7","Number2":"7"} 

とレスポンスヘッダがあります。

私のクライアントコードは次のとおりです。

uri = "http://localhost:4217/Service1.svc/"; 
Number obj = new Number() { Number1 = 7, Number2 = 7 }; 
using (HttpResponseMessage response = new HttpClient().Post(uri+"test/", 
     HttpContentExtensions.CreateDataContract(obj))) 
{ 
    string res = response.Content.ReadAsString(); 
    return res.ToString(); 
} 

........

おかげで私を助けてください。

答えて

8

あなたのコードの問題を見つける方法ですenable tracingにサーバー上問題を説明する例外があります。私はあなたのコードで簡単なテストを書いて、それが同様のエラー(400)を有し、およびトレースは、次のエラーが発生しました:[Serializable]が付い

The data contract type 'WcfForums.StackOverflow_7058942+Number' cannot be 
deserialized because the required data members '<Number1>k__BackingField, 
<Number2>k__BackingField' were not found. 

データ型は、すべてのフィールドオブジェクト内のはないシリアライズプロパティ。その属性をコメントアウトすることで、コードが実際に罰金(タイプはその後、「POCO」に該当するすべてのパブリックフィールドとプロパティをシリアライズ(プレーン旧CLRオブジェクト)ルールを、うまくいく。

public class StackOverflow_7058942 
{ 
    //[Serializable] 
    public class Number 
    { 
     public int Number1 { get; set; } 
     public int Number2 { get; set; } 
    } 
    [ServiceContract] 
    public class Service 
    { 
     [OperationContract(Name = "Add")] 
     [WebInvoke(UriTemplate = "test/", Method = "POST", ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)] 
     public int Add(Number n1) 
     { 
      int res = Convert.ToInt32(n1.Number1) + Convert.ToInt32(n1.Number2); 
      return res; 
     } 
    } 
    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.AddServiceEndpoint(typeof(Service), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior()); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     WebClient c = new WebClient(); 
     c.Headers[HttpRequestHeader.ContentType] = "application/json; charset=utf-8"; 
     c.Encoding = Encoding.UTF8; 
     Console.WriteLine(c.UploadString(baseAddress + "/test/", "{\"Number1\":\"7\",\"Number2\":\"7\"}")); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 
2

あなたが間違っていることの1つは、リクエストオブジェクトのフォーマットです。

{ n1: { "Number1":"7","Number2":"7"} } 

パラメータ名は、wcf jsonエンドポイントに渡されるjsonオブジェクトのルートプロパティ名です。

私はgitにsample wcf serviceを持っています。とりわけ、jsonエンドポイントを持ち、Default.asmxではjqueryを使用して呼び出します。私は同様のWebページ(WCFサービスと同じWebサイト上にホストする)を作成し、jsonを介してjsonサービスを呼び出し、フィドラーがサンプルリクエストを取得するために実行している間にサービスをテストすることをお勧めします。これは、jqueryがヘッダの詳細を大事に扱うので、リクエストを自分で作成するよりも簡単で、エラーの発生が少なくなります。

次のようにあなたがあなたのサービスのために適合させることができ、私のエコーサービスを呼び出すためのサンプルjqueryのAjaxのコードは次のとおりです。

$("#btnEchoString").click(function() { 
     var request = $("#request"); 
     var response = $("#response"); 
     $.ajax({ 
      url: 'EchoService.svc/JSON/Echo', 
      type: "POST", 
      contentType: "application/json; charset=utf-8", 
      data: JSON.stringify({ request: request.val() }), 
      dataType: "json", 
      success: function (data) { 
       response.val(data.d); 
      }, 
      error: function (request, status, error) { 
       //TODO: do something here 
      } 
     }); 
    }); 
+1

の「通常」の使用をWCF RESTは、あなたのサンプルにある ' 'ではなく、' 'の振る舞いを使用します(コード経由の場合は' WebHttpBehavior')。の場合、デフォルトのBodyStyleは 'Bare'です。パラメータ名を持つJSONオブジェクトにオブジェクトをラップする必要はありません(のデフォルトは 'WrappedRequest'です)。 – carlosfigueira

+0

カルロス、説明のためにありがとう! –

関連する問題