lee*_*rog 2 c# rest wcf web-services windows-store-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();
}
Run Code Online (Sandbox Code Playgroud)
Web服务接口:
[OperationContract]
[WebInvoke(UriTemplate = "LogStartup", Method="POST", BodyStyle=WebMessageBodyStyle.Wrapped)]
string LogStartup(CustomClass obj);
Run Code Online (Sandbox Code Playgroud)
执行:
public void LogStartup(CustomClass obj)
{
// nothing
}
Run Code Online (Sandbox Code Playgroud)
例如,这会在运行时因上述错误而失效
您的代码有两个问题.
1)您Content-Type在提出请求时必须发送标题
var content = new StringContent(serialized,Encoding.UTF8,"application/json");
Run Code Online (Sandbox Code Playgroud)
2)你必须使用BodyStyle = WebMessageBodyStyle.Bare
WebMessageBodyStyle.Bare可以使用一个参数,如您的示例,但如果您想发布更多参数,那么您必须使用WebMessageBodyStyle.Wrapped但是,您发布的对象应该被修改为
var serialized = JsonConvert.SerializeObject(new { obj = customObject });
Run Code Online (Sandbox Code Playgroud)
这是一个可以使用自托管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; }
}
Run Code Online (Sandbox Code Playgroud)
PS:如果你想返回一个json响应,那么你可以使用ResponseFormat=WebMessageFormat.Json.然后,您应该将WebInvoke属性更改为
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped,ResponseFormat=WebMessageFormat.Json)]
Run Code Online (Sandbox Code Playgroud)
顺便说一句:您仍然可以通过设置动态选择返回的内容类型(xml或json)AutomaticFormatSelectionEnabled.