Offline cache navigation when internet is not available - asp.net

I am creating a Web Application using ASP.NET MVC 3 and I would like to enable offline access to the WebPage only when the Internet is not available.
I have a question:
I found a lot of tutorials for caching in ASP.NET MVC3 (for example Official Site) but how I can invalidate cache content if network connection is available and update cache content accordingly? Concequently, I want the user to be able to browse the online website if his internet connection is OK and browse the cached version of the website if internet connection is not available. PS. I am not sure if caching is the appropriate solution for this kind of problem.

Salamis,
I have been looking for a solution for a similar kind of problem. So far I can think of the below design to achieve what you need. I am not sure whether it is worth the pain. All the resources required for your application need to go via a Resource manager in client side. The resource manager for a given resource id, will fetch the content from the server and store it in localStorage when online and when offline would use the last fetched data from localStorage. These are easy for images as then can be stored as Data-Uri, but haven't thought about other resources.
May be for scripts which powers these should be cached by app manifest and for data to be retrieved by service calls and images can go through the Resource manager. But I have not really found any library / framework which does the above :(

Related

Migrate static content from ASP.NET project to Windows Azure platform

I've got asp.net project. I want publish it in azure platform. My project contains different static content: images, javascript, css, html pages and so on. I want store this content in azure blob storage. So, my questions are:
1) Is there any way to automate the process of migration this content from my application to blob storage?
2) How can I use data retreived from blob storage? Any examples would be great!
Best regards,
Alexander
First off, what you're trying to do could create cross-site scripting (they'll be on different domain names) or security issues (if you're using SSL). So make sure you really want to seperate the static files from the rest of your web site.
That said, the simpliest approach would be to use any one of a number of Windows Azure Storage management utilities (Storage Explorer or Cerebrata's Storage Studio would both work), to upload the static content to a Windows Azure Storage blob container. Then set the permissions on that container to publis read so that anyone with a web browser can access the contents of the container.
Finally, change all referrences to the content to point to the new URI's in blob storage and deploy your ASP.NET web role.
Again though, if I were you, I'd really look at what you're trying to accomplish with this approach. By putting it in blob storage, you do gain access to a few things (like CDN enablement), but as a trade-off, you lose control over many others (like simplified access control via IIS for request logs to tell when someone is downloading your image files a trillion times to try and run up your bill). So unless there's a solid NEED for this, I'd generally recommend against it.
Adding a bit to #Brent's answer: you'll get a few more benefits when offloading static content to blob storage, such as reduction in load against your Web Role instances.
I wrote up a more detailed answer on this similar StackOverflow question.
In light of your comment to Brent, you may want to consider uploading the content into Blob storage and then proxying it through a WebRole. You can use something like an HttpModule to accomplish that fairly seamlessly.
This has 2 main advantages:
You can add/modify files without reloading your web roles or losing them on role refresh.
If you're migrating a site, the files can stay at the same URLs they were pre-migration.
The disadvantages:
You're paying the monetary cost for Blob accesses and the performance cost to your web roles.
You can't use the Azure CDN.
Blob storage is generally slower (higher latency) than disk access.
I've got a fairly simple module I wrote to do exactly this. I haven't gotten around to posting it anywhere public, but if you're going to do this I can send you the code or something.

Sharing Data Between Two Web Applications in ASP.NET

I have a web application (MainApplication) where many of the pages contain a custom Web Control that looks for some content in a cache. If it can't find any data within the cache, then it goes out to a database for the content. After retrieving the content, the Control displays the content on the page.
There is a web application (CMS) in a subdirectory within the aforementioned web application. Users use this CMS to update the content pulled in by the MainApplication.
When a user updates some content using the CMS, I need the CMS to clear the relevant portion of the cache used by the MainApplication. The problem is that, as two different web applications, they can't simply interact with the same static cache object.
The ideal solution would be to somehow share an instance of a cache object between both web applications.
Failing that, what would be the best (performance-wise) way of communicating between the two web applications? Obviously, writing/reading to a database would defeat the purpose. I was thinking about a flat file?
Update
Thank you all for your help. Your wonderful answers actually gave me the right search terms to discover that this was a duplicate question (sorry!): Cache invalidation between two web applications
We had the exact same setup in a previous project i worked on, where we had one ASP.NET Web Application (with MCMS Backing), and another ASP.NET Web Application to display data.
Completely different servers (same domain though).
However, when a "editor" updated content in the CMS application, the UI was automatically refreshed.
How? Glad you asked.
We stored the content in SQL Server, and used Replication. :)
The "frontend" Web Application would read the data from the database (which was replicated by the CMS system).
Now - we don't cache this data, because in the database, we actually stored the markup (the HTML) for the control. Therefore we dynamically re-rendered the HTML.
Why is that "defeating the purpose"?
You can't get one application to "invalidate" the cache on another application.
If you're going down this path, you need to consider a distributed caching engine (e.g Velocity).
One option that comes to my mind in such scenario is using Velocity distributed cache mechanism. Do read about it and give it a try if possible http://msdn.microsoft.com/en-us/magazine/dd861287.aspx
In ASP.NET there is the notion of Cache Dependency. You can have a look here: http://www.codeproject.com/KB/web-cache/CachingDependencies.aspx or http://www.devx.com/dotnet/Article/27865/0/page/5.
There is also the Enterprise Library Caching Block available here that adds some feature to the standard stuff: http://msdn.microsoft.com/en-us/library/ff649093.aspx
Now, if you're running on .NET 4, there is a new System.Runtime.Caching namespace that you should definitely use: http://msdn.microsoft.com/en-us/library/system.runtime.caching.aspx
This article here "Caching in ASP.NET with the SqlCacheDependency Class" is quite interesting: http://msdn.microsoft.com/en-us/library/ms178604.aspx

Communicating between ASP.NET applications on the same machine

I have a situation where information about a user is stored in the web application cache and when that information is updated in one application - I want to notify the other applications (running on the same machine) that the data should be removed from it's cache so it can be refreshed. Basically I need to keep cached data in sync across multiple asp.net applications.
I have started down the path of using a central web service to help coordinate the notifcations but it is turning out to be more complex than I think it needs to be.
Is there a way that one asp.net application can easily reach across to another on the same box to clear an item from the cache?
Is there a better way to achieve shared cached information than using the application cache?
I really want to create a way for apps to communicate in a loosely coupled way - I looked at nservice bus but the dependency on MSMQ scared me away - my client has had bad experiences with MSMQ and does not want to support an app that requires it.
Suggestions?
Michael
I agree with Hogan. Best is to use a shared database. I want to add to that that, when using SQL Server, you can use SQL Cache Dependency. This SQL Server mechanism allows notifications to applications in such a way that used caches can be invalided directly after a change is made to the data.
A shared database is probably going to cause you the least pain.
Edit
Note: ASP.NET allows you to make "cache clearing" triggers on SQL server changes. Should be a quick search in the cache examples on MSDN to find some examples. Thus when the user info stored in the cache changes in the DB the local cache copy will clear and be re-loaded from the DB.
There are commercial distributed caches available for .net other than Microsoft Velocity - NCache, Coherence, etc.
How about Velocity? It's a distributed cache that works between servers as well as between applications. It has PowerShell management and all sorts of documentation to get you going faster and be far more maintainable in the long-term.
What about COM/DCOM, using namespace System.Runtime.Remoting

ASP.NET AJAX JavaScript files served from a static location

I realise that this is going to be a fairly niche requirement and will almost certainly raise a few "WTF's" but here goes...
Within an ASP.NET Webforms application I need to serve static content from a local client machine in order to reduce up-front bandwidth requirements as much as possible (Security policy has disabled all Browser caching). The idea is to serve CSS, images and JavaScript files from a location on the local file system referenced by filesystem links from within the Web application (Yes, I know, WTF's galore but that's how it is). The application itself will effectively be an Intranet app that's hosted externally from a client but restricted by IP range along with standard username/password security. So it's pretty much a hybrid Internet/Intranet application but we can easily roll out packages of files to client machines. I am not suggesting that we expect nor require public clients to download packages of files. We have control to an extent over the client machines in terms of the local filesystem and so on but we cannot change the caching policy.
We're using UpdatePanel controls to perform partial page updates which obviously means that we need to Microsoft AJAX JavaScript files. Presently these are being served (as standard) by a standard resource handler within IIS/ASP.NET. Ideally I would like to be able to take these JS files and reference them statically from a client machine, and no longer serve them via an AXD.
My questions are:Is this possible?If it is possible, how do we go about doing so?
In order to attempt to pre-empt some WTF's the requirement stems from attempting to service a requirement with as little time and effort as possible whilst a more suitable solution is developed. I'm aware that we can lighten the load, we can switch to jQuery AJAX updates, we can rewrite the front-end in MVC etc. but my question is related to what we can quickly deploy with our existing application architecture.
Many thanks in advance :)
Lorna,
maybe your security team is going crazy. What is the difference between serving a dynamic HTML generated by the server and a dynamic JS generated by the server?
It does not make any sense. You should try talking them out of it.
what is the average size of pages and viewstate data. you might need to store viewstate in sqlserver rather than sending it to client browser every time.

How to write an offline version of an AJAX/ASP.NET web application

We have a web application that uses AJAX to talk to an ASP.NET web service. We would like to write another version that can be used offline. We need to be able to re-use our existing code as much as possible. What approaches should we consider?
The app is currently using XmlHttpRequest to get dynamic data from the server. Obviously the offline version will not be able to talk to the server, but it does need to talk to something! I'm sure installing IIS or Cassini on the client would work, but I was hoping for a simpler solution. Is there no other way for JavaScript to talk to some external code?
There are plenty offline web apps nowaday. It simply evolve from AJAX.
For example:
WoaS (wiki on a stick / stickwiki), Tiddly Wiki,
Google doc and Gmail is going to be offline.
You don't need a webserver to run these webapps in offline mode. Just store the required data, scripts on the client side (usually as XML).
One of the possibilities would be to use Cassini. This is a web server that acts as a host for the ASP.Net runtime. You can host Cassini in a Windows application or a Windows Service. In this scenario you do not have to rewrite the web app and the web service.
Most other solutions do require a rewrite of both your web app and your web service. Depending on the way you have written the existing app you can reuse more or less code.
Have you considered HTML5 with application cache and offline storage?
If you hope to create an "offline" version of your package your biggest issue by far will be the need to install your site into a local copy of IIS (registering a virtual directory, etc.). I pursued this briefly a few years ago and gave up in frustration. It can be done: a number of software vendors such as DevExpress do this so you have local copies of their demonstration projects. Indeed, I was able to do this. The problem was the classic "it works on my computer" syndrome. There was simply no way to guarantee that most of my end-users had anywhere near the technical proficiency to make this work.
Thus, I would strongly recommend that you not pursue this path unless you have very technically proficient users and a huge support staff.
But there is one more very important question: did you abstract all data access code to a DAL? If not, then you have a lot of work to do in managing data access as well.
Update: user "Rine" has recommended Cassini. I just wanted to let you know that I pursued Cassini and another 3rd-party web server as well. I think that there are licensing issues with Cassini but may be wrong - it has been awhile. However, I do distinctly remember running into barrier after barrier with this approach and very little documentation to help me out.
if you want a web application run offline, you need a webserver (IIS for ASP) bound to the localhost (127.0.0.1) address. After this so can access your web application by typing http://127.0.0.1/ in your web browser the same way as you do online.
If your AJAX relies on XMLHttpRequest's, you can:
Make the static versions of XML's you get over XMLHttpRequest and put then into a folder on disk.
Rewrite your XMLHttpRequest URL's so that they point to files on disk.
Rewrite your XMLHttpRequest's so that they don't check status (it's always 0 for the file:// protocol.
All JScript works on file:// pages as well as on http:// ones.
Of course it's not the best way to develop static pages, but it may save you some time on rewriting.
I havent come across any framework specifically built for asp.net like the ones available for PHP or RoR.
Here is a good article by Steven to get you started with HTML 5 and ASP.Net Creating HTML 5 Offline application
Obviously the offline version will not be able to talk to the server, but it does need to talk to something!
Enter HTML5 LocalStorage. It works like a database and enables you to put data on your client. Indeed you have to rework parts of your code in javascript and transmit it to the client, but then it would work offline.
Local Storage works like this:
- Setter: window.localStorage.setItem(KEY, VALUE)
- Getter: window.localStorage.getItem(KEY)
- Remove: window.localStorage.removeItem(KEY)
To get the main page working offline you need to create a manifest. This is used to store complete sites on the client. Please refer to this for more information about manifests:
http://diveintohtml5.info/offline.html
You want to build a web application to work offline?? It can't be done.
You could split the interface code from the rest (in diferent dlls) and create a windows application to mimic the behaviour of your web application. This way you have 2 distinct user interfaces but the same code for business rules and data access.
I don't really see any other way...

Resources