Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make WCF Dataservice to stop tracking Entity changes?

I have web app which invokes OData Webservice (DataServiceContext) via a proxy. The issue is the code even though makes a call to OData webservice every time, it always returns old data after changing content in the Content Management system (SDL Tridion).

string getPageContentForUrl(string url)
{
    var page = cdService
                   .Pages
                   .Expand("PageContent")
                   .Where(x => x.Url == url)
                   .FirstOrDefault();

    if (page == null || page.PageContent == null)
    {
        return string.Empty;
    }
    else
    {
        return page.PageContent.Content;
    }

}

We had to an reset the apppool to see the latest data changes.

So while debugging more, I noticed that

var context = (System.Data.Services.Client.DataServiceContext)cdService;
context.Entities[0].State = Unchanged

so I tried fixing it by calling .Detach() explicitly before returning the value from getPageContentForUrl, so something like,

cdService.Detach(page);
cdService.Detach(page.PageContent);

My question is, can I do the above at more "global" level, maybe have webservice always assume the State as "Changed", since I don't want to manually write code to Detach()?

like image 749
parsh Avatar asked Nov 08 '12 09:11

parsh


2 Answers

I think the answer lies indeed - as you suspected - in the proxy you're using, or rather in the DataServiceContext. This is what Microsoft has to say:

By default, the client only materializes an entry in the response feed into an object for entities that are not already being tracked by the DataServiceContext. This means that changes to objects already in the cache are not overwritten. This behavior is controlled by specifying a MergeOption value for queries and load operations.

To me, this sounds exactly like the behaviour that you're describing. Fortunately, the caching can be turned off by setting the MergeOption property on the DataServiceContext.

See http://msdn.microsoft.com/en-us/library/gg602811.aspx.

like image 135
Quirijn Avatar answered Oct 21 '22 13:10

Quirijn


As Quirijn already commented, it seems like the Tridion Content Delivery OData service is returning cached results in your set up. Detaching and re-attaching the client is a brute force work-around.

Tridion Content Delivery Object Cache will (when properly configured) automatically remove items from its cache when they are updated by publish actions from the Content Management System. Since this is not happening in your set up, it seems likely that your Object Cache is not correctly configured.

The simplest step is to find the cd_storage_conf.xml file of your cd_webservice web application and turn Object Caching off (as Quirijn already said):

<ObjectCache Enable="false" />

Now recycle the application pool as you did before and test again. If the OData calls now always return the updated content, your problem was indeed being caused by a mis-configured Object Cache.

Unfortunately at this stage, all you'll have done is turn off the Object Cache, which is certain to reduce the load your web service can handle. The next step should be to fix the configuration problem of your Object Cache.

For that I'd suggest reaching out to SDL Professional Service or one of SDL's partners. Although configuring the Object Cache is not too difficult, it is a bit too involved to explain in a Q&A format.

like image 37
Frank van Puffelen Avatar answered Oct 21 '22 13:10

Frank van Puffelen