How to use outputcache in a usercontrol, with control properties - asp.net

I have a UserControl, which should only change based on 2 URL parameters.
The problem is, it has a public property, which is used in the calling pages, so it throws a NullReferenceException on my property.
Any ideas?

I think I've figured this one out, it seems to be quite tricky which is due to my lack of comprehensive understanding of how output cache works I suspect.
You can't cache the UserControl if it has variable properties that dicatate it's content. You need to put a cache control in the Content page that holds the control. Then add the cache to the content page:
<%# OutputCache Duration="120" VaryByControl="JobList" %>
Where the vary by control is the ID of the control you wish to cache. Then specify a property for that vary by control:
<%# OutputCache Duration="120" VaryByControl="JobList.LoggedInUserID" %>
This seems to work for me!

Check the VaryBy options,
try to take a look to this articles:
http://msdn.microsoft.com/en-us/library/hdxfb6cy%28v=vs.71%29.aspx
https://web.archive.org/web/20211020113508/https://www.4guysfromrolla.com/articles/022802-1.aspx
http://weblogs.asp.net/stefansedich/archive/2008/03/17/output-cache-with-usercontrol-on-masterpage-and-multiple-varybycustom.aspx

Related

How to use: HttpResponse.RemoveOutputCacheItem when using varyByCustom

I have implemented the Redis OutputCache (Microsoft.Web.RedisOutputCacheProvider) using the Azure Redis service.
I have found similar unanswered / unsolved questions here and here.
On top of the pages need to cache:
<%# OutputCache VaryByParam="*" Duration="600" %>
After access a random page and I check the key in Redis database is has saved like: /_a2/monitor.aspx
So running the below line of code, will remove this cache item (and it worked).
HttpResponse.RemoveOutputCacheItem("/monitor.aspx", "RedisOutputCache")
Now I have updated the same page adding the varyByCustom the the OutputCache directive:
<%# OutputCache VaryByParam="*" varyByCustom="userhash" Duration="600" %>
Now accessing the page and checking the key in Redis database it is saved like: /_a2/monitor.aspxHQFCNuserhashVcc6ef5b7173286704cef942d5577b88bd81f2cce71a0dcdc8676d3a815e68b59DE
You see the added userhash hash value, this is nice and worked as expected.
But now here comes the problem: How do I clear this cache item.
This is not working:
`HttpResponse.RemoveOutputCacheItem("/monitor.aspx", "RedisOutputCache")`
Also tried:
HttpResponse.RemoveOutputCacheItem("/monitor.aspx?userhash=cc6ef5b7173286704cef942d5577b88bd81f2cce71a0dcdc8676d3a815e68b59", "RedisOutputCache")
And also tried:
HttpResponse.RemoveOutputCacheItem("/monitor.aspx {userhash:cc6ef5b7173286704cef942d5577b88bd81f2cce71a0dcdc8676d3a815e68b59}", "RedisOutputCache")
Also tried using some of the below options in combination of the above code:
Response.Cache.SetVaryByCustom("userhash")
Response.AddCacheItemDependency("action")
HttpContext.Current.Cache.Item("action") = "test"
Response.Cache.VaryByParams("userhash") = True
HttpResponse.RemoveOutputCacheItem("/monitor.aspx")
Is there an way to remove this cache item on using the varyByCustom option?
I don't use the system.web.mvc object. So I can not access this object for URL helper.
Any help is most welcome!
Joël
According to your description, I tried to implement my OutputCacheProvider to store cache into files to test this issue on my side. Here is my test result, you could refer to it.
OutputCache of my Monitor.aspx
<%# OutputCache VaryByParam="None" Duration="60" Location="Server" %>
When accessing the above page, I would get the following log from my OutputFileCacheProvider as follows:
And the current DateTime string would be refreshed in my monitor.aspx page after I have accessed another .aspx to clear the cache.
<%# OutputCache VaryByParam="*" Duration="60" VaryByCustom="userhash" Location="Server" %>
Note: The same way to call HttpResponse.RemoveOutputCacheItem("/monitor.aspx") for cleaning cache from another .aspx endpoint.
Both VaryByParam and varyByCustom could work as expected on my side. I assumed that you could add log within your OutputCacheProvider and try to find whether you have missed something.

Dynamically registering controls in .NET

Can anyone tell me if I can dynamically set the file name when registering a user control please, for example:
<%# Register src="[file name]" tagname="WebUserControl" tagprefix="uc1" %>
No, I don't believe you can. What you can do is register all of the possible controls that you might use on the page, either in the page directive or the web.config.
EDIT
What you can do, if this helps, is to add the controls dynamically in code-behind using the LoadControl method. This way, you can create instances of whatever user controls you want without worrying about registering them in the page directive or web.config. Thanks #Gabriel for pointing this out.

disabling viewstate of whole page

Is it possible to make the viewstate false of whole page including all controls at a time.I mean I don't want to set enableviewstate="false" for all controls..In the page directive of the aspx page I have made enableviewstate="false" but still viewstate of all the controls of the is enabled..
And what the EnableViewState="False"actually works within Page directive.
Have you tried setting enableViewState to false in web.config? Like this:
<pages enableViewState="false" />
In ASP.Net 4.0 one of the new features is more control over the ViewState of a Page and its Controls.
In ASP.Net 3.5 and earlier, the ViewState of ChildControls is ignored, if the ViewState for the Page is set explicitly. So if you set EnableViewState="false" for a UserControl, it still will use ViewState, if the Page.EnableViewState is set to true.
ASP.Net 4.0 introduces a new ViewStateMode-Property with 3 Values: Enabled, Disabled and Inherit
<%# Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" ViewStateMode="Disabled" Inherits="_Default" %>
So if you set ViewStateMode to Inherit for child controls, they will inherit the page's behaviour. If you set it to Enabled or Disabled, they will do as you want them to.
See for more info: http://www.dotnetcurry.com/ShowArticle.aspx?ID=478&AspxAutoDetectCookieSupport=1
Even though it does not directly answer your question, why your EnableViewState value in the Page gets ignored, but it might show you how to do it in ASP.Net 4.0 or where to look for the problem. Maybe you set EnableViewState="true" on a higher level, like the MasterPage?
This is (a somewhat dated) but still very relevant article about ViewState and how it works.
Here is another good article on MSDN.
I suggest you read and understand both before deciding that ViewState is not off.

Register User Control Issue

I have a user control registered at the top of my page:
<%# Register Src="/Controls/User/Navbar.ascx" TagName="Navbar" TagPrefix="pmc" %>
and I reference it in my page like this:
<pmc:Navbar runat="server" id="navbar"></pmc:Navbar>
but it does not know what <pmc:Navbar is. I cannot figure out why.
I'm using VS 2008, in a Web Application Project.
Maybe you should specify the path with ~: ... Src="~/Controls/User/Navbar.ascx" ...
Remove either the initial slash from the path to the control, or better still, prefix it with "~" :
<%# Register Src="Controls/User/Navbar.ascx" TagName="Navbar" TagPrefix="pmc" %>
or
<%# Register Src="~/Controls/User/Navbar.ascx" TagName="Navbar" TagPrefix="pmc" %>
The first solution is flakey as it relies on the page existing in the root folder and the control existing below it. The second is the preferred as it will work from any page in your project.
You should also consider registering your user controls in your web.config, as it keeps things much neater, and tends to avoid path issues a little better.

Simple HTML construction in ASP.NET?

A simple question, I think:
I want to put a tag into an ASP.NET app I've been asked to maintain, so I'm coming at this from a newbie point of view just tinkering around the edges without knowing a lot.
I wrote an old ASP application back in 1998, so I am just running on memory...
How do I write some output to the webpage?
I know I can use an
<asp:label id="blah">
but then I need to define a Label blah; in my code behind and then assign it.
I believe that I can put in-place:
<% Response.Write("sometext"); %>
and that will write sometext in the location within the page. (Am I correct?)
Lastly, I remember there was a syntax to the effect of
<%= "some string" %>
but I can't find the documentation on it, to say either it is deprecated, unadvised, or the rationale for such a decision.
I have tried googling for "ASP.NET grammar" but I can't even find a good description that "<%=" even exists, though it is mentioned in a few blogs.
For something simple, like inject the global version number, or the current date, then I can't see anything particularly wrong with in-place composition - it would save me defining 15 labels and having to initialise them all - though perhaps the asp:label approach could reference one global instance of a label?
Just asking for opinions on good practices :)
<%= string %> is perfectly valid ASP.NET syntax. The reason you will often find references to problems with using that is people use <%= (equivalent to Response.Write) when they should use <%# (for databinding) or vice-versa.
For example, we use it very extensively in our content managed site, where we pull in values from a global settings repository:
<%= SiteContext.Current.GetSetting("SiteTitle") %>
MSDN:
MSDN entry on <%= (this is under the JScript.NET section but still applies)
MSDN entry on <%#
Some others suggest <%= is not a "best practice" or a very good approach, but I strongly disagree with that sentiment. For an MVC-ish type site (especially a site that is template- or view-driven in some way), the most direct approach is frequently more effective than using server controls.
Just be mindful that when you use an <asp:Label /> it renders the .Text inside the <span> tag whereas an <asp:Literal /> adds no extraneous HTML to the string passed to it.
For example, if you were building a content management system and wanted to display user-driven HTML, a Label control would not correctly display the output from a WYSIWYG type rich textbox whereas a Literal control is the appropriate choice.
The <%= %> is the late-bound equivalent of the Literal's .Text property. The only difference here is when the value is placed in the page (aside from obvious syntax and separation of concerns paradigm) during the course of the page lifecycle.
Since the .Text property is on a control inherited from WebControl, it can be set/read/manipulated during any of the events following the control's Load event (wherever/whenever you load the control inside the page), but the <%= %> text cannot be directly read/used/manipulated by the code-behind without referencing some other control to get to it (like a containing div's InnerHtml property).
There are lots of options. You could use a single label, and string concatenate all the data you want displayed in that location.
You could create a user control with the layout you want and assign values that way.
You could inject it directly with response.write or the <%= %> syntax
You could create an HtmlGenericControl in your code behind (it's a div), add some text to it, and inject it into the pages controls collection.
Whatever you pick, try and go with the existing style of the coded page.
Look up the term "render blocks" for the <% %> syntax.
How about using
<asp:Literal id="z" text="goofy" runat="server" />?
Labels are usually used with forms.
You can also take full control of the rendering of your pages and controls and compose whatever you need to. You control the HTML, the order of rendering your controls, etc...
Go with the <asp:label /> (or a literal control if you want to customize some html in the content). Seriously. I'ts not that hard: when you put label in your markup visual studio will create it in the code-behind for you, so there's no extra work involved.
You could use the <%= "some string" %> syntax in web forms, but there can be issues when mixing that with the asp controls and there's a good reason new frameworks moved away from mixing logic like that in with your markup.

Resources