views:

430

answers:

1

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.

+1  A: 

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
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