Output caching a custom control (server control) - asp.net

I've come across hints about output caching a server control, but have yet to find a definitive answer to: Can the output of a server control be cached (in the same way that user controls are cached)?
The suggestions I've come across involve caching the data (not true output caching), or suggest setting the response.cache options. Ideally, I'd like to be able to drag a server control on to the page and set properties with the same names as the outputcache directive:
Example:
<cc1:MyCustomControl ID="ctl1" runat="server" CacheDuration="200" VaryByCustom="user" />
I was going to dig into the framework to see how output caching really works, but was hoping to find some information to get me started. From my limited understanding, the parser decides whether or not a page/usercontrol is cached. Since server controls are not parsed, there would be no way to stop the code from executing. I suppose I could initialize an "IsInCache" boolean and make sure that all methods check that var before executing the code. This would not entirely eliminate the server control from being executed, but it might improve performance enough by avoiding calls to the database and binding data to controls.
I'm still using .NET 3.5, and haven't had much time to explore the OutputCache provider model in .NET 4.0. Maybe there's a solution in the latest version of the framework?
Any thoughts?

I was looking for this as well and I figured I'd add the solution to this page since it came up in my web search. There is an attribute called PartialCaching that is applied to the server-side/custom control to achieve the same effect as the OutputCache directive used in ascx and aspx templates. It takes the same parameters (VaryByParameter, etc) as well. For example:
[PartialCaching(1000, "foo", null, null)]
public class ClientScriptVariableBlock : Control {
...
}
The ASP plumbing treats this the same as the template attribute, so the end result is the same. This is valuable (in my case) because I get to create common server controls outside of the web project itself that can be cached. ASCX templates don't work very well in external assemblies :)

Related

ASP.Net Web Parts, personalization, and javascript

Folks,
I have some personalized properties on an ASP.Net Web Part that I would like to set via Ajax (for example, the size to which the user has expanded the WebPart using the jQuery Resizable plugin.)
I've read this question and answer, but I don't think it will work. Personalized properties are instance properties. (If they were static, they couldn't be user-scoped, could they?) A WebMethod, which must be static, can't access them.
You might be thinking that I could just use a hidden field and send my values back that way, but that assumes that a postback is done at least once after the values are set. In this case I can't guarantee that: the page in question displays a lot of data but doesn't take any user input other than for configuration.
I seem to recall that some Ajax techniques involve remotely instantiating a page on the server and going through at least part of the page life cycle, but the last time I messed with that was 2006 and I never could get it to work very well. I have the impression that modern Ajax techniques, even for ASP.Net, work in other ways.
So, does anybody have an idea of how this could be managed?
Thanks very much,
Ann L.
Webmethods only have to be static when they are page-based. Create a webservice in your project and stick non-static webmethods in there. You can even enable session state.

What's the official Microsoft way to track counts of dynamic controls to be reconstructed upon Postback?

When creating dynamic controls based on a data source of arbitrary and changing size, what is the official way to track exactly how many controls need to be rebuilt into the page's control collection after a Postback operation (i.e. on the server side during the ASP.NET page event lifecycle) specifically the point at which dynamic controls are supposed to be rebuilt? Where is the arity stored for retrieval and reconstruction usage?
By "official" I mean the Microsoft way of doing it. There exist hacks like Session storage, etc but I want to know the bonafide or at least Microsoft-recommended way. I've been unable to find a documentation page stating this information. Usually code samples work with a set of dynamic controls of known numbers. It's as if doing otherwise would be tougher.
Update: I'm not inquiring about user controls or static expression of declarative controls, but instead about dynamically injecting controls completely from code-behind, whether they be mine, 3rd-party or built-in ASP.NET controls.
This greatly depends on the problem at hand, and the type of controls you're recreating. Are they all simple text boxes or various different complex custom user controls. the main thing here is: if you want your dynamic control to regain state after a post-back, you have to re-create it in the Init phase of a page life-cycle.
Anyway. There's nothing like a Microsoft way or Microsoft recommended way basically. When you're dynamically adding several simple controls of the same type a hidden field with a count would do the trick, but when you have several complex controls other ways would have to be used. You could still hidden fields and save control's full type strings in them (ie. System.Web.UI.WebControls.TextBox) and re-instantiate them. But think of an even more complex example of putting various controls on different parts in the page... And initializing them to a specific state. That would be a bit more challenging. Hence no Microsoft way... The recommended way is to recreate in Init phase. And that's it.
Everything can be solved, but sometimes one took a wrong direction in the UI and things could be done easier using a different approach.
Additional explanation
This state-full technique of ViewState that Asp.net uses is considered the worse culprit with web developers in general. That's why Asp.net MVC developers think the new framework is bliss since its much more suited to the state-less HTTP protocol. Me being one of them. :D

Is it possible to modify ASP.NET to no longer require runat="server"?

I know why runat="server" is currently required (ASP.NET why runat="server"), but the consensus is that it should not be required if you incorporate a simple default into the design (I agree of course).
Would it be possible to modify, extend, decompile and recreate, intercept or otherwise change the behavior of how ASP.NET parses ASPX and ASCX files so that runat="server" would no longer be required? For instance, I assume that a version of Mono could be branched to accomplish this goal.
In case specific requirements are helpful, the following highlights one design:
During parsing, when configured namespace tags are encountered (such as "asp"), default the element's runat property to "server"
During parsing, when configured namespace tags are encountered (such as "asp"), if the element's runat property value is available, then that value should be used in place of the default
New page-level setting introduced (can be set in the page directive or web.config) that specifies the default runat value for a specific namespace tag
I'm afraid you'd have to modify the entire page parser to accomplish this, and I don't think that's possible.
On the other hand, you should be able to create your own. See the buildProviders Element and the BuildProvider class. You should be able to create your own build provider for .aspx pages and use it to replace the built-in provider.
Unfortunately, the PageBuildProvider class used by ASP.NET is internal, and the PageParser class that it uses to parse pages is sealed. You'll be entirely on your own.
Consider that runat="server" has been in ASP.NET for a decade now, and I think you'll see that this won't change anytime soon.
You'd also lose Designer support, but maybe you don't care about that.
So far as I know, there are no hooks deep enough in the ASP.NET Page handling process that would allow this. I know of no way to override or extend the parsing or processing of actual aspx/ascx code.
While ASP.NET is fairly flexible and lets your override many default behaviors (like how ViewState is saved/loaded, where Session is stored, etc) this is not one of them.
However... technically the Page object is just another HttpHandler. You could write your handler and do anything you wanted with it. All you have to do is implement everything the Page class does and then throw in this extra functionality. :) Alternately, pull out Reflector and dig through the Page object's ProcessRequest method and see where it is actually parsing/initializing the objects declared in aspx and you might get a clue how to implement the functionality you're looking for. But I suspect you'd be wasting your time.

Running ASP / ASP.NET markup outside of a web application (perhaps with MVC)

Is there a way to include some aspx/ascx markup in a DLL and use that to generate text dynamically? I really just want to pass a model instance to a view and get the produced html as a string. Similar to what you might do with an XSLT transform, except the transform input is a CLR object rather than an XML document. A second benefit is using the ASP.NET code-behind markup which is known by most team members.
One way to achieve this would be to load the MVC view engine in-process and perhaps have it use an ASPX file from a resource. It seems like I could call into just the ViewEngine somehow and have it generate a ViewEngineResult. I don't know ASP.NET MVC well enough though to know what calls to make.
I don't think this would be possible with classic ASP or ASP.NET as the control model is so tied to the page model, which doesn't exist in this case.
Using something like SparkViewEngine in isolation would be cool too, though not as useful since other team members wouldn't know the syntax. At that point I might as well use XSLT (yes I am looking for a clever way to avoid XSLT).
You can host ASP.NET Runtime in another application. See :- http://msdn.microsoft.com/en-us/magazine/cc188791.aspx
Also see http://www.west-wind.com/presentations/aspnetruntime/aspnetruntime.asp

How to choose between Web Service or Page PostBack?

Let's consider that I have an asp.net page which will go to the server after a client-side event and will do "some stuff" and show a return value of this process on the UI afterwords.
My question is, if I am working in the same domain, how should I decide between creating a web-service and calling that AND simply raising a post-back and handle this "some stuff" on the aspx page itself?
Under what conditions creating a web-service becomes meaningful to overcome some processes while working in the same domain?
There are no hard-and-fast rules. However, I can offer a few high-level guidelines:
Prefer an .aspx page if the result includes a significant amount of markup (HTML, JS, etc), or where generating the results is simplified by having access to control state from the original page. Keep in mind that the Page object carries a significant amount of overhead with it.
Prefer a web service for queries that can be parameterized and that return structured data
Prefer an HttpHandler for queries with simple parameters that return either simple, full-custom text or binary (such as an image)
I would look at how fast it takes for the post and reload action to occur. It depends on the user's expectations. Most people, if they know they are using a browser, will find that up to two seconds is just about acceptable for the action to occur, and the screen to be reloaded. On the other hand, in one of my jobs, I was using ASP.NET to drive a touchscreen, and this just looked totally wrong, so I refactored the code to use a static web page plus a WebService component.
You also need to take into account the capabilities of the browser. In the example above, I knew that I was only using IE6, so I could afford to write my Javascript code to take advantage of that browser. You may not be so lucky. If you are to use a web service which has client update, you should ensure that you target a version of Javascript and DOM that is supported by all your target browsers.

Resources