C# 如何在WCFSOAP方法上实现curl-GET?

C# 如何在WCFSOAP方法上实现curl-GET?,c#,web-services,wcf,curl,soap,C#,Web Services,Wcf,Curl,Soap,我有一个使用WCF公开的服务,运行在SLES盒中的Mono上。我正在使用BasicHttpBinding进行此操作。现在,我有一个简单返回布尔值的方法,我想从SLES框本身调用这个方法,并得到布尔值。我正在尝试使用curl来实现这一点,但到目前为止,我还没有成功调用该方法 假设我的服务称为“RemoteService”,我想调用的方法是“CheckProcessRunning”。同样,CheckProcessRunning只返回一个布尔值,而且返回速度非常快 所以我试过: curl -H "Co

我有一个使用WCF公开的服务,运行在SLES盒中的Mono上。我正在使用BasicHttpBinding进行此操作。现在,我有一个简单返回布尔值的方法,我想从SLES框本身调用这个方法,并得到布尔值。我正在尝试使用curl来实现这一点,但到目前为止,我还没有成功调用该方法

假设我的服务称为“RemoteService”,我想调用的方法是“CheckProcessRunning”。同样,CheckProcessRunning只返回一个布尔值,而且返回速度非常快

所以我试过:

curl -H "Content-Type: text/xml; charset=utf-8" -H "SOAPAction:" -X GET http://localhost:4000/RemoteService/CheckProcessRunning

curl --header "Content-Type: text/xml;charset=UTF-8" --header "SOAPAction:RemoteService/CheckProcessRunning" http://localhost:4000/RemoteService/CheckProcessRunning

curl --header "Content-Type: text/xml;charset=UTF-8" --header "SOAPAction:url:CheckProcessRunning" http://localhost:4000/RemoteService
全部返回如下内容:

a:destinationUnreachable请求消息具有目标http://localhost:4000/RemoteService/CheckProcessRunning“使用此服务合同中无法访问的操作”


所以我的问题是,如何在WCF服务中对SOAP方法执行curl请求?我需要使用BasicHttpBinding来执行此操作-我已经查看了WebHttpBinding,但我发现我无法使用它,因为它破坏了其他功能。

您帖子中的错误消息称操作为空白或空。因此,一个解决方案可能是更改您的服务以支持空操作。服务需要通过查看请求主体来确定调用哪个方法。幸运的是,在中有一个这样的例子,并且有很好的使用信息

还有一篇文章提到cURL并专门针对空操作裁剪了相同的示例:。功劳必须归于原作者,但对于后代来说,这是代码

在操作合同中指定空操作:

[OperationContract(Action="")]
ResponseMessage DoOperationA(RequestMessage message);

[OperationContract(Action="")]
ResponseMessage DoOperationB(RequestMessage message);
EmptyActionBehaviorAttribute
类添加到服务项目:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface)]
public class EmptyActionBehaviorAttribute : Attribute, IContractBehavior
{
    public void AddBindingParameters(
        ContractDescription contractDescription, 
        ServiceEndpoint endpoint, 
        BindingParameterCollection bindingParameters)
    {
        return;
    }

    public void ApplyClientBehavior(
        ContractDescription contractDescription, 
        ServiceEndpoint endpoint, 
        ClientRuntime clientRuntime)
    {
        return;
    }

    public void ApplyDispatchBehavior(
        ContractDescription contractDescription, 
        ServiceEndpoint endpoint, 
        DispatchRuntime dispatchRuntime)
    {
        var dispatchDictionary = new Dictionary<XmlQualifiedName, string>();

        foreach (var operationDescription in contractDescription.Operations)
        {
            var qname = new XmlQualifiedName(
                operationDescription.Messages[0].Body.WrapperName, 
                operationDescription.Messages[0].Body.WrapperNamespace);

            dispatchDictionary.Add(qname, operationDescription.Name);
        }

        dispatchRuntime.OperationSelector 
            = new EmptyActionOperationSelector(dispatchDictionary);
    }

    public void Validate(
        ContractDescription contractDescription, 
        ServiceEndpoint endpoint)
    {
    }
}
class EmptyActionOperationSelector : IDispatchOperationSelector
{
    Dictionary<XmlQualifiedName, string> dispatchDictionary;

    public EmptyActionOperationSelector(
        Dictionary<XmlQualifiedName, string> dispatchDictionary)
    {
        this.dispatchDictionary = dispatchDictionary;            
    }

    public string SelectOperation(ref System.ServiceModel.Channels.Message message)
    {
        var xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(message.ToString());

        var nsManager = new XmlNamespaceManager(xmlDoc.NameTable);
        nsManager.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");

        XmlNode node = xmlDoc.SelectSingleNode(
            "/soapenv:Envelope/soapenv:Body", 
            nsManager).FirstChild;

        var lookupQName = new XmlQualifiedName(node.LocalName, node.NamespaceURI);

        return dispatchDictionary.ContainsKey(lookupQName)
            ? dispatchDictionary[lookupQName]
            : node.LocalName;           
    }
}
最后,在服务合同上使用新属性:

[ServiceContract]
[XmlSerializerFormat(Style = OperationFormatStyle.Rpc, Use = OperationFormatUse.Encoded)]
[EmptyActionBehavior]
public interface IMyService

因此,以下是它的工作原理:

我将WebInvoke装饰添加到WCF接口,以指定请求和响应的方法和格式:

[OperationContract]
[WebInvoke(Method = "GET", RequestFormat = WebMessageFormat.Json,
       ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]
bool CheckProcessRunning();
我还使用WebServiceHost初始化了另一个主机(使用不同的端口)以将我的接口公开为REST服务:

string webHttpAddress = "http://localhost:4001/RemoteService";
WebServiceHost webServiceHost = new WebServiceHost(typeof(RemoteService), new Uri[] { new Uri(webHttpAddress) });

webServiceHost.AddServiceEndpoint(typeof(IRemoteService), new WebHttpBinding(WebHttpSecurityMode.None), webHttpAddress);
webServiceHost.Open();
现在我可以使用curl调用CheckProcessRunning方法:

curl http://localhost:4001/RemoteService/CheckProcessRunning
true

我这样做了,但到目前为止还不能使它工作。我在使用以下curl命令时收到此错误消息:
curl-H“内容类型:text/xml;charset=utf-8“-H”SOAPAction:“-X得到http://localhost:4000/RemoteService/CheckProcessRunning
a:destinationUnreachable请求消息具有目标的http://localhost:4000/RemoteService/CheckProcessRunning“使用此服务合同中无法访问的操作“”
确定,您可以安装吗?您可以使用它来获取从cURL发送的请求详细信息,也可以从那里成功调用服务。查找失败请求和成功请求之间的差异。同时将请求详细信息添加到问题中。。。然后再给我留言;)