This project has moved. For the latest updates, please go here.

Service is called only once, CachePolicy is ignored

May 7, 2012 at 11:56 PM

Hi guys,

I 've been working with AgFx trying to figure out if it's suitable for a project of mine. After reading the tutorial, I have implemented something basic but it seems that either I don't get how it works or I have made some enormous mistake.

There is this simple service on an MVC 3 project, with just this method:

        [OperationContract]
        [WebGet(UriTemplate = "/Version/{param}",
                BodyStyle = WebMessageBodyStyle.Bare,
                RequestFormat = WebMessageFormat.Json,
                ResponseFormat = WebMessageFormat.Json)]
        public string GetVersion(string param)
        {
             return param + ": " + DateTime.Now.ToLongTimeString();
        }

I have a LoadContext:

    public class StructureVersionLoadContext : LoadContext
    {
        public string Param
        {
            get
            {
                return (string)Identity;
            }
        }
 
        public StructureVersionLoadContext(string param)
            : base(param)
        {
        }
    }

and a VM:

    [CachePolicy(CachePolicy.CacheThenRefresh, 10)]
    public class StructureVersionModel : ModelItemBase<StructureVersionLoadContext>
    {
        public StructureVersionModel()
        {
        }
 
        public StructureVersionModel(string param) :
            base(new StructureVersionLoadContext(param))
        {
        }
 
        private string _description;
        public string Description
        {
            get { return _description; }
            set
            {
                _description = value;
                RaisePropertyChanged("Description");
            }
        }
 
        public class StructureVersionModelDataLoader : IDataLoader<StructureVersionLoadContext>
        {
            public LoadRequest GetLoadRequest(StructureVersionLoadContext context, Type objectType)
            {
                var url = string.Format(@"http://localhost:2641/Service/Version/{0}", context.Param);
                return new WebLoadRequest(context, new Uri(url));
            }
 
            public object Deserialize(StructureVersionLoadContext context, Type objectType, Stream data)
            {
                var model = new StructureVersionModel(context.Param);
                model.LoadContext = context;
 
                using (var sr = new StreamReader(data))
                {
                    var sv = JsonConvert.DeserializeObject<string>(sr.ReadToEnd());
 
                    model.Description = sv;
                };
 
                return model;
            }
        }
    }

Now, on the WP side, I have a button that runs this code:

 this.DataContext = DataManager.Current.Load<StructureVersionModel>(new StructureVersionLoadContext(theTextBox.Text));

I have set the CachePolicy of the VM to CacheThenRefresh. By reading the documentation, I understand  that when I press the button for the first time, AgFx should fetch a value from the service. If I press it again within 10 seconds, AgFx should just give me the cached value (assuming that the parameter is the same). And when I press it after 10 seconds have passed (keeping always the same parameter), AgFx should hit the service again and give me a fresh value. Correct? Well, the problem is that this last part is not happening. The service is hit once and never again. Not event if I do DataManager.Current.Refresh().

I have uploaded a project to demo the described behavior here: https://skydrive.live.com/redir.aspx?cid=ccdfc90fac9f29ce&resid=CCDFC90FAC9F29CE!549&parid=CCDFC90FAC9F29CE!547 

 

Coordinator
May 9, 2012 at 9:35 PM

Hi there -

Thanks for the detailed explanation.  You've neither made a mistake, nor is  your code wrong.  It's all good.

I believe what you're seeing here is the caching behavior on the phone.  I remember wrestling with this for hours the first time I came across it.

What's happening is that the web cache on the phone is getting in the way, which stops your server from seeing the request even if AgFx asks for it.

To test this, do this:

var url = string.Format(@"http://localhost:2641/Service/Version/{0}?{1}", context.Param, DateTime.Now.Ticks);

Basically this just changes the URL so it gets around the cache.  That should verify the issue.  I think the real fix is that you want your web service to return:

Cache-Control: No-Cache

as a header, it's been a while since I've done that with ASP.NET/WFC so maybe check into how to flip that bit and see if that also does the trick after you've verified the issue with the above, and allows you to dump the fake param.

Shawn

May 9, 2012 at 9:59 PM

Wow! Your reply just came in while I was investigating the issue using the LastUpdated and IsUpdating properties.

Yes, it is the web cache that causes this behavior. The DateTime.Now.Ticks parameter trick as well adding this to the service

WebOperationContext.Current.OutgoingResponse.Headers.Add("Cache-Control""no-cache");

fixes the problem.

 

Thanx!

Manos