kbbucks
kbbucks

Reputation: 138

WCF Restful Service exception on POST Unrecognized charSet 'Windows-1252' in contentType

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.

Upvotes: 0

Views: 1534

Answers (1)

Simon Mourier
Simon Mourier

Reputation: 138776

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

Upvotes: 1

Related Questions