I have a relatively urgent question (website needs to go live Monday morning).
On my site I have implemented a simple member profile editor using Contour.
To get member properties into my form I use {} notation, e.g. {member.name}.
To update the member properties, I use the workflow featured in Contour Strikes Again:
Member m = new Member(mId);
... do stuff, set properties on m ...
m.XmlGenerate(new System.Xml.XmlDocument());
m.Save();
This works in the sense that I can see on the backend that member properties are actually being updated whenever a form is submitted.
However, changes to member properties do not immediately become visible on the front end, neither when using the workflow, nor when going directly through the member tab on the back end. It takes a reset of my Umbraco instance (through touching web.config) to make the changes visible on the front end.
Likely this is a catching issue.
I now have to questions:
How to make the core dev team aware of this issue?
How to implement a temporary fix, ie, call a member cache reset from code
I guess (2) should be possible but when looking at the 6.x source I cannot find explicit references to member caching (not immediately) whereas such references do exist in 7.1.0...
Also, I can see from the Umbraco repo that there is a branch on 6.2.0 by sdeminick referring to "cache fixing"
So either I perform a code fix by calling a reset from my workflow or I perform an upgrade of Umbraco (tricky, so close before a deadline).
This issue is actually related to another one I had been having, ie I want to use Contour to update member properties (profile management for members).
I ended up upgrading my install to 6.2.0 beta and Contour 3.0.20. Mainly because I noticed a new MemberProvider system in 6.2.0.
You can read all about how I updated the Contour member tools to work with this new system here
Long story short though, I still believe that calling following general sequence:
var ms = ApplicationContext.Current.Services.MemberService;
..
Umbraco.Core.Models.Member m = (Umbraco.Core.Models.Member)ms.GetById(mId);
..
m.SetValue(p.Alias, mappings[p.Alias]);
..
ms.Save(m);
should result, not only in an updated member in the back end (which it does, the above code works), but it should also result in those changes being immediately apparent on the front end, eg when calling {member.someproperty} in another contour form.
However, this is not the case... Only by either waiting (minutes) or forcibly resetting Umbraco do the changes show up.
I am still looking into the reasons for this but since I am on a deadline (5pm today) any help would be REALLY appreciated...
It is quite possible that the new API has a bug, I will most certainly report this but I assume the mechanics for flushing the cache in general should already be in place? Even if it is not best practice, It would allow me to temporarily remedy this issue.
The delay in updating members was also happening on older Umbraco installs using the old system.
Although my member updates are not showing on the frontend this does not really concern frontend code (eg Razor).
The member updating is being done by a Contour WorkFlow (which resides in the backend) and also the loading of updated data should be done by Contour (using the {} notation)
I still have to look into how Contour handles {} maybe the problem lies there (ie Contour is caching something)...
I found a way to clear Contour "member data" caching. Use Code First to create your "Profile Form" and include the following code:
/// Removes all items from cache in entire site
var enumerator = HttpContext.Current.Cache.GetEnumerator();
while (enumerator.MoveNext())
{
HttpContext.Current.Cache.Remove(enumerator.Key.ToString());
}
I use a "CacheHelper" class that includes previous cache cleaning code so I can invoke it whenever I need.
"Profile Form" Code First Example:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Umbraco.Forms.CodeFirst;
using Umbraco.Forms.Core.Providers.FieldTypes;
using umbraco.cms.businesslogic.member;
namespace Contour.CodeFirstExample
{
[Form("Member Profile", DisableDefaultStylesheet = true, StoreRecordsLocally = false, ShowValidationSummary = true, MessageOnSubmit = "Your profile has been updated.")]
public class Profile: FormBase
{
[Field("Profile", FormFieldsets.Details,
Mandatory = true,
DefaultValue = "{member.firstName}")]
public string FirstName { get; set; }
[Field("Profile", FormFieldsets.Details,
Mandatory = true,
DefaultValue = "{member.lastName}")]
public string LastName { get; set; }
[Field("Profile", FormFieldsets.Details,
Mandatory = true,
Regex = @"(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,3})",
DefaultValue = "{member.email}")]
public string Email { get; set; }
[Field("Profile", FormFieldsets.Details,
Mandatory = true,
DefaultValue = "{member.telephone}")]
public string Telephone { get; set; }
[Field("Profile", FormFieldsets.Details,
Mandatory = true,
Type = typeof(Textarea),
DefaultValue = "{member.contactAddress}")]
public string Address { get; set; }
public override IEnumerable<Exception> Validate()
{
var e = new List<Exception>();
var m = Member.GetCurrentMember();
if (m != null)
{
if (m.Email != Email)
{
if (Member.GetMemberFromLoginName(Email) != null)
e.Add(new Exception("Email already in use."));
}
}
return e;
}
public override void Submit()
{
var m = Member.GetCurrentMember();
if (m != null)
{
m.Email = Email;
m.LoginName = Email;
m.Text = FirstName + " " + LastName;
//asign custom properties
m.getProperty("firstName").Value = FirstName;
m.getProperty("lastName").Value = LastName;
if (!string.IsNullOrEmpty(Telephone))
m.getProperty("telephone").Value = Telephone;
if (!string.IsNullOrEmpty(Address))
m.getProperty("contactAddress").Value = Address;
//Save member
m.Save();
//Generate member Xml Cache
m.XmlGenerate(new System.Xml.XmlDocument());
Member.AddMemberToCache(m);
// Clear member cache
CacheHelper.ClearCacheItems();
}
}
}
}
And the CacheHelper code:
using System;
using System.Web;
namespace Contour.CodeFirstExample
{
public static class CacheHelper
{
/// Removes all items from cache in entire site
public static void ClearCacheItems()
{
var enumerator = HttpContext.Current.Cache.GetEnumerator();
while (enumerator.MoveNext())
{
HttpContext.Current.Cache.Remove(enumerator.Key.ToString());
}
}
}
}
More recent digging has turned up the way to do stuff like editing/updating members using the new MemberService. Could be interesting to people that end up reading this thread. You can find more info here.
I am still using Umbraco 6 but now that Umbraco 7 seems more stable I think it's time for change.
I will take a look at the new MemberService system. Thanks for the info!
I thought I had the same problem but mine was different. I get updated data with $.ajax. When the member is saved I fire another $.ajax call for the updated information. I have to set cache to false in the $.ajax call to see the updated information, then it works.
Programmatically reset member cache
Hi guys,
I have a relatively urgent question (website needs to go live Monday morning).
On my site I have implemented a simple member profile editor using Contour.
To get member properties into my form I use {} notation, e.g. {member.name}.
To update the member properties, I use the workflow featured in Contour Strikes Again:
This works in the sense that I can see on the backend that member properties are actually being updated whenever a form is submitted.
However, changes to member properties do not immediately become visible on the front end, neither when using the workflow, nor when going directly through the member tab on the back end. It takes a reset of my Umbraco instance (through touching web.config) to make the changes visible on the front end.
Likely this is a catching issue.
I now have to questions:
I guess (2) should be possible but when looking at the 6.x source I cannot find explicit references to member caching (not immediately) whereas such references do exist in 7.1.0...
Also, I can see from the Umbraco repo that there is a branch on 6.2.0 by sdeminick referring to "cache fixing"
So either I perform a code fix by calling a reset from my workflow or I perform an upgrade of Umbraco (tricky, so close before a deadline).
Any help would be greatly appreciated
Hello,
How do you fetch the member data in the frontend? Usually you write some custom code for that which has it's own caching. For example: http://our.umbraco.org/forum/developers/extending-umbraco/27626-Accessing-Member-Information#comment103415
That uses library.GetMember but that cache should be cleared after a member is updated.
Jeroen
Hello Jeroen,
Thanks for the feedback.
This issue is actually related to another one I had been having, ie I want to use Contour to update member properties (profile management for members).
I ended up upgrading my install to 6.2.0 beta and Contour 3.0.20. Mainly because I noticed a new MemberProvider system in 6.2.0.
You can read all about how I updated the Contour member tools to work with this new system here
Long story short though, I still believe that calling following general sequence:
should result, not only in an updated member in the back end (which it does, the above code works), but it should also result in those changes being immediately apparent on the front end, eg when calling {member.someproperty} in another contour form.
However, this is not the case... Only by either waiting (minutes) or forcibly resetting Umbraco do the changes show up.
I am still looking into the reasons for this but since I am on a deadline (5pm today) any help would be REALLY appreciated...
It's possible that the new API still has some bugs. You can report them here: http://issues.umbraco.org/dashboard#newissue=yes
If you want to fetch data with the new API you can use Umbraco.TypedMember.
Jeroen
Hi Jeroen,
It is quite possible that the new API has a bug, I will most certainly report this but I assume the mechanics for flushing the cache in general should already be in place? Even if it is not best practice, It would allow me to temporarily remedy this issue.
The delay in updating members was also happening on older Umbraco installs using the old system.
Also important maybe:
Although my member updates are not showing on the frontend this does not really concern frontend code (eg Razor).
The member updating is being done by a Contour WorkFlow (which resides in the backend) and also the loading of updated data should be done by Contour (using the {} notation)
I still have to look into how Contour handles {} maybe the problem lies there (ie Contour is caching something)...
Hi Kris,
I found a way to clear Contour "member data" caching. Use Code First to create your "Profile Form" and include the following code:
I use a "CacheHelper" class that includes previous cache cleaning code so I can invoke it whenever I need. "Profile Form" Code First Example:
And the CacheHelper code:
Thanks Ivan ,
That solution seemed to work.
More recent digging has turned up the way to do stuff like editing/updating members using the new MemberService. Could be interesting to people that end up reading this thread. You can find more info here.
You are welcome Kris.
I am still using Umbraco 6 but now that Umbraco 7 seems more stable I think it's time for change. I will take a look at the new MemberService system. Thanks for the info!
I thought I had the same problem but mine was different. I get updated data with $.ajax. When the member is saved I fire another $.ajax call for the updated information. I have to set cache to false in the $.ajax call to see the updated information, then it works.
is working on a reply...