如何使自托管WCF接受REST/JSON? [英] How do i make a self hosted wcf accept REST/JSON?

查看:118
本文介绍了如何使自托管WCF接受REST/JSON?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在SO上的几篇文章中已经读到过,可以创建一个自托管的wcf REST服务,该服务接受JSON作为输入.但是我无法使它正常工作,我的头撞到了似乎在同一块岩石上的:(

I have read here on SO in several posts that it is possible to create a selfhosted wcf REST service that accepts JSON as input. But i cant get it to work, im banging my head against the same rock over and over it seems :(

这是我无法正常工作的非常基本的代码. 我在VS 2017中使用.net 4.6.1

This is my very basic code that i cant get working. Im using .net 4.6.1 in VS 2017

[ServiceContract]
public interface IService1
{
//[WebInvoke(Method = "POST", UriTemplate = "Save")]
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
bool Save(BatchOfRows request);
}

public bool Save(BatchOfRows request)
{
    return true;
}


Uri baseAddress = new Uri("http://localhost:8000/");

// Step 2: Create a ServiceHost instance.
var selfHost = new ServiceHost(typeof(Service1), baseAddress);
try
{
// Step 3: Add a service endpoint.
selfHost.AddServiceEndpoint(typeof(IService1), new WSHttpBinding(), "");

// Step 4: Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
smb.HttpsGetEnabled = false;
selfHost.Description.Behaviors.Add(smb);

// Step 5: Start the service.
selfHost.Open();
Console.WriteLine("The service is ready.");

// Close the ServiceHost to stop the service.
Console.WriteLine("Press <Enter> to terminate the service.");
Console.WriteLine();
Console.ReadLine();
selfHost.Close();
}
catch (CommunicationException ce)
{
    Console.WriteLine("An exception occurred: {0}", ce.Message);
    selfHost.Abort();
}

然后我用此代码连接

        string url = @"http://127.0.0.1:8000";

        var client = new RestClient(url);

        var request = new RestRequest("Save", Method.POST);

        var b = new BatchOfRows();
        b.CaseTableRows.Add(new AMCaseTableRow { PROJID = "proj1", CASEID = "case1" });
        b.CaseTableRows.Add(new AMCaseTableRow { PROJID = "proj2", CASEID = "case2", DEVICEID = "device2" });

        var stream1 = new MemoryStream();
        var ser = new DataContractJsonSerializer(typeof(BatchOfRows));

        ser.WriteObject(stream1, b);

        stream1.Flush();
        stream1.Position = 0;

        StreamReader reader = new StreamReader(stream1);
        string payload = reader.ReadToEnd();

        request.AddParameter("Save",payload);

        var response = client.Post(request);
        var content = response.Content; 

以我为前提,把它拿回来.

In the respose i get this back.

"StatusCode: UnsupportedMediaType, Content-Type: , Content-Length: 0)"
  Content: ""
  ContentEncoding: ""
  ContentLength: 0
  ContentType: ""
  Cookies: Count = 0
  ErrorException: null
  ErrorMessage: null
  Headers: Count = 3
  IsSuccessful: false
  ProtocolVersion: {1.1}
  RawBytes: {byte[0]}
  Request: {RestSharp.RestRequest}
  ResponseStatus: Completed
  ResponseUri: {http://127.0.0.1:8000/Save}
  Server: "Microsoft-HTTPAPI/2.0"
  StatusCode: UnsupportedMediaType
  StatusDescription: "Cannot process the message because the content type 'application/x-www-form-urlencoded' was not the expected type 'application/soap+xml; charset=utf-8'."

我无法正常工作!我尝试了不同的客户端实现,但结果相同. 在每个答案中,我都只使用

I cant get it to work! I have tried with different client implementations with the same result. In every answer i check it sais to just use

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

我应该很好.但这不起作用,我有点沮丧,因为这是我能想到的最简单的例子.

And i should be good. But its not working and im getting abit frustrated as this is the simplest example i can think of.

那我在做什么错了?

我以前使用过相同类型的实现,但是对于SOAP项目而言,这工作得很好.这次我做不到.

I have used the same type of implementation before, but for a SOAP project, and that is working just fine. I cant do that this time.

推荐答案

Bro,我们需要使用WebHttpBinding创建Restful风格的WCF服务. 这是一个示例.

Bro, we need to use WebHttpBinding to create Restful style WCF service. Here is an example.
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-create-a-basic-wcf-web-http-service
Webservicehost is also need to host the service when we create the Restful style service. Alternatively, we could add WebHttpBehavior endpoint behavior to the host, like below.

static void Main(string[] args)
{
    Uri uri = new Uri("http://localhost:9999");
    WebHttpBinding binding = new WebHttpBinding();
    using (ServiceHost sh=new ServiceHost(typeof(MyService),uri))
    {
        ServiceEndpoint se=sh.AddServiceEndpoint(typeof(IService),binding,"");
        se.EndpointBehaviors.Add(new WebHttpBehavior());


        sh.Open();
        Console.WriteLine("Service is ready....");

        Console.ReadLine();
        sh.Close();
    }
}

结果.

此外,对于 BodyStyle = WebMessageBodyStyle.Wrapped 属性,当我们具有自定义"对象参数时,请注意数据格式.

Result.

Besides, For the BodyStyle=WebMessageBodyStyle.Wrapped attribute, Please pay attention to the data format when we have the Custom object parameter.

[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
bool Save(BatchOfRows request);

假定BatchOfRows具有一个ID属性.根据您的定义,Json数据应为.

Assumed that the BatchOfRows has one ID property. Based on your definition, the Json Data should be.

{请求":{"ID":1}}

{ "request":{"ID":1}}

有关详细信息.
在JSON中使用JSON获取对象为空WCF服务
随时让我知道是否有什么可以帮助您的.

For details.
Get the object is null using JSON in WCF Service
Feel free to let me know if there is anything I can help with.

这篇关于如何使自托管WCF接受REST/JSON?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆