To cache or not to cache? And how to cache it on the base controller in asp.net mvc?

I create my own base controller, because I want to transfer some data to the main page. Now, since it is like adding this code to all the views in this controller, it runs every time.

By the time it loads for the first time, I think it hit my code at least twice. So I thought about caching it. But my book says that you donโ€™t cache personal data, because everyone sees it.

So I'm not sure what to do.

What my couple of lines of code does is this.

  • Finds the username and displays it to the user.
  • Find the user plan and display it.

So I need a username to find out what their GUID is, so I can find out what plan they signed up for.

Therefore, I do not know how to cache it, but do not disclose it to everyone. Is there cache access only for this user?

Quote Asp.net mvc framework unleasehd pg 330

Do not cache personal data

Caching a page containing a user's personal data is extremely dangerous. when a page is cached on the server, the same page is shared with all users. So, if you are caching a page that displays the user's credit card number, everyone can see the credit card number (not good!).

The same page is cached for all users even if you require authorization. Imagine, for example, that you are creating a financial services website and the site includes a page that displays all of the user's investments. The page displays the amount of money that the user has invested in a set of stocks, bonds and mutual funds.

Since this information is confidential, you require the user to log in before seeing the page. In other words, each user must be logged in before the user can view the page.

To improve the performance of a financial services page, you decide to enable page caching. You add the OutputCache attribute for the controller action that returns page

Do not do this! If you cache the actions of a controller that returns pages of financial services, private financial data for the first person to request that the page be each subsequent visitor to the application.

In the general case, adding an OutputCache and Authorize attribute to the same controller action opens the hole protection. Avoid this:

+4
source share
2 answers

The best way to answer if something needs to be cached or not is to determine if it really affects the performance of your site. With actual performance. Do not guess. If it doesnโ€™t hurt anything, and everything seems responsive, then I would say that work on something else until such a need arises. "Permanent optimization is the root of all evil," said a time or two :)

If you prefer to cache data, I'm not sure if you mean that everyone will be allowed to see this? If you mean the ASP.NET caching infrastructure ( HttpContext.Current.Cache ), then it lives in the memory of your server and is completely unstable (it will be destroyed at any time if the memory pressure reaches it). So make sure you keep that in mind and always check for null. To use it, you can simply use Cache.Insert() , and it has a couple of overloads to configure your caching settings.

Now, if you are talking about caching anything with cookie browsers, this is another story. Cookies are actually stored in the browser, and if you do not specify HttpOnly for the cookie, it can be read via javascript (this is only a problem if you have an XSS vulnerability somewhere), because an attacker could use javascript for "phone-home" "personal cookie data of users". Therefore, do not put anything private in the cookie if it is absolutely necessary, and if you do, you must specify HttpOnly and take appropriate steps to protect your users.

You definitely need to learn more about XSS and other common HTTP security issues if security really bothers you. (And it should be :)

UPDATED to address the issue of editing output caching:

Ok, so you specifically referred to Output Caching. Indeed, this book mentions a security hole that seems to have been fixed before MVC 1 was released. The Authorize attribute must be smart enough to handle Output Cacheing correctly when these two attributes are used together. Perhaps this book was written during the preview and is no longer relevant.

I quote the following: Steve Sanderson (author of Pro ASP.NET MVC Framework)

Update: Since the beta release, the [Authorize] Filter now does some smart tricking to collaborate with ASP.NET Output Caching. In particular, it registers the delegate using HttpCachePolicy.AddValidationCallback (), so that it can intercept future cache deletes and tells ASP.NET output caching not to use the cache when [Authorize] rejected the request. This solves the problem of caching ASP.NET output bypassing the [Authorize] filter. If you are going to write your own authorizations, be sure to pull it out of AuthorizeAttribute so you can inherit this useful behavior.

Note that this does not stop ASP.NET output caching bypassing any of your other action filters, and it does not add support for partial caching. If this is a problem for you then consider using [ActionOutputCache] (below).

It would be useful to read his article (and his book, for that matter): http://blog.codeville.net/2008/10/15/partial-output-caching-in-aspnet-mvc/

+2
source

Your controller classes only have a life cycle that extends from requesting action to rendering. Do you really need to cache this data? Just output the data to the model object. Queries do not seem complicated enough, and in addition, most RDBMS providers typically perform many caching queries.

HTTP is a stateless protocol, meaning that after a request, your web server forgets everything about this request. To get around this statelessness, asp.net offers application and session objects. The application is available worldwide for all requests, and Session is tied to a single IP address. Placing any data in it is usually the last resort, albeit a part of data caching schemes that do have a long download time.

The flow in ASP.NET MVC is approximately equal

  • URL requested
  • The controller is called
  • Action called
  • Action calls Model for data (username / user plan)
  • Action sets data in view mode
  • The action invokes the desired view with data in view mode.
  • The view is displayed.

Setting the data on the viewmodel is already 'private', so I'm not sure where the caching comes from. Perhaps I do not understand the question?

Edit

Well, forgive me first if my post was a bit arrogant. I really think that your code should not even go into the constructor of your base constructor. In the end, you will not transfer your controller for viewing.

It is good practice to pass typed ViewModels. Say this is your definition in your .master site

 <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MyNS.BaseViewDataModel>" %> 

And this is the definition of your help page:

 <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyNS.HelpViewDataModel>" %> 

Then you can create a BaseViewDataModel

 namespace MyNS { public class BaseViewDataModel 

And your HelpViewDataModel

 namespace MyNS { public class HelpViewDataModel : BaseViewDataModel { 

Then, in your assistant, deal with the actions

 [AcceptVerbs(HttpVerbs.Get)] public ActionResult Index() { var viewDataModel = new HelpViewDataModel (); viewDataModel.HelpText = "something"; .. .. return View(viewDataModel); } 

Now you can create your custom pointer and user plan in the BaseViewDataModel constructor, and it will only be called for actions that actually create an instance of the BaseViewDataModel subclass.

And your views are safe in type, which is a huge increase in productivity, since we scored those views that we can now call

 <%= this.Model.HelpText %> 

In the help window.

+1
source

All Articles