如何使自托管 wcf 接受 REST/JSON?
How do i make a self hosted wcf accept REST/JSON?
我在 SO 上的几篇文章中读到,可以创建接受 JSON 作为输入的自托管 wcf REST 服务。但是我无法让它工作,我似乎一遍又一遍地用头撞同一块石头:(
这是我无法正常工作的非常基本的代码。
我在 VS 2017 中使用 .net 4.6.1
[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;
我把这个拿回来了。
"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'."
我无法让它工作!我尝试过不同的客户端实现,但结果相同。
在每个答案中,我都检查说只使用
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
而且我应该很好。但它不起作用,我有点沮丧,因为这是我能想到的最简单的例子。
那我做错了什么?
我以前使用过相同类型的实现,但对于 SOAP 项目,它工作得很好。这次我做不到了。
兄弟,我们需要使用 WebHttpBinding 来创建 Restful 风格的 WCF 服务。
这是一个例子。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-create-a-basic-wcf-web-http-service
Webservicehost也是我们创建Restful风格的服务时需要承载的服务。或者,我们可以向主机添加 WebHttpBehavior 端点行为,如下所示。
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属性,我们有自定义对象参数时请注意数据格式。
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
bool Save(BatchOfRows request);
假设BatchOfRows 有一个ID 属性。根据您的定义,Json 数据应该是。
{ “request”:{“ID”:1}}
详情。
如果有什么我可以帮忙的,请随时告诉我。
我在 SO 上的几篇文章中读到,可以创建接受 JSON 作为输入的自托管 wcf REST 服务。但是我无法让它工作,我似乎一遍又一遍地用头撞同一块石头:(
这是我无法正常工作的非常基本的代码。 我在 VS 2017 中使用 .net 4.6.1
[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;
我把这个拿回来了。
"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'."
我无法让它工作!我尝试过不同的客户端实现,但结果相同。 在每个答案中,我都检查说只使用
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
而且我应该很好。但它不起作用,我有点沮丧,因为这是我能想到的最简单的例子。
那我做错了什么?
我以前使用过相同类型的实现,但对于 SOAP 项目,它工作得很好。这次我做不到了。
兄弟,我们需要使用 WebHttpBinding 来创建 Restful 风格的 WCF 服务。
这是一个例子。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-create-a-basic-wcf-web-http-service
Webservicehost也是我们创建Restful风格的服务时需要承载的服务。或者,我们可以向主机添加 WebHttpBehavior 端点行为,如下所示。
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属性,我们有自定义对象参数时请注意数据格式。
[WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
bool Save(BatchOfRows request);
假设BatchOfRows 有一个ID 属性。根据您的定义,Json 数据应该是。
{ “request”:{“ID”:1}}
详情。
如果有什么我可以帮忙的,请随时告诉我。