How to make WCF Dataservice to stop tracking Entity changes?
Asked Answered
A

2

9

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()?

Ambry answered 8/11, 2012 at 9:45 Comment(3)
I don't think it should be necessary to detach. The Content Delivery Service can be set up to cache content from the broker. Please open the cd_storage_conf.xml in the CDS, turn off caching and retry.Rubbing
Thanks Quirijn, can you please see my comment on Frank's answerAmbry
I think you were right after all, please check my answer below and see if it helps.Rubbing
R
10

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.

Rubbing answered 9/11, 2012 at 10:57 Comment(2)
Yep that fixed the issue, I had to set the MergeOption = NoTracking, since the OData WS is readyonly.Ambry
Thank you! Microsoft.OData.Client.DataServiceContext.MergeOption has the same issue because it defaults to "AppendOnly". Setting to context.MergeOption = MergeOption.PreserveChanges fixed the problem for me. learn.microsoft.com/en-us/dotnet/api/…Caramel
K
5

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.

Kezer answered 8/11, 2012 at 18:51 Comment(3)
Thanks for your answer. I think I wasn't clear with my question, when I fire the actual Odata call in a browser I get the updated content, mydomain/odata.svc/… We have implemented a CacheChannel Service which clears the OData WS cache when new data is published. The issue is inside the code (getPageContentForUrl) which invokes the OData WS using a proxy (DataServiceContext) which shows the older data. Doesn't this mean OData WS is setup fine but not the proxy?Ambry
Ah... if the browser shows the updated content, the problem indeed must be in the client. I've never seen a generated proxy return stale content, so can't help with that unfortunately.Kezer
Quirijn's suggestion fixed the issue. Had to set the MergeOption - see my comment to his answer.Ambry

© 2022 - 2024 — McMap. All rights reserved.