What is difference between HttpContext.Current.Cache and HttpContext.Response.Cache? - c#

Wanted to know about - What is the different between HttpContext.Response.Cache and HttpContext.Current.Cache objects ? and What should be used in Asp.net MVC web application?
Why I am asking this question?
Because, I have my own [NoCache] attribute, which is responsible to avoid cache during the view redirection.
E.g.
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var cache = filterContext.HttpContext.Response.Cache;
cache.SetExpires(DateTime.Now.AddDays(-1));
cache.SetValidUntilExpires(false);
cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
cache.SetCacheability(HttpCacheability.NoCache);
cache.SetNoStore();
base.OnActionExecuting(filterContext);
}
And I am using this above attribute in my BaseController, like..
[NoCache]
public class BaseController : Controller
{
}
This works fine!
BUT, in the authentication part - I am storing some information in the cache by below mechanism
public ActionResult Login()
{
HttpContext.Current.Cache.Insert("someKey", "someValue", null, expiredTime.Value, Cache.NoSlidingExpiration);
return view();
}
SO, my Question is..
I am using my custom attribute in base class of controller, which is responsible to clear the cache items, even though, I can still access the cache key and value throughout the application which was set by the Login method code..
Why this both cache mechanism act differently? What is the difference between these two?
Could you please suggest some idea or information on this.

HttpContext.Current.Cache is a class that provides caching of any kind of serializable objects. It in itself equates to HttpRuntime.Cache to muddy your waters even more.
We use HttpContext.Current.Cache usually to cache data from our database servers. This saves having to continually ask the database for data that changes little. This is entirely server-side and does not affect the client.
HttpResponse.Cache allows you to set up and control the various cache control headers sent with the response content. This tells the client (and any in-between proxies) what kind of caching you suggest. Note I say suggest, because it's entirely arbitrary whether the client honors it or not.

Related

ASP.NET WebAPI - how to create an abstract layer for multiple services

Alright, so assuming I am making a fancy web store.
I have a payment provider (say, paypal) which requires the user to sign into paypal website, confirm the credentials and then to redirect him into my website.
So basically the code behind that would look like this:
class PaymentManager
{
public string AcceptPayment(Payment payment)
{
//return redirect url
}
public bool ConfirmPayment(string paymentToken)
{
//if token is valid the payment succeded
}
}
So basically the usage of this manager from my controller maps into 2 controller methods (each requiring an individual request).
Now, assuming I have a different payment manager, which requires 3 methods being sequentially executed instead of 2. Something like:
class AnotherPaymentManager
{
public string AcceptPayment(Payment payment)
{
//return validation redirect url
}
public string ValidatePayment(string validationCode)
{
//return redirect url
}
public bool ConfirmPayment(string paymentToken)
{
//if token is valid, confirm payment
}
}
Now this class' usage maps into 3 controller methods (we need the client to execute the Accept method to declare payment, then to execute the Validate method to validate it and after all to execute the Confirm method to make sure the server has accepted it).
The question is: provided these managers have different API usage scenarios to do the same thing (as shown above), is there a way to make an abstract layer between them and the controller? I mean something like:
interface IPaymentManager
{
void MakePayment(); //this controls the payment methods flow
//Something like (Accept -> Confirm) in the former case
//and (Accept -> Validate -> Confirm) in the latter
}
I am doing this in ASP.NET WebAPI 2, but I think it may apply to MVC as well.
If I understand correctly, when a user creates a transaction they are redirected to the payment provider (with a redirect url in the response). Once there they confirm their credentials which returns them to your fancy web store (with a confirmation token provided by the payment provider). If that token is valid then the transaction was successful. Also each of those actions require a separate endpoint in your controller.
If those assumptions are correct, I would say it is not necessary, or even recommended, to create an abstraction here. Also there is response data (validationCode, paymentToken, etc.) from the payment provider which your PaymentManger functions and controller endpoints are dependent on in order to proceed in the process.
In my experience, trying to abstract too early can make more work for you down the road. Without more information (more implementations of payment provider clients) you might make abstractions that are too specific - which can not be used for different PaymentManager types you add later.
However, if you already posses this data (validationCode, etc.), then you could abstract here, but I would still say it is unnecessary, and potentially a waste of time.
If you are determined to abstract here, then you can implement your interface in each of your PaymentManager classes. Having each PaymentManger implement the MakePayment function which would call the respective PaymentManager functions.
Again, I would not recommend abstracting here. It doesn't make sense, and really won't be that helpful in my opinion. Wait until you implement a few more PaymentManager classes. Then you will be able to more accurately see the patterns between the different types of PaymentMangers and abstract those patterns out.
If my understanding of the problem was not correct, let me know where I misunderstood the problem, and I will try to answer it again.
On a side note, I would recommend looking into asynchronous functions and the await operator, if you haven't already and are making calls to an external API.
Hope this helps.

Caching Data in ASP.NET MVC 3

I have an ASP.NET MVC 3 app that is basically just a set of web services. These web services are exposed by a set of Controller actions. Each controller action queries my database. Because my data rarely changes, and, stale data is not a concern, I thought i would implement some cacheing to improve performance. My goals are:
Never cache a response to a user.
Cache the database records for up to 24 hours. If 24 hours has passed, hit the database again.
Does that make sense? I know how to prevent the response from caching. I just use the following:
HttpContext.Response.Cache.SetCacheability(cacheability)
However, I'm not sure how to cache my database records in memory for up to 24 hours. Does anyone have any suggestions on how to do this? I'm not even sure where to look.
Thank you
You can use the System.Runtime.Caching namespace (or the ASP.NET cache, but this is older and can only be used within web applications).
Here's a sample function which you can use to wrap around your current data retrieval mechanism. You can alter the parameters in MemoryCache.Add to control how much it's cached, but you requested 24h above.
using System.Runtime.Caching; // At top of file
public IEnumerable<MyDataObject> GetData()
{
IEnumerable<MyDataObject> data = MemoryCache.Default.Get(MYCACHEKEY) as IEnumerable<MyDataObject>;
if (data == null)
{
data = // actually get your data from the database here
MemoryCache.Default.Add(MYCACHEKEY, data, DateTimeOffset.Now.AddHours(24));
}
return data;
}
As mentioned by #Bond, you may also wish to look at using an SQL Cache Dependency if the data you're caching is likely to change within the 24 hours. If it's pretty static though, this will do what you asked.
The MVC framework is persistence-agnostic. There are no built-in means to store data, so there are no built-in means to cache stored data.
The OutputCache attribute can be used to cache a server response. But you explicitly stated that that's not something you want to do.
However, you may still be able to use the built-in OutputCache if you want to stay within the MVC framework. Consider exposing the data you want to cache as a JSON result
[OutputCache(Duration = 86400)]
public JsonResult GetMyData() {
var results = QueryResults();
return Json(results);
}
The JSON string at /ControllerName/GetMyData will be cached for 24 hours, so the actual query will only be ran once per day. That means you'd have to implement an AJAX call on your final page, or make another HTTP call from your server. Neither of those are ideal.
I would look for another solution to your problem outside of the MVC framework. Consider memcached, which was created for exactly this purpose.
What you are talking about is not exactly MVC responsibility. ASP.Net allow you to cahce only the things it produces (and this they are responces, obviosly).
If you want to cache data it can be better to cachet it the same place it was produced - somewhere in BL or Data Layer.
You can do something like that:
public class DataCacher
{
private static String data;
private static DateTime updateTime;
private DataCacher() { }
public static String Data
{
get
{
if (data == null || updateTime > DateTime.Now)
{
data = "Insert method that requests your data form DB here: GetData()";
updateTime = DateTime.Now.AddDays(1);
}
return data;
}
}
}
String data presents your actual data here. After adding this class replace your GetData() methods with DataCacher.Data.
Hope it helps or at least leads you to some further thinking.
If you're using MSSQL you may want to look at SQL Cache Dependency.
I'm not sure if you can configure cache expiration to 24 hours but with the cache dependency you may not need to - it will invalidate the cache as soon as there is an update on the database(i.e. should be more efficient than the time expiration strategy).
Here is a good article which discusses several performance related practices for ASP.NET MVC 3 and caching is mentioned.

Maintaining state in a MVC2 Controller

I want to maintain model state between method calls on the controller.
Is that possible?
A controller is created at the call of some of its methods and destroyed when the called method finishes its execution?
If not... how can I maintain the state between method calls?
If that is possible... how has it to be written?
thanks
Let's keep this simple! :-)
You asked following questions:
I want to maintain model state between method calls on the controller.
Is that possible?
Answer: yes, it is
A controller is created at the call of some of its methods and destroyed when the called method finishes its execution?
Answer: yes, it doesn't persist any state - it just returns the result generated by the action
If not... how can I maintain the state between method calls? If that is possible... how has it to be written?
Answer:
We had the same issue in our current business application using ASP.NET MVC2 and came up with following solutions:
Solution(s):
1st he Proof-Of-Concept for this application contained some special functionality using the global Session. (Note that the session is saved on the webserver)
Saving and reading from session in ASP.NET MVC:
public Action SaveIntoSession()
{
...
Session["SessionData"] = "Something to be stored in session";
...
}
public action ReadFromSession()
{
...
// UNBOXING is required when you're using the session as ASP.NET doesn't know what is stored into the session
string sessionData = (string)Session["SessionData"];
...
}
2nd There's another concept of saving the required information for each request into a Session Table into your database. (But I won't go too deep into that.. check this article for more info - although it's php, you can get your head around the concept pretty easily)
3rd Would be to use the TempDataDictionary as mentioned by Charlino. The problem with this is, that it only persists the state from one call to the another. All data that is stored will be deleted by the next request. (TempData is mostly used to display errors to the user..)
public Action SaveIntoTempData()
{
...
TempData["TempData"] = "Something to be stored ONE request ONLY";
...
}
public Action ReadFromTempData()
{
...
string tempData = (string)TempData["TempData"];
}
4th You could also use the ViewDataDictionary. It is not recommended to be used with sensitive data. (check this thread for more info)
public Action SaveIntoViewData()
{
...
TempData["ViewData"] = "Something to be stored into the page";
...
}
public Action ReadFromViewData()
{
...
string viewData = (string)ViewData["ViewData"];
}
At the end of the day. It is up to you and your team what best matches requirements.
You have access to the standard ASP.NET session, even in MVC. Check the docs.
Would TempData / TempDataDictionary be suitable?
HTHs,
Charles
I think by default you should be trying for a Restfull approach. If that is not viable then either serialise to the session object or store in a Singleton or something like that.
By default I don't think MVC maintains state between calls.

What are the best practices to persist`Conversational state' in ASP.NET MVC applications?

What is the ultimate workaround?)
Desired scenarios are:
Multistep forms.
If a page has tabs on it, the tabs should persist their `viewstate'
Whatever navigation user has chosen, it shouldn't affect (more appropriately, bother) the conversational state management.
Those are just several aspects, but I find them much practically relevant.
I have worked once on Wizard kind of form in Asp.Net MVC and best thing to do in this case is to use Model/ModelBinding to keep track of form input.
We can create a chain of Controller Actions (for each steps) with output model of each serving as the input Model for the next Step (Action).
For example if we have three steps for creating a user. Then UserController can have actions for each steps.
public ActionResult Step1()
{
User user = new User();
return View(user);
}
[Post]
public ActionResult Step1(User user)
{
//perform business validation
RedirectToAction<UserController>(u => Step2(user));
}
After this Step2 action will take over with modified user from Step1 and can render its own view and so on.
You may also want to check out http://blog.maartenballiauw.be/post/2009/10/08/Leveraging-ASPNET-MVC-2-futures-ViewState.aspx. There's an Html.Serialize() helper in MVC Futures. The article refers to it as lightweight Viewstate, but it's effectively just a glorified wrapper around "serialize this object and store the base64 string in a hidden form field." If you need state to be associated with individual pages rather than an entire Session, this helper might be appropriate for your needs.
Not sure about a "workaround", but have you considered using AJAX and jQuery? Both would be appropriate based on the requirements you listed.

SQL role security + custom ASP.Net base page

I'm workng on a new, green-field ASP.Net application. We're implementing a base page which all pages will be, er, based on. The application will be running under Integrate Windows Auth, so I'll have the user's account details. With these, I'll be going to several databases (in which the user will exist) to find out what roles they are assigned to in each db. I'll be holding the role yay/nay in a bool array, and key into it via an enum.
There will be a session object that will hold a few things, and the roles assigned for that user. I'm thinking of making the session object available as a property of the base page, as the code would be something like this:
public SessionObject MasterSessionObject
{
get
{
if (Session["SessionObject"] == null)
{
// Create session object, assign user name, etc.
// Do something with roles...
Session["SessionObject"] = sessionObject;
}
return (SessionObject)Session["SessionObject"]
}
}
In order to control what happens on the (sub-classed) page, I want to provide a CheckSecurity method - e.g. if the user is not authorised to a certain part of a page, it can be hidden / disabled, or they could be booted back to a "not yours" page. The logical place for it is the base page, but seeing as the base page is already exposing the SessionObject that holds the roles permissions, would it not make more sense to Create a DatabaseSecurity type object and have the check on that?
Dealing with the latter approach, I've used abstract base classes to get me so far: I have a DatabaseRoles abstract class which contains the bool array, and a method to retrieve the roles for the user. The concrete implementation holds an Enum (as previously mentioned) to key into the array (in the base class). The abstract class also has the CheckRole method which takes in an int, to which I'm intending use a cast of the enum...
The SessionObject contains several of these DatabaseRoles implementations, and essentially does away with the need for a CheckSecurity in the base page class, leading to code like this in the actual page:
if (MasterSessionObject.SampleDatabaseRoles.Check((int)SampleDatabaseRolesEnum.RoleView))
{
// Do something
}
But, I'm sure you'll agree, it looks sucky...
If there was a CheckSecurity method on the base page, it would have to take a concrete DatabaseRoles object, but also an enum of which role to check, which would also look sucky. And finally, there would be a requirement at a later date to add more databases and their security settings...
I'll add code tomorrow if required... :-s
I dunno, I'm not that thick, but I do have a hard time sometimes binding all this together...
Thank you,
Mike K.
IF you happen to use ASP.Net / ASP.Net MVC, I would say the best place to do this would be via a custom HTTP Module by handling the AuthenticateRequest method & continuing with the request only if the request has been authenticated. There are tons of excellent articles online for this code.
Also - have a look at the Roles & Memberships of ASP.Net - it is pretty good & generally satisfies most requirements or you are always free to extend it. Again - tons of articles on custom membership providers...
unless I am missing something - HTH.

Categories