Link to home
Start Free TrialLog in
Avatar of djbassam
djbassam

asked on

WCF method failing due to Xml containing ascii character 31

I have a .NET WCF service which communicates with a time and attendance clocking terminal.
The WCF service method is as follows:
   
[WebInvoke(UriTemplate = "/Status", Method = "POST")]
public Stream Status(XmlElement status)
{
   
    XmlDocument xml = new XmlDocument();
    xml.LoadXml(status.OuterXml);

    string terminal = xml.SelectSingleNode("/StatusResponse/@terminal").Value;
    string uid = xml.SelectSingleNode("/StatusResponse/@uid").Value;

    StringBuilder builder = new StringBuilder();
    builder.Append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
    builder.Append("<OperationStatus uid=\"" + uid + "\">OK</OperationStatus>");

    return new MemoryStream(Encoding.UTF8.GetBytes(builder.ToString()));
}

The WCF service is choking on ascii characters (ASCII 31) which are contained within the XML being sent from the terminal.
There is an error in XML document (3, 55), this is the ASCII 31 character after SR00 in the XML.

It is not possible to change the firmware on the terminal so I need to modify the WCF service to cope with the ascii characters.
If need be the ascii characters can be removed, however this must be done by the WCF service and not the client.

Details from Wireshark below :

POST /AccutouchService.svc/status HTTP/1.1
Host: 192.168.0.11
Accept: */*
Date: Sun, 26 Aug 2018 15:21:45 GMT
Authorization: ATS 000001714134:PASS
Content-Type: application/xml
Accept-Encoding: gzip
User-Agent: UCS-XML/3.0 ATS-MaximusColor/32x32/Suprema_Unifinger_SFM_3050
Transfer-Encoding: chunked

<?xml version="1.0" encoding="UTF-8"?>
<StatusResponse terminal="000001714134" uid="5b82beac-1234-1234-1234-0060950492fa">
<UcsStatus  ts="2018-08-07T23:21:29.000000+01:00">SR00.180807232129.Accu-Time Systems.6155/134.</UcsStatus>
</StatusResponse>

HTTP/1.1 400 Bad Request
Content-Type: text/html
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Sun, 26 Aug 2018 15:21:45 GMT
Content-Length: 2809

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Request Error</title>
    <style>BODY { color: #000000; background-color: white; font-family: Verdana; margin-left: 0px; margin-top: 0px; } #content { margin-left: 30px; font-size: .70em; padding-bottom: 2em; } A:link { color: #336699; font-weight: bold; text-decoration: underline; } A:visited { color: #6699cc; font-weight: bold; text-decoration: underline; } A:active { color: #336699; font-weight: bold; text-decoration: underline; } .heading1 { background-color: #003366; border-bottom: #336699 6px solid; color: #ffffff; font-family: Tahoma; font-size: 26px; font-weight: normal;margin: 0em 0em 10px -20px; padding-bottom: 8px; padding-left: 30px;padding-top: 16px;} pre { font-size:small; background-color: #e5e5cc; padding: 5px; font-family: Courier New; margin-top: 0px; border: 1px #f0f0e0 solid; white-space: pre-wrap; white-space: -pre-wrap; word-wrap: break-word; } table { border-collapse: collapse; border-spacing: 0px; font-family: Verdana;} table th { border-right: 2px white solid; border-bottom: 2px white solid; font-weight: bold; background-color: #cecf9c;} table td { border-right: 2px white solid; border-bottom: 2px white solid; background-color: #e5e5cc;}</style>
  </head>
  <body>
    <div id="content">
      <p class="heading1">Request Error</p>
      <p>The server encountered an error processing the request. The exception message is 'There is an error in XML document (3, 55).'. See server logs for more details. The exception stack trace is: </p>
      <p>   at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
   at System.ServiceModel.Dispatcher.UnwrappedTypesXmlSerializerManager.XmlSerializerXmlObjectSerializer.ReadObject(XmlDictionaryReader reader, Boolean verifyObjectName)
   at System.ServiceModel.Dispatcher.SingleBodyParameterMessageFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Message message, Object[] parameters)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&amp; rpc)
   at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)</p>
    </div>
  </body>
</html>
AccutouchService.svc.cs
IAccutouchService.cs
Web.config
Avatar of arnold
arnold
Flag of United States of America image

look for the char(31) and convert it.
See if the following provides an option:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/e72506df-20b1-4d51-a030-92e822b1ef49/how-to-pass-char-array-to-wcf-service-via-message-contract?forum=wcf

You may want to pull data first, then XML encode.
Avatar of djbassam
djbassam

ASKER

If I attempt to read the data in as a string (with the intention of stripping out the ASCII characters before converting it to an XmlElement
public Stream Status(string status)
     
I get the following error  

The server encountered an error processing the request. The exception message is 'Unable to deserialize XML body with root name 'StatusResponse' and root namespace '' (for operation 'Status' and contract ('IAccutouchService',  'http://tempuri.org/')) using DataContractSerializer. Ensure that the type corresponding to the XML is added to the known types collection of the service.'
You would need to carefully determine based on your original setup at which point char(31) triggers the issue. when you are trying to convert the esponse to string.
ionce you get the response,look through repacing char(31) with char(32) as an example... or stripping it completetly.
I guess the problem I have is where do I try to remove the ASCII 31 characters.

I don't think I can do it in the web method itself as the error is happening before it hits the code within the web method.
Before the event that triggers the issue.

add a proceed on error or continue on error
in an effort to determine when you get the response from the terminal, then one would commonly validate before proceeding.

Do not know whether the issue is during the xml to string coversion.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.