2017-04-26 48 views
0

消失我有属性Name我在WCF用来传送一个模型(通信)的对象A空间上通过WCF转印(XML)

[DataMember(IsRequired = false, EmitDefaultValue = false, Name = "p0", Order = 0)] 
public string Name { get; set; } 

我discoverd当Name开始与当时在另一边它已经失去了空间,并成为“123” deserialisation后空间“123”。

的WCF服务使用MTOM消息编码。

这是在一般的XML或WCF已知的效果呢?

的答案的帮助下提供我发现,领先的空格是由于MTOM编码中删除。事实上,当我删除Mtom时,领先的空白区域被正确转移。

的安全配置并没有我的情况下起到任何作用。

有没有办法避免它?

+0

您必须对XML名称进行编码。 http://stackoverflow.com/questions/1091945/what-c​​haracters-do-i-need-to-escape-in​​-xml-documents –

+0

从来没有听说过这样的事情,并会惊讶,如果这是别的一个错误。客户端和服务器都是使用WCF的.NET吗? –

+0

@KevinRaffay肯定不是。 (Net)DataContractSerializer(“WCF”)将为您做到这一点。 –

回答

1

UPDATE:因为很清楚您使用的是MTOM,所以将其替换为答案。

显然这是WCF中的bug,根据this被标记为“延迟”。所以很难说,什么时候它会被修复。最后一个链接还提到了一些解决方法,我将在这里重现,以便他们不会迷路。

  1. 不要使用MTOM
  2. 添加一些前缀字符发送者和接收者了解,并且然后接收器可以剥离(如报价等)。
  3. 使用消息检查和缓冲消息

下面的代码显示了这个问题的第三个解决方法:

public class Post_4cfd1cd6_a038_420d_8cb5_ec5a2628df1a 
{ 
    [ServiceContract] 
    public interface ITest 
    { 
     [OperationContract] 
     string Echo(string text); 
    } 
    public class Service : ITest 
    { 
     public string Echo(string text) 
     { 
      Console.WriteLine("In service, text = {0}", ReplaceControl(text)); 
      return text; 
     } 
    } 
    static Binding GetBinding() 
    { 
     //var result = new WSHttpBinding(SecurityMode.None) { MessageEncoding = WSMessageEncoding.Text }; 
     var result = new BasicHttpBinding() { MessageEncoding = WSMessageEncoding.Mtom }; 
     return result; 
    } 
    static string ReplaceControl(string text) 
    { 
     StringBuilder sb = new StringBuilder(); 
     foreach (var c in text) 
     { 
      if ((' ' <= c && c <= '~') && c != '\\') 
      { 
       sb.Append(c); 
      } 
      else 
      { 
       sb.AppendFormat("\\u{0:X4}", (int)c); 
      } 
     } 

     return sb.ToString(); 
    } 
    public class MyInspector : IEndpointBehavior, IDispatchMessageInspector, IClientMessageInspector 
    { 
     public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) 
     { 
     } 

     public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) 
     { 
      clientRuntime.MessageInspectors.Add(this); 
     } 

     public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) 
     { 
      endpointDispatcher.DispatchRuntime.MessageInspectors.Add(this); 
     } 

     public void Validate(ServiceEndpoint endpoint) 
     { 
     } 

     public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) 
     { 
      request = request.CreateBufferedCopy(int.MaxValue).CreateMessage(); 
      return null; 
     } 

     public void BeforeSendReply(ref Message reply, object correlationState) 
     { 
     } 

     public void AfterReceiveReply(ref Message reply, object correlationState) 
     { 
      reply = reply.CreateBufferedCopy(int.MaxValue).CreateMessage(); 
     } 

     public object BeforeSendRequest(ref Message request, IClientChannel channel) 
     { 
      return null; 
     } 
    } 
    public static void Test() 
    { 
     string baseAddress = "http://" + Environment.MachineName + ":8000/Service"; 
     ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress)); 
     var endpoint = host.AddServiceEndpoint(typeof(ITest), GetBinding(), ""); 
     endpoint.Behaviors.Add(new MyInspector()); 
     host.Open(); 
     Console.WriteLine("Host opened"); 

     ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress)); 
     factory.Endpoint.Behaviors.Add(new MyInspector()); 
     ITest proxy = factory.CreateChannel(); 

     string input = "\t\tDoc1\tCase1\tActive"; 
     string output = proxy.Echo(input); 
     Console.WriteLine("Input = {0}, Output = {1}", ReplaceControl(input), ReplaceControl(output)); 
     Console.WriteLine("input == output: {0}", input == output); 

     ((IClientChannel)proxy).Close(); 
     factory.Close(); 

     Console.Write("Press ENTER to close the host"); 
     Console.ReadLine(); 
     host.Close(); 
    } 
} 

再次,真正的答案和代码是从here

+0

这是HTTP与MTOM绑定名称=“BasicHttpBinding”closeTimeout =“00:01:00”openTimeout =“00:01:00”receiveTimeout =“00:01:00”sendTimeout =“00:01:00”maxBufferPoolSize =“2147483647”maxBufferSize =“2147483647”maxReceivedMessageSize =“2147483647”transferMode =“Streamed”useDefaultWebProxy =“true”messageEncoding =“Mtom”' – Gerard

+0

还有'security mode =“None”'这是您的第二个链接中的mentiod。 – Gerard

+0

所以,你有它;-) –