2011-09-21 199 views
4

我正在尝试调用WCF服务。用XML调用WCF服务

但是,我有请求正文作为XML文档。

因此,例如,而不是此

ListProductsRequest request = new ListProductsRequest(); 
request.Query = new RootQuery(); 
request.Query.Product = "milk"; 
request.Query.Group = "dairy"; 

ListProductsPortType client = new ListProductsPortTypeClient(); 
ListProductsResponse response = client.ListProducts(request); 

我想这样做:

String xml = "<Root xmlns=\"urn:ns\"><Query><Group>dairy</Group><Product>milk</Product></Query></Root>"; 
var request = // read in to XmlReader or XmlDocument or whatever 
ListProductsPortType client = new ListProductsPortTypeClient(); 
var response = client.ListProducts(request); 

是否有使用生成的代理的方式,与具有数据层安全性的优势,运输为我处理,但不使用代理对象?

感谢, 布莱希特

+0

这是一个REST服务?如果是这样,那么你可以直接使用WebClient。 – alf

+0

不,这是一个基于NetTCP的SPNego等SOAP服务。手动操作太复杂了。 我做了类似的事情,我想使用Axis2服务客户端,但不幸的是Axis2不支持SPNego,所以我试图在.NET中创建一些通用的调用WCF服务以避免互操作性问题。 编辑:更多解释+打字 –

+0

我正在寻找一种方法来解决您的问题,并发现这: http://social.msdn.microsoft.com/forums/en-US/wcf/thread/ad917cdd-60d4- 404c-a529-10597ff1bbf8/ 这可能是一个解决方案...使用该消息并将其传递到一个通道让你 选择如何格式化消息。 这里有一个Message.Create的例子 http://www.c-sharpcorner.com/UploadFile/dhananjaycoder/7893/ – 2GDev

回答

1

我不认为你可以调用WCF服务,并通过你想要什么。

方法ListProducts只接受一个ListProductsRequest对象。所以你必须创建这种对象。

String xml = "<Root xmlns=\"urn:ns\"><Query><Group>dairy</Group><Product>milk</Product></Query></Root>"; 
ListProductsRequest request = MappingObject(xml); 
ListProductsPortType client = new ListProductsPortTypeClient(); 
var response = client.ListProducts(request); 

而在Mapping方法中,您可以使用XML来创建ListproductRequest。

我不知道是否有另一种方式来做到这一点。

+0

它不是真的'我想要的',xml进入对应100%的消息合约在wsdl中。 –

+0

@布雷希特对不起,你是对的... – 2GDev

+0

不需要道歉:) –

0

我想你可以使用

ListProductsRequest request = (ListProductsRequest) new XmlSerializer(
    typeof(ListProductsRequest)).Deserialize(); 

创建相应的对象...

+0

谢谢。这个问题是我从其他地方获取XML,我希望这是通用的。反序列化方法告诉我XML文档存在问题('Root'不是预期的),虽然我可以通过简单的XML读取它。 我怀疑这是因为ListProductsRequest有一个指定Wrapper元素名称的属性,并且这不是XmlSerializer所期望的。 [System.ServiceModel.MessageContractAttribute(WrapperName =“Root”,WrapperNamespace =“urn:ns”,IsWrapped = true)] –

+0

使用此博客帖子,我能够反序列化请求。 http://wcfpro.wordpress.com/2010/11/24/customxmlobjectserializer/ –

1

我能走到今天,得益于2GDev的评论。代码没有正确处理异常或异常情况。

这样我可以使用生成的存根的端点(从而重用配置等)

public void CallWs() 
    { 
     WsdlRDListProductsPortTypeClient client = new WsdlRDListProductsPortTypeClient(); 

     String req = "<Root xmlns=\"urn:ns\"><Query><Group>TV</Group><Product>TV</Product></Query></Root>"; 

     CallWs(client.Endpoint, "ListProducts", GetRequestXml(req)); 
    } 

    public XmlElement CallWs(ServiceEndpoint endpoint, String operation, XmlElement request) 
    { 
     String soapAction = GetSoapAction(endpoint, operation); 

     IChannelFactory<IRequestChannel> factory = null; 

     try 
     { 
      factory = endpoint.Binding.BuildChannelFactory<IRequestChannel>(); 
      factory.Open(); 
      IRequestChannel channel = null; 

      try 
      { 
       channel = factory.CreateChannel(endpoint.Address); 
       channel.Open(); 

       Message requestMsg = Message.CreateMessage(endpoint.Binding.MessageVersion, soapAction, request); 
       Message response = channel.Request(requestMsg); 
       return response.GetBody<XmlElement>(); 
      } 
      finally 
      { 
       if (channel != null) 
        channel.Close(); 
      } 
     } 
     finally 
     { 
      if (factory != null) 
       factory.Close(); 
     } 
    } 

    private String GetSoapAction(ServiceEndpoint endpoint, String operation) 
    { 

     foreach (OperationDescription opD in endpoint.Contract.Operations) 
     { 
      if (opD.Name == operation) 
      { 
       foreach (MessageDescription msgD in opD.Messages) 
        if (msgD.Direction == MessageDirection.Input) 
        { 
         return msgD.Action; 
        } 
      } 

     } 

     return null; 
    } 

当我尝试这个来自MSDN http://msdn.microsoft.com/en-us/library/ms734712.aspx

基本ICalculator样品,其固定用SPNego,我必须改变这一点,因为那样我们需要一个IRequestSessionChannel而不是一个IRequestChannel。

public XmlElement CallWs(ServiceEndpoint endpoint, String operation, XmlElement request) 
    { 
     String soapAction = GetSoapAction(endpoint, operation); 

     IChannelFactory<IRequestSessionChannel> factory = null; 

     try 
     { 


      factory = endpoint.Binding.BuildChannelFactory<IRequestSessionChannel>(); 
      factory.Open(); 
      IRequestSessionChannel channel = null; 

      try 
      { 
       channel = factory.CreateChannel(endpoint.Address); 
       channel.Open(); 

       Message requestMsg = Message.CreateMessage(endpoint.Binding.MessageVersion, soapAction, request); 

       Message response = channel.Request(requestMsg); 
       return response.GetBody<XmlElement>(); 
      } 
      finally 
      { 
       if (channel != null) 
        channel.Close(); 
      } 
     } 
     finally 
     { 
      if (factory != null) 
       factory.Close(); 
     } 
    } 

它所做的谈判,和消息似乎被发送,但不幸的是我现在得到了以下错误消息:

No signature message parts were specified for messages with the 'http://Microsoft.ServiceModel.Samples/ICalculator/Add' action. 
+0

最后,我刚刚使用http://wcfpro.wordpress.com/2010/11/24/将xml反序列化为代理对象customxmlobjectserializer /并使用这些。 –