0

I've created a WCF Restful Service which works fine in most circumstances:

[OperationContract(Name = "OrderResponse")]
[WebInvoke(Method = "POST", UriTemplate = "OrderResponse")]
void PostOrderResponse(Stream ordata);

However if the content-type of the incoming request is set to the following:

"text/xml; charset=Windows-1252"

the client POST to the api gets a HTTP Response 400 and the following shows up in the wcf trace logs:

The default content type mapper selected the request format, 'Xml', given the request's content-type, 'text/xml; charset=Windows-1252'.

Unrecognized charSet 'Windows-1252' in contentType.

I'm pretty sure the error is being thrown before any code is called as the code behind will either set the response to HTTP 202 or 406 depending on what is sent through or if any error is thrown:

    public void PostOrderResponse(Stream ordata)
    {
        try
        {
            // convert Stream Data to byte array
            using (var streamReader = new MemoryStream())
            {
                ordata.CopyTo(streamReader);
                data = streamReader.ToArray();
            }
            //if no data reject (http response)
            if (data.Length == 0)
            {
                SetResponseHttpStatus(HttpStatusCode.NotAcceptable);
            }
            else
            {   //convert byte[] to string
                xmlString = enc.GetString(data);
                conl = new SqlConnection(strConnString);
                conl.Open();
                SqlCommand cmdl = new SqlCommand("Insert_MSXML_MS_POR", conl);
                cmdl.CommandType = CommandType.StoredProcedure;
                cmdl.Parameters.Add(new SqlParameter("@DATA", xmlString));
                SqlDataReader sdrl = cmdl.ExecuteReader();
                sdrl.Close();
                conl.Close();

                SetResponseHttpStatus(HttpStatusCode.Accepted);
            }
        }
        catch
        {
            SetResponseHttpStatus(HttpStatusCode.NotAcceptable);
        }
        data = null;
    }

Relevant Web.config data:

<services>
  <service name="MWHMSXML_v1.MSXML" behaviorConfiguration="MSXML_Connect" >
    <endpoint address="" binding="webHttpBinding" contract="MWHMSXML_v1.IMSXML" bindingConfiguration="secureHttpBinding" behaviorConfiguration="webHttp" />
    <endpoint name="mexHttpsBinding" address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
  </service>
</services>

<bindings>

    <webHttpBinding>
        <binding name="secureHttpBinding">
            <security mode="Transport">
                <transport clientCredentialType="None"/>
            </security>
        </binding>
    </webHttpBinding>

</bindings>

Do I need to add something to the web.config file to accept the Window-1252 charset or how can I overcome this error?

EDIT I think I'm getting closer, I followed the instructions etc for creating a customtextmessageencoder and it seems to be working to a point. Looking through the trace logs the request (using 'Windows-1252' encoding) is hitting the correct endpoint but fails after opening the 'System.ServiceModel.InstanceContext' with the following error:

Incoming message for operation 'OrderResponse' (contract 'IMSXML' with namespace 'MWHMSXML_v1')does not contain a WebBodyFormatMessageProperty. This can be because a WebContentTypeMapper or a WebMessageEncodingBindingElement has not been configured on the binding. See the documentation of WebContentTypeMapper and WebMessageEncodingBindingElement for more details.

I've a feeling it's something to do with my web.config, the relevant bits are here:

<service name="MWHMSXML_v1.MSXML" behaviorConfiguration="MSXML_Connect" >
    <endpoint address="" binding="customBinding" contract="MWHMSXML_v1.IMSXML "bindingConfiguration="customHttpBinding" behaviorConfiguration="webEndpoint"/>
<endpoint name="mexHttpsBinding" address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>

<customBinding>
    <binding name="customHttpBinding" transferMode="Buffered" maxReceivedMessageSize="10485760">
        <customTextMessageEncoding encoding="Windows-1252" mediaType="text/Xml" messageVersion="None"/>
    <httpsTransport manualAddressing="true" />
    </binding>
</customBinding>

<bindingElementExtensions>
    <add name="customTextMessageEncoding" type=" MWHMSXML_v1.CustomTextMessageEncodingBindingSection, MWHMSXML_v1" />
</bindingElementExtensions>

<serviceBehaviors>
    <behavior name="MSXML_Connect"> <serviceCredentials> <serviceCertificate findValue="*.myurl.com" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" /> </serviceCredentials> <serviceMetadata httpsGetEnabled="false" /><serviceDebug includeExceptionDetailInFaults="true"/></behavior>  </serviceBehaviors>

I've searched & searched but can't find any info that's helpful with the above error.

kbbucks
  • 108
  • 8
  • You should enable WCF traces and look at the detailed errors: http://stackoverflow.com/questions/4271517/how-to-turn-on-wcf-tracing – Simon Mourier Jun 28 '14 at 05:07
  • I have tracing on - this is what's throwing the error: "Unrecognized charSet 'Windows-1252' in contentType." It seems WCF only recognizes UTF encoding by default so I'm trying to find a way of getting my service to recognize 'Windows-1252' encoding which a certain client is sending their requests through with. – kbbucks Jun 28 '14 at 23:26

1 Answers1

1

As per the official documentation here: Choosing a Message Encoder, WCF's default TextMessageEncoder only supports UTF-8, UTF-16:

TextMessageEncodingBindingElement and MtomMessageEncodingBindingElement support only the UTF8 and UTF16 Unicode (big-endian and little-endian) encodings. If other encodings are required, such as UTF7 or ASCII, a custom encoder must be used. For a sample custom encoder, see Custom Message Encoder.

And there is a link to a custom message encoder sample: Custom Message Encoder: Custom Text Encoder (it uses the ISO-8859-1 encoding, but you get the idea)

See also this blog post: Text Encoding and WCF

Simon Mourier
  • 132,049
  • 21
  • 248
  • 298
  • Thanks for the info Simon - I've added the custom encoder based on the custom message encoder example above but am now getting: "System.InvalidOperationException: For request in operation Receipt to be a stream the operation must have a single parameter whose type is Stream." no matter what sort of content-type I send through - any ideas? As an fyi I'm a Java developer dipping my toes in the .net sea! – kbbucks Jun 30 '14 at 00:11