using static Dictionary instead of session asp.net mvc - asp.net-mvc

i have serialization problem with session(as i described here) so i used static Dictionary instead of session asp.net mvc
public static Dictionary<string, object> FlightDict;
FlightDict.Add("I_ShoppingClient", client);
in this case user will override their values?are there any problem with that
because they says with static variable users data can be overrided

Yes, you can change the static variables in the site, But You need to use this to change the data but that is not enough you need to lock this data until you have done.
public static Dictionary<string, object> CacheItems
{
get{ return cacheItems; }
set{ cacheItems= value; }
}
How to Lock?
The approach you need to use to lock all actions of add or remove until you done is:
private static Dictionary<string, object> cacheItems = new Dictionary<string, object>();
private static object locker = new object();
public Dictionary<string, object> CacheItems
{
get{ return cacheItems; }
set{ cacheItems = value;}
}
YourFunction()
{
lock(locker)
{
CacheItems["VariableName"] = SomeObject;
}
}
for manipulating the data on application state you need to use the global lock of it Application.Lock(); and Application.UnLock();. i.e
Application.Lock();
Application["PageRequestCount"] = ((int)Application["PageRequestCount"])+1;
Application.UnLock();
Last: Avoid Application State and use the Static Variable to Manage the Data across the Application for Faster Performance
Note: you can add one lock at the time only so remove it before you are trying to change it
Keep in Mind : The static variables will be shared between requests. Moreover they will be initialized when application starts, so if the AppDomain, thus application gets restarted, their values will be reinitialized.

Related

Need to pass a ds(data structure) when Http server is being started, and to make that ds global across controllers

So,
Here is the code setup.
There is a driver application, which starts the HTTP server(ASP.NET core Web API project).
The method called by driver application for starting HTTP server is
this:
public class Http_Server
{
public static ConcurrentQueue<Object> cq = new ConcurrentQueue<Object>();
public static void InitHttpServer(ConcurrentQueue<Object> queue)
{
cq = queue;
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
Controller Action Task:
[HttpPost]
[Route("XYZ")]
public virtual IActionResult AddXYZ([FromBody]List<Resourcemembers> resourcemembers)
{
//add something to ds
Http_Server.cq.Enqueue(new object());
//respond back
return new ObjectResult(example);
}
The data structure(a concurrent queue) being passed is to be made visible at controller level(like a global variable accessible across all controllers).
Is it fine to make the ds a static variable and access it across controllers?
Or Is there a way to pass this ds across to different layers?
This is my go at a better solution for this. What you are trying to do doesn't seem like the best way to approach this.
First, you want to enable caching in the application by calling the AddMemoryCache in the application StartUp.ConfigureServices method.
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMemoryCache();
...
}
Then, you want to use the cache. Something like this should get you going in the right direction.
public class XYZController : Controller {
private IMemoryCache _memoryCache;
private const string xyzCacheKey = "XYZ";
public XYZController(IMemoryCache memoryCache)
{
_memoryCache = memoryCache;
}
[HttpPost("XYZ")]
public IActionResult AddXYZ([FromBody]ResourceMember[] resourceMembers)
{
try
{
if (!_memoryCache.TryGetValue(xyzCacheKey, out ConcurrentQueue<Object> xyz))
{
xyz = new ConcurrentQueue<Object>();
_memoryCache.Set(xyzCacheKey, xyz, new MemoryCacheEntryOptions()
{
SlidingExpiration = new TimeSpan(24, 0, 0)
});
}
xyz.Enqueue(resourceMembers);
return Ok();
}
catch (Exception ex)
{
return BadRequest(ex);
}
}
}
public class ResourceMember { }
What this does is allow you to use a Memory Cache to hold your object(s), and what ever you Enqueue in the ConcurrentQueue object, should you stay with that as your main object within the Cache. Now, you can cache any object type in the MemoryCache, and pull the value when you need to based on the key you gave it when you added it to the cache. In the case above, I created a const named xyzCacheKey with a string value of XYZ to use as the key.
That static global variable thing you are trying is just not... good.
If this doesn't help, let me know in a comment, I will delete the answer.
Good luck!

HttpCache vs Singleton - Best practice for an MVC application

I am little bit confused in understanding of the HttpCache and Singleton approaches.
My application uses Asp.net MVC and the scenario is that, I have some List of Data that will never change and some data that might rarely change.
I have developed and deployed application using a Singleton repository for this type of data.
It performs great. The only issue is that when a rare case occur, i have to restart IIS to take effect.
What is the best solution.?
Singleton implementation
public class SingletonRepository : ISingletonRepository
{
private static SingletonRepository singleInstance;
private readonly IStateRepository stateRepo;
private readonly ICountryRepository countryRepo;
private readonly ITDPaymentModeRepository paymentModeRepo;
private readonly ITDPlanRepository planRepo;
private readonly ITDOrderTypeRepository orderTypeRepo;
private readonly IKeywordRepository keywordRepo;
private readonly IAgencyRepository agencyRepo;
private readonly IList<AT_STATE> lstState;
private readonly IList<AT_COUNTRY> lstCountry;
private readonly IList<TDPaymentMode> lstPaymentMode;
private readonly IList<TDPlan> lstPlan;
private readonly IList<TDOrderType> lstOrderType;
private readonly IList<Keyword> lstKeyword;
private readonly IList<Agency_MST> lstAgency;
private SingletonRepository()
{
stateRepo = new StateRepository();
countryRepo = new CountryRepository();
paymentModeRepo = new TDPaymentModeRepository();
planRepo = new TDPlanRepository();
orderTypeRepo = new TDOrderTypeRepository();
keywordRepo = new KeywordRepository();
agencyRepo = new AgencyRepository();
lstState = stateRepo.GetAll().Where(x => x.CountryId == 101).ToList();
lstCountry = countryRepo.GetAll().ToList();
lstPaymentMode = paymentModeRepo.GetAll().ToList();
lstPlan = planRepo.GetAll().ToList();
lstOrderType = orderTypeRepo.GetAll().ToList();
lstKeyword = keywordRepo.GetAll().ToList();
lstAgency = agencyRepo.GetAll().ToList();
//lstState = stateRepo.GetAll().Take(20).ToList();
//lstCountry = countryRepo.GetAll().Take(20).ToList();
//lstPaymentMode = paymentModeRepo.GetAll().Take(20).ToList();
//lstPlan = planRepo.GetAll().Take(20).ToList();
//lstOrderType = orderTypeRepo.GetAll().Take(20).ToList();
//lstKeyword = keywordRepo.GetAll().Take(20).ToList();
//lstAgency = agencyRepo.GetAll().Take(20).ToList();
}
public static SingletonRepository Instance()
{
return singleInstance ?? (singleInstance = new SingletonRepository());
}
public IList<AT_STATE> GetState()
{
return this.lstState;
}
public IList<AT_COUNTRY> GetCountry()
{
return this.lstCountry;
}
public IList<TDPaymentMode> GetPaymentMode()
{
return this.lstPaymentMode;
}
public IList<TDPlan> GetPlan()
{
return this.lstPlan;
}
public IList<TDOrderType> GetOrderType()
{
return this.lstOrderType;
}
public IList<Keyword> GetKeyword()
{
return this.lstKeyword;
}
public IList<Agency_MST> GetAgency()
{
return this.lstAgency;
}
}
}
The purpose of using the singleton pattern generally is not for static data storage. You should use a singleton when you only want one object instance to be able to perform certain actions. It may be fast, but as you can see, when the data changes, you need to reset the heap to get the new data (as you say, by restarting IIS).
HttpCache (more specifically, the ObjectCache which Http caching uses by default), stores the data in the same place as the heap: in Random Access Memory. So, it is just as fast as static data stored in a class or instance on the heap. The difference is that you can set up the cache to periodically go stale, so that it will get new data when the data changes. You can even set up SqlCacheDependencies so that the cache is made stale whenever your database's state changes.
Another advantage of cache is that it more efficiently utilizes your server's RAM resources. With your singleton, no matter what, this data will always be occupying memory, even when the data is not being used. With cache, the server only stores the data in memory when it is being used. The disadvantages with cache are that occasionally, a user here and there will get a slower response when they request data after the cache has expired. However, after they do, other users will benefit from the data being cached for a time.
You can actually reload the singleton by creating a reload method such as this:
public static void ReloadSingletonRepositoryInstance()
{
singleInstance = null;
SingletonRepository sr = SingletonRepository.Instance;
}
Hope that helps.

Singleton Dictionary in ASP.NET MVC Controller?

I have a controller in an ASP.NET MVC application. The page has several filters on it, that are represented in the controller by a Dictionary object. The filter dictionary looks like the following:
Dictionary<string,bool> filterMap = new Dictionary<string,bool>();
filterMap.Add("Accepted",true);
filterMap.Add("Rejected",true);
filterMap.Add("Valid",true);
filterMap.Add("Invalid",true);
On the page, there are toggle buttons to set the values of there respect dictionary item(i.e. If the "Accepted" Button is toggled off, it changes the value on the dictionary item to false.
My problem I am experiencing is, every time the page is called, the dictionary resets in the constructors and is initialized to the above value.
I have the following in my constructor, but it doesn't help because the dictionary is reset and is null every time.
public MyController(){
if (FilterMap == null)
{
FilterMap = new Dictionary<string, bool> {{"Accepted", true}, {"Returned",true}, {"Valid", true},{"Invalid",true}};
}
}
The easiest option would be to save the FilterMap in Session:
private Dictionary<string, bool> FilterMap
{
get { return (Dictionary<string,bool>)Session["FilterMap"] ?? GetDefaultFilterMap(); }
set { Session["FilterMap"] = value; }
}
private static Dictionary<string, bool> GetDefaultFilterMap()
{
return new Dictionary<string, bool> {{"Accepted", true}, {"Returned",true}, {"Valid", true},{"Invalid",true}};
}
Then in your action to toggle the filters make sure you set FilterMap again to save the change in Session (not necessary if you use in-memory session state):
public ActionResult ShowReturned(bool show)
{
var filterMap = FilterMap;
filterMap["Returned"] = show;
FilterMap = filterMap;
}
Note that if your dictionary is only going to have these keys, you might as well use a real class with Accepted, Returned, etc. as properties.

ASP.NET MVC HttpContext.Session object

I have a question. I've built custom class in my project that contains public static property ctx and assingn HttpContext.Current object to it. In runtime that property seem to reference HttpContext object, but ctx.Session class is null. When i debug my app the left side of an expression (ctx) is not exactly the same as right side (HttpContext.Current). why this is happening?
Grettings
HttpContext.Current is a singleton only for that request. By assigning the HttpContext.Current to a static variable you would be sharing this HttpContext.Current to an entire scope, which may not be right.
Session is a per user object while, static is an application wide object. Use static wisely.
What I would do would be something like this.
1- a static class (ex: ContextFactory) which provides current httpcontext. If it has HttpContext.Current, then is provides that value, if not then it provides an assigned context. In your case, new Mock<HttpContextBase>();
public static class ContextFactory
{
private static HttpContextBase current = null;
public static HttpContextBase Current
{
get { return current ?? HttpContext.Current; }
set { current = value; }
}
}
2- Then I alter the code UserSess to
public static class UserSess
{
public static UserID
{
get { return ContextFactory.Current.Session["UserID"]; }
set { ContextFactory.Current.Session["UserID"] = value; }
}
//...
}
sincerely

How to perform Cache Storage concept in Blackberry?

I need to create an application,that should contain two storage,one is persistent storage and another one is cache storage.After loading, the application should check the username and password with the cache storage data if it is empty then it should check with the persistent storage.How to accomplish this task?Is there any separate concept of cache or we have create the persistent as cache.please help me.
You can use RecordStore which is also persistent, or RuntimeStore which is shared between all apps but is non persistent.
Alternatively you can use some custom storage class to implement cache functionality,
storing, updating values in that class, sharing it as a field of Application class:
class Cache {
String mName = null;
String mPhone = null;
}
public class CacheApp extends UiApplication {
Cache mCache = null;
public static void main(String[] args) {
CacheApp app = new CacheApp();
app.enterEventDispatcher();
}
public CacheApp() {
initCache();
CacheScr scr = new CacheScr();
pushScreen(scr);
}
private void initCache() {
mCache = new Cache();
mCache.mName = "Name";
mCache.mPhone = "Phone";
}
}
class CacheScr extends MainScreen {
public CacheScr() {
CacheApp app = (CacheApp) UiApplication.getUiApplication();
String name = app.mCache.mName;
String phone = app.mCache.mPhone;
}
}
Coldice is correct, however I fail to see why one would use a store separate from PersistentStore (or RecordStore) for data that must endure and may be shared, and RuntimeStore for data which is shared but not durable. This just seems to be adding complexity to normal application transient storage.

Resources