How to bust/clear DonutCache in asp.net MVC

Let us say you have an asp.net MVC controller/action which is donutcached like below. And you want to bust the cache for some reason. An example would be. You cache a partial view for 24 hours, but give the user a refresh button to allow him to manually refresh it if he wishes to.

NOTE: you cannot use web.config based cacheprofiles for MVC. It just doesn’t work, so DonutCache is being used for that.

[DonutOutputCache(CacheProfile = "CachedAction")]
public ActionResult CachedAction(string id)
{
return View();
}

Here is the web.config

	<caching>
	  <outputCache enableOutputCache="true" />
	  <outputCacheSettings>
		<outputCacheProfiles>
			<add name="CachedAction" duration="14100" varyByParam="*" location="Any" />
		</outputCacheProfiles>
	  </outputCacheSettings>
	</caching>

Normally, in the javascript if you just call $.ajax() and request that action, it will just come back with the cached copy. The trick here is to first bust your server cache. So, you can create another action like so.

public void BustCache(string id)
{	
var Ocm = new OutputCacheManager();
RouteValueDictionary rv = new RouteValueDictionary();

if (!string.IsNullOrEmpty(id))
rv.Add("id", id);
Ocm.RemoveItems("controller", "cachedaction", rv);
}

Finally you would simply make two ajax calls. First, you bust your cache and then you call your regular MVC action to get your content.

$.get('@Url.Action("bustcache", "controller"');
$.get('@Url.Action("cachedaction", "controller")');

An enhanced UpdateProgress control, which shows an animation at the point where mouse was clicked

Also Check Out: My latest venture. http://loqly.me – a way for you to ask questions and get answers about local businesses around you. iTunes link:http://bit.ly/e5u4jv (only available in US for now)

WHY DO IT ???

Before you read the post, let us answer why did I waste time in changing the behavior of the UpdateProgress control. Here is the deal. Suppose, you have 5 or 6 controls on your page, which when clicked result in an Ajax call. You know that the UpdateProgress control is pretty much static, meaning, wherever you put the <asp:UpdateProgress> tags, that is the place where the progressbar will show up when your Ajax call is in progress. So, no matter which control the user clicks the progressbar is being shown in a fixed place. Why may some people consider this bad ???

  • You or anyone looking at the screen, may lose track of why you are waiting because the progressbar just shows that you are waiting not what has triggered the wait.
  • If the page is long, and the progress bar is at a fixed place, there is a possibility that you clicked a control which is a scroll length away from where the progressbar will show.
  • If the control which was clicked can give a feedback for the user to wait, it prevents the user from clicking the same button twice.

So, much for justifying why I wrote this control. But those were just a few thoughts behind it. Let us get back to the nitty gritties. Btw, here is a YouTube vide of how it looks (video is a little fuzzy but it shows what I am trying to communicate)

The Code :

I will not go into too much detail explaining the code, because I am sharing the source code with you. But here is the high level overview :

  • Create a new control, which inherits from UpdateProgress control
  • Embed two resources in your control assembly. (the default hourglass image and the javascript used to make this control work)
  • Override Render method, and inject javascript. The javascript will hook into the AJAX InitializeRequest and EndRequest events, by calling add_initializeRequest() and add_endRequest() methods of Sys.WebForms.PageRequestManager class.
  • The first Image control in the <ProgressTemplate> of the UpdateProgress control will be assumed to be the hourglass image, and if you haven’t set an ImageURL value for it, a default image will be supplied. You can create your own hourglass images from this awesome website : http://www.ajaxload.info/#preview

That is it. Do leave comments and suggestions if you find this control useful. I am also attaching the source code and the assembly. If you don’t want to see the code, just use the assembly and things should work right away.

Use declarative security to show a Security trimmed navigation Menu along with enforcing role based security for your website

Hi All,

Here is what we are trying to achieve in this article.

  • Provide side-wide security without writing a single line of code
  • Show navigation menus to the user, which automatically hide the options which the user doesn’t have access to (also called Security Trimming)
  • Use declarative syntax in web.config to tighten your security so that even if the user knows a particular URL, he cannot get to it, unless he is explicitly granted access to the URL.

Background :-
I have this hierarchy of folders
/
|—UserManagement

|—Default.aspx

|—ChangePass.aspx

|—AdminPage.aspx (Only admins should have access to this page, and the menu control shouldn’t show this option)

I am using a ASP:Menu control and I want all logged in users to be able to see all menu options except the AdminPage link, but I want the administrator to be able to see every single menu option.

Here is a snapshot of the relevant tags from my web.config file —————————————————————-

<!–In this case my Roles are stored in an XML file, your roles can reside in SQL Server or AD or ADAM, it doesn’t matter–>

<add name=AzManPolicyStore connectionString=msxml://C:/Azman.xml />

<!–Here is how we enable the role manager. In this case the built in ASP.Net website config tool will automatically read and write Roles and their membership info in the file mentioned above. i.e Azman.xml–>

<roleManager enabled=true defaultProvider=RoleManagerProvider>

<providers>

<add name=RoleManagerProvider

type=System.Web.Security.AuthorizationStoreRoleProvider, System.Web, Version=2.0.0.0, Culture=neutral, publicKeyToken=b03f5f7f11d50a3a

connectionStringName=AzManPolicyStore

applicationName=TestApp/>

</providers>

</roleManager>

 


<!– To make security trimming and declarative security work, we need to follow the pessimistic approach. i.e first we will deny everyone access to our website–>

<authorization>

<deny users=*/>

</authorization>

<!– Then we selectively start permitting users and or Roles access to folders/files–>

<location path=UserManagement>

<system.web>

<authorization>

<allow roles=“Administrators, Managers, Users”/>

</authorization>

</system.web>

</location>

<!– Deny access to everyone except Admin on the Admin only page–>

<location path=UserManagement/AdminPage.aspx”>

<system.web>

<authorization>

 

<deny users=*/>

<allow roles=“Administrators”/>

</authorization>

</system.web>

</location>

Here is the excerpt from my Default.aspx page, which has the menu control ———————————–
<asp:Menu ID=Menu1 runat=server DataSourceID=SiteMapDataSource1

Orientation=Horizontal>

</asp:Menu>


<!–Note that I am explicitly mentioning Sitemapprovider=”” attribute, although if I dont mention it, it should pick up the default provider. But this is what made the security trimming work for me. If you don’t do this, the Security trimming in menus will not work !! –>

 

<asp:SiteMapDataSource ID=SiteMapDataSource1 runat=server SiteMapProvider=XmlSiteMapProvider />


 

 

Here is my Web.Sitemap file—————————–

 

<?xml version=1.0 encoding=utf-8 ?>

<siteMap xmlns=http://schemas.microsoft.com/AspNet/SiteMap-File-1.0>

<siteMapNode url=~/Default.aspx title=Home description=“”>

<siteMapNode url=~/UserManagement/Default.aspx title=Manage security settings description=“”/>

<siteMapNode url=~/UserManagement/ChangePass.aspx title=Change your password description=“”/>

<siteMapNode url=~/UserManagement/AdminPage.aspx title=Admin Only Functions description=“”/>

</siteMapNode>

</siteMap>

 

 

 

Thats it. Just by following these simple steps, you will have rock solid security for your website. And you don’t have to write a single line of code too.