2

I have a WebHttpBinding WCF service that I am calling. My first POST method send the object correctly, but subsequent calls to POST methods are passing null for the object.

Here is my service:

public void Update(ObjectDTO objectDTO)
{
  string token = WebOperationContext.Current != null ? WebOperationContext.Current.IncomingRequest.Headers["token"] : string.Empty;

  //Authentication
  bool isUserAuthenticatedResult = IsUserAuthenticated(ref token);
  if (!isUserAuthenticatedResult)
      return null;

  //Perform service action
  MyDtoManager = new MyDtoManager();
  objectDTO = MyDtoManager.Update(objectDTO); 
  return objectDTO;
}

Here is my Service Contract:

[ServiceContract]
public interface IMyDtoService
{
    [OperationContract]
    [WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
    List<ObjectDTO> LoadById(string value);

    [OperationContract]
    [WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
    List<ObjectDTO> Load(string field, string value);

    [OperationContract]
    [WebInvoke(Method="GET", BodyStyle = WebMessageBodyStyle.Bare, ResponseFormat = WebMessageFormat.Json)]
    List<ObjectDTO> LoadAll();

    [OperationContract(Name = "InsertSingle")]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
    ObjectDTO Insert(ObjectDTO objectDto);

    [OperationContract(Name = "UpdateSingle")]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
    ObjectDTO Update(ObjectDTO objectDto);

    [OperationContract(Name = "DeleteSingle")]
    [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
    ObjectDTO Delete(ObjectDTO objectDto);
}

Here is my server configuration:

<system.serviceModel>
  <bindings>
    <webHttpBinding>
      <binding name="WebHttpBindingConfig" 
           openTimeout="00:05:00" 
           sendTimeout="00:05:00"
           maxBufferSize="65536000" 
           maxBufferPoolSize="52428800" 
           maxReceivedMessageSize="65536000"
           transferMode="Buffered">
      <readerQuotas maxDepth="32" 
                  maxStringContentLength="65536000" 
                  maxArrayLength="16384" 
                  maxBytesPerRead="4096" 
                  maxNameTableCharCount="16384" />
      <security>
        <transport />
      </security>
    </binding>
  </webHttpBinding>
 </bindings>
 <services>
   <service behaviorConfiguration="Services.ServiceBehavior"
        name="Services.MyDtoService">
     <endpoint address="" 
          behaviorConfiguration="HttpBehavior" 
          binding="webHttpBinding" 
          name="Services.MyDtoService"
          contract="ServiceInterfaces.IMyDtoService">
     <identity>
        <dns value="localhost" />
     </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
 </service>
</services>
<behaviors>
  <serviceBehaviors>
    <behavior name="Services.ServiceBehavior">
      <serviceMetadata httpGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="HttpBehavior">
      <webHttp />
    </behavior>
  </endpointBehaviors>
</behaviors>
</system.serviceModel>

And finally my client code making the call:

IMyDtoService myDtoService = new WebChannelFactory<IMyDtoService>(BindingConfig, new Uri("http://localhost:8080/MyDtoService.svc")).CreateChannel();
using (new OperationContextScope((IClientChannel)myDtoService))
{
    if (WebOperationContext.Current != null)
        WebOperationContext.Current.OutgoingRequest.Headers.Add("token", tokenResult.Result);

    ObjectDTO insertResult = ipAddressService.Insert(new ObjectDTO
                                              { ObjectGuid = Guid.NewGuid(),
                                                IsAllow = true,
                                                Identifier = 1,
                                                IdentifierType = 0,
                                                StartIpAddress = "192.168.0.1"
                                              });
    List<ObjectDTO> loadByIdResult1 = myDtoService.LoadById(insertResult.ObjectGuid.ToString());
    Console.WriteLine("Insert Found: " + loadByIdResult1.Count);

    insertResult.IsAllow = false;
    ObjectDTO updateResult = ipAddressService.Update(insertResult);
}

As you can see my client code calls my WCF service and the insert method works perfectly fine and I can see the persisted object in my database. However on the update, the ObjectDTO parameter is null. If I load an existing object and perform an update it works perfectly. It appears to be an issue with subsequent calls to the WCF service using POST methods. I do not have this problem with GET methods.

Brandon
  • 10,744
  • 18
  • 64
  • 97
  • Doing some testing, if I move my Update call to it's own: using(new OperationalContextScope((IClientChannel)myDtoService)) then both my Insert and Update methods work. If my Update method remains the way it is in my posted example, then the Update method gets a null value for the ObjectDTO parameter. Can anyone explain why? – Brandon Feb 12 '10 at 20:06

2 Answers2

2

I have gone through this problem but WCF SOAP. On client site you can see object filled with values when debug point comes in service it is null. It had happened due to change in casing of param. . If you see your service contract has

ObjectDTO Update(ObjectDTO objectDto);

and defination has public void Update(ObjectDTO objectDTO) , note the difference in casing.

Ajay Kelkar
  • 4,591
  • 4
  • 30
  • 29
1

You have not shown the relevant code to be 100% sure what the problem is. But it looks like it is null because this line:

ObjectDTO insertResult = ipAddressService.Insert(new ObjectDTO 
                                              { ObjectGuid = Guid.NewGuid(), 
                                                IsAllow = true, 
                                                Identifier = 1, 
                                                IdentifierType = 0, 
                                                StartIpAddress = "192.168.0.1" 
                                              }); 

is returning null. So you need to check the insert method.

Shiraz Bhaiji
  • 64,065
  • 34
  • 143
  • 252
  • My insertResult object is populated after the call. I believe it has something to do with the OperationalContextScope. If I seperate the Insert and Update method calls into their own OperationalContextScopes, both methods get the correct results and pass the correct parameters. – Brandon Feb 14 '10 at 13:55