October 2009 Entries

I wanted  to consume  a  java webservice, so I wrote a WCF client to consume the service. I thought Java -.Net  interinteroperability would be easy with WCF, not so easy. 

The Java Web Service used WS-Security and required a UserNameToken passed as clear text.  The below code snippet  from Hanselman's blog will solve the problem, but there is a catch . This will work only if the endpoint address is on SSL. Ofcourse, WCF will not allow you to pass UserNameToken ( username & password) as clear text on http. It has to passed on https protocol, only then it will work . 

            

public void WCFMethod()
{

    WSHttpBinding myBinding = new WSHttpBinding();
    myBinding.Security.Mode 
        = SecurityMode.TransportWithMessageCredential;
    myBinding.Security.Message
    .ClientCredentialType = MessageCredentialType.UserName;
    myBinding.Security
    .Message.EstablishSecurityContext = false;

    myBinding.Security
    .Message.NegotiateServiceCredential = false;

    BindingElementCollection elements = myBinding.CreateBindingElements();
    elements
    .Find<SecurityBindingElement>().IncludeTimestamp = false;

    elements
    .Find<TextMessageEncodingBindingElement>()
    .MessageVersion = MessageVersion.Soap11;
    CustomBinding newBinding = new CustomBinding(elements);
    FooPortTypeClient svc = 
    new FooPortTypeClient(newBinding, 
    new EndpointAddress("https://javawebservice.com/service"));
}
 
 

 So, I had to go apply SSL on the webservice, to get this done. I digged more & was wondering if I could create a custom binding by getting my hands dirty. It turned out, there is already an open source custom binding, luckily I stumbled on  Yaron Naveh's  blog. He has writtern Clear Username Binding to solve the problem and is  hosted ongoogle code.  I hope this helps others like me. I used this binding get authenticated on http using WS-Security.

 

I don't know  if people are aware of the below exception. I wanted to throw some light on the issue, and help stranded people solve this issue.
Exception information:
Exception type: ArgumentException
Exception message: '', hexadecimal value 0x01, is an invalid character.

I support a web service which is heavily being used in the company, users who were consuming the web service where reporting problems that it was throwing some exception like above. After lot of investigation I solved the issue with  Bill's blog
Ascii control characters are not allowed in XML, they don't conform to xml specification.  So The .net framework when trying to serialize information with ascii control characters into XML , it throws an exception. These characters should not be allowed.

There are two ways to clean up the data and to remove the characters, you have to search the string , here is how you can do it.

 

/// <summary>
/// Remove illegal XML characters from a string.
/// </summary>
public string SanitizeXmlString(string xml)
{
    if (xml == null)
    {
        throw new ArgumentNullException("xml");
    }

    StringBuilder buffer = new StringBuilder(xml.Length);

    foreach (char c in xml)
    {
        if (IsLegalXmlChar(c))
        {
            buffer.Append(c);
        }
    }

    return buffer.ToString();
}
 
 

source : Bill's blog

 

Here is my version of the code using regex.

 
private string SanitizeXmlString(string xml)
{
 
   if (!string.IsNullOrEmpty(xml))
   {
     char[] hexp = new char[7] 
     { '\x00', '\x08', '\x10', '\x19', 
       '\x0B', '\x0F', '\x7F' };
     string pattern = string.Empty;
     pattern = string.Format("[{0}-{1}{2}-{3}{4}-{5}{6}]", 
     hexp[0], hexp[1], hexp[2], 
     hexp[3], hexp[4], hexp[5], hexp[6]);
     xml = Regex.Replace(xml, pattern, "");
    }
   
    return xml;  
}