2014-09-02 75 views
2

我想創建一個IIS託管的Web服務,我將消耗使用通用的Windows應用商店的AOO(的Windows Phone/Windows 8.1中/ Windows的RT)。創建/使用WCF和通用應用程序消耗REST WebService的

據我瞭解使用「添加服務引用」,所以我需要創建一個RESTful Web服務和消費手動它的普及應用通用應用程序不支持代理類生成和SOAP調用。

我試過幾十個教程,並在整個網絡接近,但我從來沒有設法實際上POST數據到web服務。

我需要發送其在一個共享庫的web服務定義的自定義類的對象。我知道我需要序列化對象並將其包含在POST請求中,但無論我嘗試什麼,我都會遇到不同的問題 - 例如HTTP 400錯誤請求:傳入消息具有意外的消息格式「原始」。預期的操作消息格式是'Xml'; 'Json的'。

我已經看到了幾種方法來手動設置內容類型頭,但是我發現沒有提供一個通用的應用程序的方法。

有人可以提供信息,或者是裝修我的方案(通過通用的應用程序POST-ING)的例子嗎?

更新1:爲了進一步澄清:我知道WCF是如何工作的,我已經能夠像this post描述來完成一個基本的GET請求。但是我無法將其擴展爲也可以使用POST請求。

一些代碼,我已經試過:

public async static void SendStartup(CustomClass customObject) 
{ 
    var httpClient = new HttpClient(); 
    var serialized = JsonConvert.SerializeObject(customObject); 
    var response = await httpClient.PostAsync("http://localhost:49452/Metrics.svc/LogStartup", new StringContent(serialized)); 
    string content = await response.Content.ReadAsStringAsync(); 
} 

Web服務接口:

[OperationContract] 
[WebInvoke(UriTemplate = "LogStartup", Method="POST", BodyStyle=WebMessageBodyStyle.Wrapped)] 
string LogStartup(CustomClass obj); 

實現:

public void LogStartup(CustomClass obj) 
{ 
    // nothing 
} 

例如,這failes在運行時用上述

提到的錯誤
+0

什麼代碼給你一個問題? – Greg 2014-09-02 19:58:30

+0

您是否閱讀過Web API,或者使用PCL編寫WCF? http://msdn.microsoft.com/en-us/library/gg597391(v=vs.110).aspx http://www.asp.net/web-api – Lloyd 2014-09-02 20:00:25

+0

@Lloyd WCF不支持Windows Phone Store應用程序,所以這是我的替代品。 – leepfrog 2014-09-02 21:11:59

回答

1

您需要了解的一件事Windows Communication FoundationABC的

  • 答:地址
  • B:綁定
  • C:合同

所以理論非常簡單,但同時你的編碼,它是很奇怪。一個簡單的教程可以發現herehere。在這個確切的方法Code Code Project中可以找到其他幾個教程。

瞭解多態性可能有助於理解Windows Communication Foundation,因爲它很大程度上依賴於它。

[ServiceContract] 
public interface IContent 
{ 
    [OperationContract] 
    void DoSomething(SomeModel model); 
} 

所以你在這裏做的是定義你的服務,定義你的方法。正如我上面提到的,我們明確宣佈我們的合同,但我們還沒有實施我們的方法。我們還打算通過SomeModel這將是我們的數據合同

我們將建立我們的模型:

[DataContract] 
public class SomeModel 
{ 
    [DataMember] 
    public string Name { get; set; } 
} 

該模型可以是非常簡單像上面,或極其複雜的。這將取決於使用情況。現在

我們想實現我們的方法:

public class Content : IContent 
{ 
    public void DoSomething(SomeModel model) 
    { 
      // Implementation 
    } 
} 

現在在客戶機上,只需消耗你的服務。一旦你瞭解了基礎知識,以及它如何序列化和反序列化,你可以將它用於REST。哪些教程也存在。

+0

感謝Greg的例子。我意識到WCF背後的基本思想,過去我使用WCF/SOAP構建了一些簡單的應用程序。我的問題是專門針對發佈到REST webservice(基本的GET請求做的工作) – leepfrog 2014-09-02 21:14:09

2

你見過這篇文章嗎?

How to use HttpClient to post JSON data

基本上好像你需要更多的參數添加到您的StringContent()構造是這樣的:

new StringContent(serialized, System.Text.Encoding.UTF8, "application/json"); 
6

有兩個問題,你的代碼。

1)你要發送Content-Type頭,而你正在請求

var content = new StringContent(serialized,Encoding.UTF8,"application/json"); 

2)你必須使用BodyStyle = WebMessageBodyStyle.Bare

WebMessageBodyStyle.Bare可以用一個參數的工作在你的例如,但是如果你想發佈更多的參數,那麼你必須使用WebMessageBodyStyle.Wrapped,但是,你發佈的對象應該被修改爲

var serialized = JsonConvert.SerializeObject(new { obj = customObject }); 

這裏是工作的代碼,你可以用自承載WCF服務

async void TestRestService() 
{ 
    var ready = new TaskCompletionSource<object>(); 
    Task.Factory.StartNew(() => 
    { 
     var uri = new Uri("http://0.0.0.0:49452/Metrics.svc/"); 
     var type = typeof(Metrics); 
     WebServiceHost host = new WebServiceHost(type, uri); 
     host.Open(); 
     ready.SetResult(null); 
    },TaskCreationOptions.LongRunning); 

    await ready.Task; 

    var customObject = new CustomClass() { Name = "John", Id = 333 }; 
    var serialized = JsonConvert.SerializeObject(new { obj = customObject }); 

    var httpClient = new HttpClient(); 
    var request = new StringContent(serialized,Encoding.UTF8,"application/json"); 
    var response = await httpClient.PostAsync("http://localhost:49452/Metrics.svc/LogStartup", request); 
    string content = await response.Content.ReadAsStringAsync(); 
} 

[ServiceContract] 
public class Metrics 
{ 
    [OperationContract] 
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped)] 
    public string LogStartup(CustomClass obj) 
    { 
     return obj.Name + "=>" + obj.Id; 
    } 
} 

public class CustomClass 
{ 
    public string Name { set; get; } 
    public int Id { set; get; } 
} 

PS測試:如果你想返回一個JSON響應,那麼你可以使用ResponseFormat=WebMessageFormat.Json。然後,您應該改變WebInvoke屬性作爲

[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped,ResponseFormat=WebMessageFormat.Json)] 

BTW:您仍然可以動態地設置AutomaticFormatSelectionEnabled選擇返回的內容類型(XML或JSON)。

+1

非常感謝您的詳細示例和解釋,我馬上就工作! – leepfrog 2014-09-07 16:03:58

+0

@LB,當我通過WebChannelFactory使用POST方法訪問UriTemplate時,我收到錯誤消息:「沒有可以接受消息的」xxx「端點。 – RGS 2017-01-10 18:52:28

+0

@RGS很難說沒有代碼的東西,也許你想問一下一個問題,併發佈一個最小的代碼來重現該問題。 – 2017-01-10 19:05:44