[英]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)。
你看過這篇文章嗎?
基本上,您似乎需要向StringContent()
構造函數添加更多參數,如下所示:
new StringContent(serialized, System.Text.Encoding.UTF8, "application/json");
關於Windows Communication Foundation,您需要了解的一件事是ABC 。
所以這個理論非常簡單,雖然在編寫代碼時,卻很奇怪。 這里或這里可以找到一個簡單的教程。 可以在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.