ASP.NET fragment cache -- control is null second time round - asp.net

I have an ascx control which works just fine. It is contained in a larger aspx page. I want to put it in the fragment cache, so I added the appropriate CacheOutput directive at the top. However, now the control on the underlying aspx.cs file has the control variable set to null the second time the page has loaded. I found a few places on the web where it said this would happen, but I also didn't find a solution to accessing the control.
What am I missing?
Also, can I control where it is cached? Can I make it cache in the browser cache rather than at the server?

Question #1: Output caching only stores the HTML result on the server. If you want to interact or run any code in the user control at all, you may not use full output caching. You may want to look into a lower-level caching, perhaps database or object caching, or embed another user control within this one that uses full output caching itself but the outer user control no longer does.
Question #2: "Can I control where it is cached?" If you use output caching, then no. That always means cache on the server. However, there are lots of different levels of caching. You can only cache a full HTTP response at the browser: a single HTML page, a CSS file, etc. If you want to cache only part of a page at the browser, but have the rest of the page dynamic, you would have to do it with some kind of JavaScript. Either HTML5 local storage, or via AJAX that has appropriate caching headers or responds with a 304 Not Modified response.
Side note: The term "fragment cache" is more often referred to "partial caching" in the ASP.Net world.
SO Tips: These are two questions, and should really be asked as two individual questions in the future.
Also, there are many ways to solve your problems here; if you provided more context to what you are doing and the performance problem you are trying to solve, we could offer more specific answers.

Related

Webscraping a tricky asp.net page

The overall goal is to perform a search on the following webpage http://www.cma-cgm.com/eBusiness/Tracking/Default.aspx with a container value of CMAU1173561. I have tried two approaches, the php extension cURL and python's mechanized. The php approached involves a performing a POST submit using the input fields found on the page (NOTE: These are really ugly on the asp.net page). The returned page does not contain any of the search results. The second approaches involves using python's mechanize module. In this approach I load the page, select the form, then change the text field ctl00$ContentPlaceBody$TextSearch to the container value. When I load the response again no search results.
I am at a really dead end. Any help would be appreciate because as it stands my next step is to become a asp.net expertm which i perfer not to.
The source of that page is pretty scary (giant viewstate, tables all over the place, inline CSS, styles that look like they were copied from Word).
Regardless...an ASP.Net form still passes the same raw data to the server as any other form (though it is abstracted to the developer).
It's very possible that you are missing the cookies which go along with the request. If the search page (or any piece of the site) uses session state, the ASP.Net session cookie must be included in the request. You will be able to tell it from its name (contains "asp.net" and "session").
I assume that you have used a tool like Firebug or Chrome to view the complete outgoing request when the page is submitted. From my quick test, it looks like the request may be performed with a GET, not a POST. I submitted a form, looked at the request, and pasted the URL into a new browser window.
Example: http://www.cma-cgm.com/eBusiness/Tracking/Default.aspx?ContNum=CMAU1173561&T=57201202648
This may be all you need to do.

Drupal 6 - Disable Views cache for specific View

I have lots of views which don't change very often, and enjoy the benefit of caching. But I have 1 view which is used to display a random quote in a block in my sidebar, which I do not want cached. Is there a way to disable caching for this particular view? Specifically, I want to see a different quote every time I refresh the page.
UPDATE: I have Caching Mode set to Normal in my site's Performance settings, and I've tried going into the View and setting Caching = None (as well as in Block settings: Caching = Do not cache), and going into the Views tools page, and selecting "Disable views data caching", and it works when I'm logged in, but as soon as I logout, the quote stays the same after refreshing.
UPDATE: I'm beginning to think that if you have enabled page caching in Drupal, then all other cache settings are ignored (i.e. View and Block caching). Can anyone confirm this?
In the Views UI under the Basic settings of a particular display you have an option called Caching make that as none. And your view won't be cached. So you get random
quote everytime. :)
EDIT : Oops how did I miss what you were telling :(
Use Cache Exclude module to disable caching on the particular page. If your random block is on many pages, you may need to dig deeper to find an alternate solutions. All the best ;)
Suggestion: Randomize on the client side. Load 'em all up into a javascript array and write a quick function to select the random quote on page load. Unless there are hundreds of possible quotes it shouldn't weigh the page down too much, & you could exclude this one little sidebar feature from consideration when working on your caching strategy.
In fact even if there are hundreds of random quotes, you could use a combination of the two approaches. Grab 50 random lines w/ your module and them let javascript pick from there. To an end user it would be nearly identical.
The block may be being cached. Did you try to http://drupal.org/project/blockcache_alter ?
You can also directly change a block's cache setting in the database with something like:
update blocks set cache=-1 where bid=<blockbid>;
Setting this cache entry to -1 means the block will not be cached.
In addition, setting cache to 1 will cache the block per role, 2 will cache the block per user, 4 will cache the block per page, and 8 will cache the block exactly once (the same for all users, pages, etc).

Standard way to persist data between requests in ASP.NET-MVC

What is the most standard or best way to persist data between requests?
Should I use cookies or session variables? I'm interested in keeping data like sort order, sort column, and page number (for paginiation).
I'm coming from a webforms background so normally this type of thing was automatically handled for me in the viewstate of the controls I was using.
update
I like the querystring idea, for searching and more meaningful URLs; however, I'm working on an "index/list" view, which consists of a View with header, and "control" options, like DDLs for filtering and a partial view that renders the table of data.
The DDLs use a $.load() to call an ActionResult on the controller, which returns the partial view, passing parameters there in the querystring, but since these are ajax requests the main page url of the user's browser does not get updated.
Is there a best-practice for taking querystrings off the main-page URL and using them in ajax requests to other ActionResults?
If you want it to survive only through one request/redirect TempData is your friend.
However, for things like your pagination, URL is the best method, for the ability to share links alone.
A standard way is to pass those sort of things via URL Query Parameters. You can modify your routing to expect certain URL variables. That way the pages become more search engine friendly as well.
It depends on how permanent you want the information to be:
Things like the page number should indeed be in the URL (as others have pointed out) - this helps with bookmarking, etc, but remember that if you add more content to the list, then that bookmarked result set will not always be what the user wanted...
If you're happy for these values to be lost when a session times out (by default around 20 minutes), then put them in Session.
If you think that sessions are going to timeout before the next request, or you want to save it across visits then you should be storing them in either cookies, or a profile (potentially allowing "Anonymous" profiles, which work with the users cookies, so they would lose them across machines).
Personally, I'd think very carefully about putting sort order and columns in the URL if you do you could actually end up really confusing search engines:
Lots of pages with very similar content (page 1, sorted by date desc, page 1 sorted by date asc, etc) - search engines don't like duplicate content, and nor should you as Google (for instance) will only show two pages from your site in a default result set, you want them to be valid, not duplicates.
Search engines will spend lots more time crawling your site, and potentially give up - If on every page they find links to "Sort by this column", they will attempt to follow them, resulting in more work on the server, higher bandwidth use, etc.
These can be mitigated through the use of a Robots.txt file denying access to sorted versions of the page, but if this is generated almost dynamically that will be very complex to maintain going forward.
In response to your update, a nice way to achieve that for pages would be to have links to "Previous" and "Next" pages of results (or better yet, a list of all pages in the list), output on the page, with the page numbers, that you then hide with JavaScript.
This way users should see your nice, AJAXy behaviour, and search engines (and users without JavaScript - mobile, or those using older screen readers for instance) will still be able to get access to all your pages - this will help your pages to degrade gracefully, or use "Progressive Enhancement".
Things that were previously in viewstate should probably be put back in the clients hands via either hidden fields or cookies.
Session is "too" easy. In a dev environment it works great, pretty much no matter what you put in it. In production scalability and persistence become a problem. In-process session is likely to disappear unexpectedly if you have crashing bug in your site, and requires server affinity when load balancing. Out-of process session fixes the durability and affinity issues, but can still be a performance bottle neck if too much stuff is put in session. A VERY common problem is that each page will put 1 or 2 items into session but never take them out again when they are done. And even if a page removes it session data when it is no longer needed, the data can still get orphaned if a user starts a process and never completes it.
Cookies is a fast and simple way to persist data between requests, and you can also make them live only for a limited time depending on your needs.
Session are easiest.

asp.net url concealment?

In my asp.net 2005 app, I would like conceal the app structure from the user. Currently, the end user can learn intimate details of my web app as they navigate and watch the url change. I don't want the end user to know about my application structure. I would like the browser url to not change if possible. Please advise.
thanks
E.A.
URL rewriting is the only one that can provide any kind of real concealment.
Just moving the requests to AJAX or to frames, means anyone (well, more advanced users) can still see those requests being fired, just not in the address bar.
Simplest solution is to use frames - a single frame that holds your application and is 100% * 100%. The URL will not change though the underlying URL can still be seen via "View Frame info", however only advanced users will even figure that out.
In your pages, make sure that they are contained inside the holding frame.
A couple of possibilities.
1) use AJAX to power everything. This will mean that the user never leaves the home page
2) use postbacks to power everything. In this, you'd have all those pages be user controls which you progrmattically hide or show.
3) URL rewriting (especially if this is asp.net 3.0 or later)
My site uses url parameters to dynamically load ascx files into a single main aspx. So if I get 'page_id=123' on the query string, I load the corresponding ascx. The url changes, but only the query string - the domain part remains the same.
If you want the url to remain precisely the same at all times, then frames (per Oded) or ajax (per Stephen) are probably the only ways to do it.
Short answer: use URL encryption
A simple & straight article: http://devcity.net/PrintArticle.aspx?ArticleID=47
and another article: https://web.archive.org/web/20210610035204/http://aspnet.4guysfromrolla.com/articles/083105-1.aspx
HTH

re-rendering a site within an iframe?

I want to make a site where there user can basically navigate the web from within an iframe. The catch is that I'd like to be able to have more control over what is rendered within the iframe. Specifically,
I'd like to be able to filter out images or text, disable forms etc.
I'd also like to be able to gather feedback such as what links the users clicked on.
Question 1:
Is this even possible using a standard back-end scripting language (like php), with html and javascript on the frontend?
Question 2:
Would I first need to grab the source of the site before it is rendered, then do whatever manipulation is necessary, and finally re-render it somehow?
Question 3:
Could somebody please explain the programming flow that would occur here (assuming its possible)?
I think you would probably want to grab the source of the of site (with server-side code) before rendering it. You might run into cross-site scripting issues if you try to use JavaScript. Your iframe would load a page like render.php and pass the address of the page to render os a querystring parameter. Then use regular expressions to find elements in the HTML that render.php downloads from the address. Rewrite the HTML as necessary and then write it all out to the iframe.
Rewrite links so that that the user is taken to a page you control and redirected onto a target site if you want to track where people are going. Example: a link in the page needs to go to google.com. You would send them to tracker.php?target=http://google.com. You control tracker.php and can log each load of this page and then redirect the user to the target site.
Update:
Another possible solution is to use Apache or other server to proxy the target website. There are modules like mod_proxy for this. There may also be modules that let you parse the HTML or you could roll your own.
I should point out that even the best solutions offered to your question will be somewhat brittle if you do not have full control over the target site. You will want to have lots of error handling or alerting.
You can have a look at this. It uses iFrame really well, and maybe even use the library it has.

Resources