通过HTTPS向WCF自托管REST服务发出POST请求的示例 [英] Example of a POST request to WCF selfhosted REST service over HTTPS
问题描述
关于SO的同一主题,这里有很多问题,但是似乎都没有一个完整的答案.我已经检查了大多数问题/答案,并进行了测试,测试和测试.因此,希望这个问题对我和其他挣扎中的人有帮助.
There are numerus question about the same topic here on SO, but none of them seems to give a complete answer. I have checked most of the questions/answers and tested, tested and tested. So hopefully this question will help me and others struggling.
问题.
如何设置可在https上运行的WCF自托管REST服务? 这就是我尝试设置服务和客户端的方式.它不起作用!但是我觉得每次更改都非常接近,但没有达到目标.
How do i set up WCF selfhosted REST service that works over https? This is how I have tried setting up the service and clients. It doesn't work! But i feel that im very close with every change, but im not reaching the goal.
那么,有人可以帮我一个完整的示例,该示例与REST端点,HTTPS上的自托管WCF和POST请求一起使用吗?我已经尝试过从各个地方弄乱一些零碎的东西,但我无法使它正常工作! 我应该放弃吗?选择其他技术?
So, can someone help me with a complete example that is working with a REST endpoint, selfhosted WCF over HTTPS and a POST request? I have tried puzzling together bits and pieces from everywhere and i cant get it working! Should i give up? Choose another technology?
因此,一些代码:
[ServiceHost]
[ServiceHost]
Uri uri = new Uri("https://localhost:443");
WebHttpBinding binding = new WebHttpBinding(WebHttpSecurityMode.Transport);
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
using (ServiceHost sh = new ServiceHost(typeof(Service1), uri))
{
ServiceEndpoint se = sh.AddServiceEndpoint(typeof(IService1), binding, "");
//se.EndpointBehaviors.Add(new WebHttpBehavior());
// Check to see if the service host already has a ServiceMetadataBehavior
ServiceMetadataBehavior smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
// If not, add one
if (smb == null)
smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = false; //**http**
smb.HttpsGetEnabled = true; //**https**
smb.MetadataExporter.PolicyVersion = PolicyVersion.Policy15;
sh.Description.Behaviors.Add(smb);
// Add MEX endpoint
sh.AddServiceEndpoint(
ServiceMetadataBehavior.MexContractName,
MetadataExchangeBindings.CreateMexHttpsBinding(), //**https**
"mex"
);
var behaviour = sh.Description.Behaviors.Find<ServiceBehaviorAttribute>();
behaviour.InstanceContextMode = InstanceContextMode.Single;
Console.WriteLine("service is ready....");
sh.Open();
Console.ReadLine();
sh.Close();
}
[IService]
[IService]
[ServiceContract]
public interface IService1
{
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Xml, RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest, UriTemplate = "Datarows_IN/")]
[OperationContract]
bool Save(BatchOfRows batchOfRows);
}
[服务]
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class Service1 : IService1
{
public bool Save(BatchOfRows batchOfRows)
{
Console.WriteLine("Entered Save");
return true;
}
}
[BatchOfRows]-简化
[BatchOfRows] - simplified
[DataContract]
public class BatchOfRows
{
[DataMember]
public int ID { get; set; } = -1;
[DataMember]
public string Data { get; set; } = "Hej";
}
这是在SO答案和Microsoft教程之后建立在SO答案之上的. 我什至不知道例子从哪里开始,其他例子从哪里结束. 我从这里开始: https://stackoverflow.com/a/57554374/619791 直到我尝试启用https之前,一切都很好,然后一切都停止了工作.
This is build upon SO answer after SO answer and Microsoft tutorials. I dont even know where what example started and the others ended. I began from this: https://stackoverflow.com/a/57554374/619791 And that worked very well until i tried enabling https, then everything stopped working.
这是我尝试过的一些客户端代码.
Here are some client code that i have tried.
[WebClient]
[WebClient]
string uri = "https://localhost:443/Datarows_IN";
WebClient client = new WebClient();
client.Headers["Content-type"] = "application/json";
client.Encoding = Encoding.UTF8;
var b = new BatchOfRows();
var settings = new JsonSerializerSettings() { DateFormatHandling = DateFormatHandling.MicrosoftDateFormat };
string str2 = "{\"batchOfRows\":" + JsonConvert.SerializeObject(b, settings) + "}";
string result = client.UploadString(uri, "POST", str2);
[HttpClient]
[HttpClient]
string str2 = "{\"batchOfRows\":" + JsonConvert.SerializeObject(b, settings) + "}";
var contentData = new StringContent(str2, System.Text.Encoding.UTF8, "application/json");
//string result = client.UploadString(uri, "POST", str2);
//HttpResponseMessage response = client.PostAsJsonAsync("https://localhost:443/Datarows_IN", b).GetAwaiter().GetResult();
HttpResponseMessage response = client.PostAsync("https://localhost:443/Datarows_IN", contentData).GetAwaiter().GetResult();
response.EnsureSuccessStatusCode();
[ChannelFactory]
[ChannelFactory]
//var c = new ChannelFactory<IService1>(binding, new EndpointAddress("https://localhost:443/Datarows_IN"));
var c = new ChannelFactory<IService1>(binding, new EndpointAddress("https://localhost:443/"));
((WebHttpBinding)c.Endpoint.Binding).Security.Mode = WebHttpSecurityMode.Transport;
((WebHttpBinding)c.Endpoint.Binding).Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
c.Endpoint.Behaviors.Add(new WebHttpBehavior());
var aw = c.CreateChannel();
var b = new ModuleIntegration.Client.Objects.BatchOfRows();
aw.Save(b);
没有一个客户在工作.如果我调试,则永远不会触发服务端点. 这是即时通讯收到的当前错误:
None of the clients work. If i debug my Service endpoint is never triggered. This is the current error that im getting:
<Fault xmlns="http://schemas.microsoft.com/ws/2005/05/envelope/none">
<Code>
<Value>Sender</Value>
<Subcode>
<Value xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</Value>
</Subcode>
</Code>
<Reason>
<Text xml:lang="sv-SE">The message with Action '' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</Text>
</Reason>
</Fault>
请帮助!为什么这么难?!?
Please help! Why is this so hard?!?
推荐答案
Your service is missing the WebHttpBehavior
.
没有它,WebInvoke
属性什么也不做,并且路径"Datarows_IN"
无法识别为动作.
Without it, the WebInvoke
attribute does nothing, and the path "Datarows_IN"
is not recognized as an action.
以下是完整的(对我有用)服务主机代码:
Here's the full (works for me) service host code:
var binding = new WebHttpBinding()
{
Security = {
Mode = WebHttpSecurityMode.Transport
}
};
var baseUri = new Uri("https://localhost:443");
using (ServiceHost sh = new ServiceHost(typeof(Service1), baseUri))
{
var metadata = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (metadata == null) {
metadata = new ServiceMetadataBehavior();
sh.Description.Behaviors.Add(metadata);
}
metadata.HttpsGetEnabled = true;
var endpoint = sh.AddServiceEndpoint(typeof(IService1), binding, "/");
endpoint.EndpointBehaviors.Add(new WebHttpBehavior());
Console.WriteLine("Service is ready....");
sh.Open();
Console.WriteLine("Service started. Press <ENTER> to close.");
Console.ReadLine();
sh.Close();
}
这篇关于通过HTTPS向WCF自托管REST服务发出POST请求的示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!