odatawcf-data-servicesdataservicewcf-data-services-client

Consuming WCF Data Service EF , Failed to SaveChange()


I am consuming WCF Data Service as Following:

 DataMan.ContextWrapper context = new DataMan.ContextWrapper(new Uri("http://localhost:2060/PCM/DataMan.svc/rest/"));
            DataMan.Report newReport = DataMan.Report.CreateReport("123123123123", DateTime.Now, "999.199905171156550187000.25");

            newReport.Title = "tt";
            newReport.StudyAcDate = Convert.ToDateTime("2016-05-04 12:09:00");
            newReport.Body = "asdasd";
            newReport.Auther = "ali.h";
            newReport.ApproverComment = "cm";
            newReport.Approver = "admin";
            context.AddToReports(newReport);
            DataServiceResponse response = context.SaveChanges();

but after calling SaveChange() I have got the following error:

The server encountered an error processing the request. The exception message is 'Incoming message for operation 'ProcessRequestForMessage' (contract 'IRequestHandler' with namespace 'http://tempuri.org/') contains an unrecognized http body format value 'Xml'. The expected body format value is 'Raw'. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.'. See server logs for more details.

and my WCF Data Service is as following:

 public class ContextWrapper : DataAccessDbContext
{
    public ContextWrapper() : base("connection string")
    {

    }
}

[JSONPSupportBehavior]
public class DataMan : EntityFrameworkDataService<ContextWrapper>
{
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.SetEntitySetAccessRule("*", EntitySetRights.All);
        config.SetEntitySetAccessRule("Studies", EntitySetRights.None);
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.All);
        config.UseVerboseErrors = true; // TODO - Remove for production?
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
    }
    protected override void HandleException(HandleExceptionArgs args)
    {
        base.HandleException(args);
    }
}

I also implemented and configured WebContentTypeMapper to bypass mentioned Error as following:

 public class ContentTypeMapper : WebContentTypeMapper
{
    public override WebContentFormat GetMessageFormatForContentType(string contentType)
    {
        return WebContentFormat.Raw;
    }
} 

Custom binding:

   <binding name="XmlMapper">
      <webMessageEncoding webContentTypeMapperType="MARCO.SOA.PCMServiceLib.ContentTypeMapper,MARCO.SOA.PCMServiceLib.Core"/>
      <httpTransport manualAddressing="true"/>
    </binding>
  </customBinding>

Service endpoint:

 <service behaviorConfiguration="Commom2.Behavior" name="MARCO.SOA.PCMServiceLib.DataMan">
    <endpoint address="rest" behaviorConfiguration="Rest.Behavior" binding="webHttpBinding" 
              bindingConfiguration="XmlMapper" contract="System.Data.Services.IRequestHandler">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:2060/PCM/DataMan.svc"/>
      </baseAddresses>
    </host>
  </service>

but it still get exception, I think something went wrong with my configuration.

Any help would be truly appreciated.

Thanks in advance.


Solution

  • okay, after much trouble I finally solved the problem, so we need to initiate factory property for serviceActivation

    So my relative address was:

    <serviceHostingEnvironment>
      <serviceActivations>
    .
    .
    .
       <add relativeAddress="DataMan.svc" service="MARCO.SOA.PCMServiceLib.DataMan"/>
    .
    .
    .
      </serviceActivations>
    </serviceHostingEnvironment>
    

    and I have changed it to

    <serviceHostingEnvironment>
      <serviceActivations>
    .
    .
    .
        <add relativeAddress="DataMan.svc" service="MARCO.SOA.PCMServiceLib.DataMan" factory="System.Data.Services.DataServiceHostFactory, Microsoft.Data.Services, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    .
    .
    .
      </serviceActivations>
    </serviceHostingEnvironment>
    

    now everything is now working nice.

    more info about DataServiceHostFactory

    Note: By this we don't need to override GetMessageFormatForContentType of WebContentTypeMapper and force it to return WebContentFormat.Raw or another content format and don't need any customBinding in config file.

    Thanks to all.