9

I've been trying out the StandardEndpoints that were introduced as part of .Net 4 and I'm getting the most peculiar of errors.

My code

[ServiceContract]
public interface IAuthenticator
{
    [OperationContract]
    [WebInvoke(UriTemplate = "AuthenticateUser", Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
    AuthPacket AuthenticateUser(string Username, string Password, string DeviceId);
}

My web.config

<system.web>
  <compilation debug="true" targetFramework="4.0" />
</system.web>

<system.webServer>
  <modules runAllManagedModulesForAllRequests="true">
  </modules>
</system.webServer>

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
  <standardEndpoints>
    <webHttpEndpoint>
      <!--
          Configure the WCF REST service base address via the global.asax.cs file and the default endpoint
          via the attributes on the <standardEndpoint> element below
      -->
      <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
    </webHttpEndpoint>
  </standardEndpoints>
</system.serviceModel>

The exception that is driving me crazy!

415 Cannot process the message because the content type 'application/json' was not 
the expected type 'text/xml; charset=utf-8'.

I can make the problem going away by going back to the .Net 3.5 standard of declaring each service, but, unless I am mistaken, one of the major upgrades in WCF with .Net 4 was it's ability to handle stuff like this. Am I doing something wrong?

thaBadDawg
  • 5,160
  • 6
  • 35
  • 44
  • Do you tried remove `BodyStyle = WebMessageBodyStyle.WrappedRequest` attribute? How you host the WFC service? Do you use .svc? Which `factory` do you use in the .svc file? – Oleg Feb 15 '11 at 16:15
  • This is wrapped in a .svc file without a factory defined. – thaBadDawg Feb 15 '11 at 17:01
  • 6
    You should try to use .svc with the factory `"System.ServiceModel.Activation.WebServiceHostFactory"` or include additional section in the web.config which do the same without .svc file. See http://stackoverflow.com/questions/4680162/host-wcf-in-mvc2-site/4680617#4680617 for details. Moreover it could help if you include client code (jQuery.ajax or what you use) which follows to the described error message. – Oleg Feb 15 '11 at 17:26
  • Do you have any progress to solve the problem? – Oleg Feb 17 '11 at 00:20

1 Answers1

7

If I read this operation contract correctly, you have defined JSON to be your response format - but not your request format:

[ServiceContract]
public interface IAuthenticator
{
    [OperationContract]
    [WebInvoke(UriTemplate = "AuthenticateUser", Method = "POST", 
     BodyStyle = WebMessageBodyStyle.WrappedRequest, 
     ResponseFormat = WebMessageFormat.Json)]
    AuthPacket AuthenticateUser(string Username, string Password, string DeviceId);
}

Could that be the problem?? What happens if you add RequestFormat = WebMessageFormat.Json to your operation contract ??

[ServiceContract]
public interface IAuthenticator
{
    [OperationContract]
    [WebInvoke(UriTemplate = "AuthenticateUser", Method = "POST", 
     BodyStyle = WebMessageBodyStyle.WrappedRequest, 
     RequestFormat = WebMessageFormat.Json,   <== ADD THIS HERE TO YOUR CODE !
     ResponseFormat = WebMessageFormat.Json)]
    AuthPacket AuthenticateUser(string Username, string Password, string DeviceId);
}

Update: if you're using WCF 4 "out of the box", its protocol mapping will associate the http:// scheme with basicHttpBinding.

To fix this, you need to override the default protocol mapping like this (in your web.config):

Default Protocol Mapping

The answer to this question is simple. WCF defines a default protocol mapping between transport protocol schemes (e.g., http, net.tcp, net.pipe, etc) and the built-in WCF bindings. The default protocol mapping is found in the .NET 4 machine.config.comments file and it looks like this:

<system.serviceModel>
   <protocolMapping>
       <add scheme="http" binding="webHttpBinding" bindingConfiguration="" />
   </protocolMapping>

Now, by default http://..... would be mapped to webHttpBinding.

(taken from: A Developer's Introduction to Windows Communication Foundation 4 )

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • I actually had it that way in an earlier version of the code and it was still kicking back the same problem. The thing that kills me is that when I explicitly declare the services in my web.config everything works. – thaBadDawg Feb 15 '11 at 16:19
  • @thaBadDawg: well, .NET 4 has those standard endpoints - the default mapping for the `http://` scheme is to use `basicHttpBinding`, however. So unless you've changed that mapping, when you use an `http://somethingoranother.......` address, WCF 4 will default to `basicHttpBinding` - **not** `webHttpBinding` – marc_s Feb 15 '11 at 16:22
  • 2
    When I switch over to use the protocol mapping I get this exception : The message with To 'http://localhost/TokenAuthProvider/Authenticator.svc/AuthenticateUser' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree. – thaBadDawg Feb 15 '11 at 17:02
  • 1
    This doesn't seem to work for me. Getting 500 now instead of 415. – JohnOpincar Jan 30 '14 at 19:39