我正在尝试调用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 :(得分: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。
我不知道是否还有其他方法可以做到这一点。
答案 1 :(得分:1)
我得到了这一点,感谢2GDev的评论。代码没有正确处理异常或异常情况。
这样我就可以使用生成的stub的端点(从而重用config等)。
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的基本ICalculator样本时 http://msdn.microsoft.com/en-us/library/ms734712.aspx
使用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.
答案 2 :(得分:0)
我认为你可以使用
ListProductsRequest request = (ListProductsRequest) new XmlSerializer(
typeof(ListProductsRequest)).Deserialize();
创建相应的对象......