我想在我的肥皂信封中添加一个命名空间设置。 我想在IClientMessageInspector的BeforeSendRequest中更改它,或者您有一种更优雅的方法。
例如
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<wsa:To xmlns="http://www.w3.org/2005/08/addressing">ws://xxx/V1</wsa:To>
...
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
...
</s:Body>
</s:Envelope>
到
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing">
...
请帮助我!
谢谢!
答案 0 :(得分:0)
我通常这样使用xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication91
{
class Program
{
static void Main(string[] args)
{
string ws = "http://www.w3.org/2005/08/addressing";
string xml = string.Format(
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>" +
"<s:Envelope xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\">" +
"<s:Header>" +
"<wsa:Address xmlns:wsa=\"{0}\">ws://xxx/V1</wsa:Address>" +
"</s:Header>" +
"<s:Body>" +
"</s:Body>" +
"</s:Envelope>",
ws);
XDocument doc = XDocument.Parse(xml);
XElement header = doc.Descendants().Where(x => x.Name.LocalName == "Header").FirstOrDefault();
XElement body = doc.Descendants().Where(x => x.Name.LocalName == "Body").FirstOrDefault();
}
}
}
答案 1 :(得分:0)
根据您的描述,我认为您可以使用WCF消息检查器。在客户端发送消息之前。我们可以自定义消息正文。
https://docs.microsoft.com/en-us/dotnet/framework/wcf/samples/message-inspectors
我做了一个演示,希望对您有用。
服务器端。
class Program
{
static void Main(string[] args)
{
Uri uri = new Uri("http://localhost:1500");
BasicHttpBinding binding = new BasicHttpBinding();
binding.TransferMode = TransferMode.Buffered;
binding.Security.Mode = BasicHttpSecurityMode.None;
ServiceHost sh = new ServiceHost(typeof(Calculator),uri);
sh.AddServiceEndpoint(typeof(ICalculator), binding, "");
ServiceMetadataBehavior smb;
smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
if (smb == null)
{
smb = new ServiceMetadataBehavior();
//smb.HttpGetEnabled = true;
sh.Description.Behaviors.Add(smb);
}
Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "MEX");
sh.Open();
Console.Write("Service is ready....");
Console.ReadLine();
sh.Close();
}
}
[ServiceContract]
public interface ICalculator
{
[OperationContract,WebGet]
double Add(double a, double b);
}
public class Calculator : ICalculator
{
public double Add(double a, double b)
{
return a + b;
}
}
客户。
class Program
{
static void Main(string[] args)
{
ServiceReference2.CalculatorClient client = new ServiceReference2.CalculatorClient();
try
{
var result = client.Add(34, 20);
Console.WriteLine(result);
}
catch (Exception)
{
throw;
}
}
}
public class ClientMessageLogger : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState)
{
string result = $"server reply message:\n{reply}\n";
Console.WriteLine(result);
}
public object BeforeSendRequest(ref Message request, IClientChannel channel)
{
XmlDocument doc = new XmlDocument();
MemoryStream ms = new MemoryStream();
XmlWriter writer = XmlWriter.Create(ms);
request.WriteMessage(writer);
writer.Flush();
ms.Position = 0;
doc.Load(ms);
ChangeMessage(doc);
ms.SetLength(0);
writer = XmlWriter.Create(ms);
doc.WriteTo(writer);
writer.Flush();
ms.Position = 0;
XmlReader reader = XmlReader.Create(ms);
request = System.ServiceModel.Channels.Message.CreateMessage(reader, int.MaxValue, request.Version);
string result = $"client ready to send message:\n{request}\n";
Console.WriteLine(result);
return null;
}
void ChangeMessage(XmlDocument doc)
{
XmlElement element = (XmlElement)doc.GetElementsByTagName("s:Envelope").Item(0);
if (element != null)
{
element.SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
element.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
}
}
}
public class CustContractBehaviorAttribute : Attribute, IContractBehavior, IContractBehaviorAttribute
{
public Type TargetContract => typeof(ICalculator);
public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
{
return;
}
public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
{
clientRuntime.ClientMessageInspectors.Add(new ClientMessageLogger());
}
public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
{
return;
}
public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
{
return;
}
}
别忘了将CustContract行为应用于服务界面。
[CustContractBehavior]
public interface ICalculator {
答案 2 :(得分:0)
有一种更好的方法可以在WCF中向SOAP消息添加名称空间或前缀。使用自定义MessageFormatter。看这些文章: 对于客户端 https://weblog.west-wind.com/posts/2016/apr/02/custom-message-formatting-in-wcf-to-add-all-namespaces-to-the-soap-envelope#ClientMessageFormatter
对于服务端 https://www.vanacosmin.ro/Articles/Read/WCFEnvelopeNamespacePrefix