2013-04-03 59 views
3

爲什麼我的WCF Rest服務方法的參數始終爲空?....我確實訪問了服務的方法,並且得到了wcf方法返回的字符串,但該參數保持爲空。WCF REST服務:方法參數(對象)爲空

經營合同:

[OperationContract] 
    [WebInvoke(UriTemplate = "AddNewLocation", 
     Method="POST", 
     BodyStyle = WebMessageBodyStyle.WrappedRequest, 
     ResponseFormat = WebMessageFormat.Json, 
     RequestFormat = WebMessageFormat.Json)] 
    string AddNewLocation(NearByAttractions newLocation); 

AddNewLocation方法的實現

public string AddNewLocation(NearByAttractions newLocation) 
    { 
     if (newLocation == null) 
     { 
      //I'm always getting this text in my logfile 
      Log.Write("In add new location:- Is Null"); 
     } 
     else 
     { 
      Log.Write("In add new location:- "); 
     } 

     //String is returned even though parameter is null 
     return "59"; 
    } 

客戶端代碼:

 WebClient clientNewLocation = new WebClient(); 
     clientNewLocation.Headers[HttpRequestHeader.ContentType] = "application/json"; 

     JavaScriptSerializer js = new JavaScriptSerializer(); 
     js.MaxJsonLength = Int32.MaxValue; 

     //Serialising location object to JSON 
     string serialLocation = js.Serialize(newLocation); 

     //uploading JSOn string and retrieve location's ID 
     string jsonLocationID = clientNewLocation.UploadString(GetURL() + "AddNewLocation", serialLocation); 

我也試過這個代碼在我的客戶端,但仍然得到一個空參數

  DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(NearByAttractions)); 

     MemoryStream ms = new MemoryStream(); 
     ser.WriteObject(ms, newLocation); 

     String json = Encoding.UTF8.GetString(ms.ToArray()); 


     WebClient clientNewLocation = new WebClient(); 
     clientNewLocation.Headers[HttpRequestHeader.ContentType] = "application/json"; 

     string r = clientNewLocation.UploadString(GetURL() + "AddNewLocation", json); 

     Console.Write(r); 

後來我也改變了BodyStyle選項「」但後來我得到了以下錯誤(與兩個客戶端代碼):

The remote server returned an error: (400) Bad Request.

任何幫助嗎?感謝

編輯1: 我使用getURL()方法裝載來自web配置文件web服務的IP地址,並返回類型的對象的Uri

private static Uri GetURL() 
    { 
     Configuration config = WebConfigurationManager.OpenWebConfiguration("~/web.config"); 

     string sURL = config.AppSettings.Settings["serviceURL"].Value; 
     Uri url = null; 

     try 
     { 
      url = new Uri(sURL); 
     } 
     catch (UriFormatException ufe) 
     { 
      Log.Write(ufe.Message); 
     } 
     catch (ArgumentNullException ane) 
     { 
      Log.Write(ane.Message); 
     } 
     catch (Exception ex) 
     { 
      Log.Write(ex.Message); 
     } 

     return url; 
    } 

服務地址存儲在web配置如下:

<appSettings> 
    <add key="serviceURL" value="http://192.168.2.123:55666/TTWebService.svc/"/> 
    </appSettings> 

這是我NearByAttraction類如何定義

[DataContractAttribute] 
public class NearByAttractions 
{ 


    [DataMemberAttribute(Name = "ID")] 
    private int _ID; 
    public int ID 
    { 
     get { return _ID; } 
     set { _ID = value; } 
    } 



    [DataMemberAttribute(Name = "Latitude")] 
    private string _Latitude; 
    public string Latitude 
    { 
     get { return _Latitude; } 
     set { _Latitude = value; } 
    } 


    [DataMemberAttribute(Name = "Longitude")] 
    private string _Longitude; 
    public string Longitude 
    { 
     get { return _Longitude; } 
     set { _Longitude = value; } 
    } 

回答

4

你似乎在正確的軌道上。您需要Bare主體樣式,否則您需要將輸入的序列化版本封裝到另一個JSON對象中。第二個代碼應該可以工作 - 但沒有關於服務如何設置以及什麼GetURL()返回的更多信息,我們只能猜測。

找出發送到WCF REST服務的方法之一是使用WCF客戶端本身 - 使用WebChannelFactory<T>類,然後使用Fiddler等工具查看它發送的內容。下面的示例是一個SSCCE,它顯示了您的方案正在工作。

public class StackOverflow_15786448 
{ 
    [ServiceContract] 
    public interface ITest 
    { 
     [OperationContract] 
     [WebInvoke(UriTemplate = "AddNewLocation", 
      Method = "POST", 
      BodyStyle = WebMessageBodyStyle.Bare, 
      ResponseFormat = WebMessageFormat.Json, 
      RequestFormat = WebMessageFormat.Json)] 
     string AddNewLocation(NearByAttractions newLocation); 
    } 
    public class NearByAttractions 
    { 
     public double Lat { get; set; } 
     public double Lng { get; set; } 
     public string Name { get; set; } 
    } 
    public class Service : ITest 
    { 
     public string AddNewLocation(NearByAttractions newLocation) 
     { 
      if (newLocation == null) 
      { 
       //I'm always getting this text in my logfile 
       Console.WriteLine("In add new location:- Is Null"); 
      } 
      else 
      { 
       Console.WriteLine("In add new location:- "); 
      } 

      //String is returned even though parameter is null 
      return "59"; 
     } 
    } 
    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     WebServiceHost host = new WebServiceHost(typeof(Service), new Uri(baseAddress)); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     Console.WriteLine("Using WCF-based client (WebChannelFactory)"); 
     var factory = new WebChannelFactory<ITest>(new Uri(baseAddress)); 
     var proxy = factory.CreateChannel(); 
     var newLocation = new NearByAttractions { Lat = 12, Lng = -34, Name = "56" }; 
     Console.WriteLine(proxy.AddNewLocation(newLocation)); 

     Console.WriteLine(); 
     Console.WriteLine("Now with WebClient"); 

     DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(NearByAttractions)); 
     MemoryStream ms = new MemoryStream(); 
     ser.WriteObject(ms, newLocation); 

     String json = Encoding.UTF8.GetString(ms.ToArray()); 

     WebClient clientNewLocation = new WebClient(); 
     clientNewLocation.Headers[HttpRequestHeader.ContentType] = "application/json"; 

     string r = clientNewLocation.UploadString(baseAddress + "/AddNewLocation", json); 

     Console.WriteLine(r); 
    } 
} 
+0

我曾經使用「bare」作爲body style,但後來我得到「遠程服務器返回錯誤:(400)Bad Request」。錯誤 – drew

3

解決,謝謝

我改變BodyStyle到「裸」所以我serivce界面如下:

[OperationContract] 
    [WebInvoke(UriTemplate = "AddNewLocation", 
     Method="POST", 
     BodyStyle = WebMessageBodyStyle.Bare, 
     ResponseFormat = WebMessageFormat.Json, 
     RequestFormat = WebMessageFormat.Json)] 
    string AddNewLocation(NearByAttractions newLocation); 

然後實現我的客戶如下:

MemoryStream ms = new MemoryStream(); 

     DataContractJsonSerializer serialToUpload = new DataContractJsonSerializer(typeof(NearByAttractions)); 
     serialToUpload.WriteObject(ms, newLocation); 


     WebClient client = new WebClient(); 
     client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); 

     client.UploadData(GetURL() + "AddNewLocation", "POST", ms.ToArray()); 

我使用WebClient.UploadData而不是UploadString。