簡體   English   中英

使用WCF和通用應用程序創建/使用REST WebService

[英]Create/Consume REST WebService using WCF and Universal Apps

我想創建一個IIS托管的Web服務,我將使用通用Windows存儲aoo(windows phone / windows 8.1 / windows RT)來使用它。

據我所知,通用應用程序不支持使用“添加服務引用”的代理類生成和SOAP調用,因此我需要創建一個RESTful Web服務並在通用應用程序中手動使用它。

我已經在整個網絡中嘗試過幾十個教程和方法,但我從未設法將數據實際發布到網絡服務。

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

我已經看到了幾種手動設置內容類型標頭的方法,但是我找到的方法在通用應用程序中不可用。

有人可以提供適合我的場景的信息或示例(通過通用應用程序發布)嗎?

更新1:進一步澄清:我知道WCF是如何工作的,我已經能夠完成像在描述一個基本的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
}

例如,這會在運行時因上述錯誤而失效

您的代碼有兩個問題。

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)]

順便說一句:您仍然可以通過設置AutomaticFormatSelectionEnabled來動態選擇返回的內容類型(xml或json)。

你看過這篇文章嗎?

如何使用HttpClient發布JSON數據

基本上,您似乎需要向StringContent()構造函數添加更多參數,如下所示:

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

關於Windows Communication Foundation,您需要了解的一件事是ABC

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

所以這個理論非常簡單,雖然在編寫代碼時,卻很奇怪。 這里這里可以找到一個簡單的教程。 可以在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。 還有哪些教程。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM