site wide variables per user - asp.net-mvc-4

I have an MVC4 site that needs to maintain some information while (and ONLY while) the user is logged in. For example, once the user logs in, I get a 'user token' back that allows me access to several off site services.
I've tried two different approaches. The first was to use a public static class that accesses the user session. However, after reading up on static classes, I'm hesitant to use them. According to what I'm reading, static classes should only be used for read only objects, and I wasn't using it that way. Although the site site did seem to be working fine with a limited number of users (currently there's 10).
(If someone would like to explain to me why this is a bad idea in MVC4, please tell me and/or link to an article)
public class SessionAccessorClasses
{
public const string SessionAccessorSessionVariablesString = "_SessionAccessorSessionVariables";
public static SessionAccessorModel SessionVariables
{
get { return System.Web.HttpContext.Current.Session != null ? (SessionAccessorModel)System.Web.HttpContext.Current.Session[SessionAccessorSessionVariablesString] : null; }
set { System.Web.HttpContext.Current.Session.Add(SessionAccessorSessionVariablesString, value); }
}
}
My second (and current) approach is to use Session variables and access them using a globally available class.
public class SessionAccessorClasses
{
private const string SessionAccessorSessionVariablesString = "_SessionAccessorSessionVariables";
public SessionAccessorModel GetSessionVariables()
{
return System.Web.HttpContext.Current.Session != null ? (SessionAccessorModel)System.Web.HttpContext.Current.Session[SessionAccessorSessionVariablesString] : null;
}
public void SetSessionVariables(SessionAccessorModel value)
{
System.Web.HttpContext.Current.Session.Add(SessionAccessorSessionVariablesString, value);
}
public void ClearSessionVariables()
{
System.Web.HttpContext.Current.Session.Remove(SessionAccessorSessionVariablesString);
}
}
This works fine, but I hesitate to call it good is because I don't fully understand why the public static class was such a bad idea, and because I now have to instantiate my new class at the beginning of nearly every function, and call the Set/Update function at the end of every function; which feels wrong somehow.
So first, since my original static class was accessing the users session, is it really that bad?
Second, is my second class a more appropriate way of doing things? Can you suggest improvements?
Third, if nothing else, can you give me the positive/negative aspects of doing it either way?

You want to use Session in ASP.net. It was created for the purpose you describe.
ASP.NET session state enables you to store and retrieve values for a user as the user navigates ASP.NET pages in a Web application. HTTP is a stateless protocol. This means that a Web server treats each HTTP request for a page as an independent request. The server retains no knowledge of variable values that were used during previous requests. ASP.NET session state identifies requests from the same browser during a limited time window as a session, and provides a way to persist variable values for the duration of that session. By default, ASP.NET session state is enabled for all ASP.NET applications.
I'm a fan of strongly-typed reusable session variables, so I wrote the following extensions to store whatever variables you want to create without the need to constantly remember magic strings.
public static class SessionExtensions
{
public static bool TryGetValue<T>(this HttpSessionStateBase session, out T value)
where T : class
{
var name = typeof(T).FullName;
value = session[name] as T;
var result = value != null;
return result;
}
public static void SetValue<T>(this HttpSessionStateBase session, T value)
{
var name = typeof(T).FullName;
session[name] = value;
}
public static void RemoveValue<T>(this HttpSessionStateBase session)
{
var name = typeof(T).FullName;
session[name] = null;
}
public static bool ValueExists(this HttpSessionStateBase session, Type objectType)
{
var name = objectType.FullName;
var result = session[name] != null;
return result;
}
}
So if you have a class:
public MyClass
{
public int MyInt { get; set; }
}
You can store it by simply:
Session.SetValue(MyClass);
that needs to maintain some information while (and ONLY while) the user is logged in.
These methods could be updated a few ways to fulfill this requirement. Here is one way:
public static bool TryGetAuthenticatedValue<T>(this HttpSessionStateBase session,
out T value)
where T : class
{
value = null;
if (HttpContext.Current.User != null
&& HttpContext.Current.User.Identity != null
&& HttpContext.Current.User.IsAuthenticated)
{
var name = typeof(T).FullName;
value = session[name] as T;
}
var result = value != null;
return result;
}
I would also recommend that whatever classes you store in session, be serializable. That is to say it has a parameterless constructor and marked as [Serializable].

Related

.NET 5 Web API: Storing data per request

When getting a request in any action of any controller, I look at the jwt know which user is requesting and lookup the user in the database to get some user-data that I want to use throughout the application. E.g. which departments the user belongs to or the users preferred language.
Now I could create a object which wraps these information and send it down the layers and pass it to every method that likes to use some of this data. But I like the data to be available to every method throughout the application without passing it in every method. Like e.g. dependency injection (Seems to late at that point) or something else I can get access to that data quickly.
Any advice of how to handle it?
Try it with the Items property on the HttpContext. By using it you can store data during a single request. The only downside with this approach is that every service needs to have access to the HttpContext to read the values. Values can be added to the Items Dictionary as shown below
public class IndexModel : PageModel
{
//
public void OnGet()
{
HttpContext.Items.Add("Key", new RequestInfo { Key = "RequestKey" });
}
}
class RequestInfo
{
public string Key { get; set; }
}
You can then access the value by registering the IHttpContextAccessor to the IServiceCollection and then using Constructor injection to use the HttpContext in your service so that you can work with the Items Dictionary.
public class Service
{
private IHttpContextAccessor _htp;
public Service(IHttpContextAccessor http)
{
_htp = http;
}
public void Log()
{
Console.WriteLine(((RequestInfo)_htp.HttpContext.Items["Key"]).Key);
}
}

RavenDB UseOptimisticConcurrency in Config?

Is there a way to set optimistic concurrency to true in Raven.Server.exe.config? Or, can it somehow be applied at the database level? On RavenDB's site, I see a couple of mentions of setting UseOptimisticConcurrency = true, but it looks like it's at the session level within the code:
public void Save<T>(T objectToSave)
{
using (IDocumentSession session = Database.OpenSession())
{
session.Advanced.UseOptimisticConcurrency = true; // This is the setting
Guid eTag = (Guid)session.Advanced.GetEtagFor(objectToSave);
session.Store(objectToSave, eTag);
session.SaveChanges();
}
}
I would like to know if it that setting exists somewhere server-wide, so it doesn't need to be specified for each session in code.
Edit: The code above produces the following error. Trying to find out why...
Edit 2: Ok, I'm making progress. If I retrieve the object, and call GetEtagFor() all within the same session, then I get a valid eTag. So I guess my main question now is: Is the correct way to use a session, within a client UI, to open the session once when the app starts, and then close it at the end? And... What's the correct way to store the eTag? The way it's coded above, the eTag is retrieved right before storing, which I would imagine is the wrong way to do it. I'm guessing the eTag should be retrieved when the object is first retrieved. But when we originally get a list of objects, should we have to loop through each and call GetEtagFor() on them? Doesn't seem right...
Bob,
No, UseOptimisticConcurrency is something that you need to setup when you open the session.
And NO, a single session per the entire application is the wrong thing to do. See this article for more details on session management:
http://archive.msdn.microsoft.com/mag200912NHibernate
It talks about NHibernate, but the session management parts applies to ravendb as well.
Disclaimer: This is not a recommended approach, and in fact bad practice to open an IDocumentSession that will live as long as the client app lives. For an alternate solution, see the answer posted here: RavenDB Catch 22 - Optimistic Concurrency AND Seeing Changes from Other Clients.
It looks like I got optimistic concurrency working, so I thought I'd post this to help any else.
First, in DataAccessLayerBase, I initialize the DocumentStore and IDocumentSession. These will be open and used as long as the client app is running.
public abstract class DataAccessLayerBase
{
protected static DocumentStore Database { get; private set; }
protected static IDocumentSession Session { get; private set; }
static DataAccessLayerBase()
{
if (Database != null) { return; }
Database = GetDatabase();
Session = GetSession();
}
private static DocumentStore GetDatabase()
{
string databaseUrl = ConfigurationManager.AppSettings["databaseUrl"];
DocumentStore documentStore = new DocumentStore();
try
{
documentStore.Url = databaseUrl;
documentStore.Initialize();
}
catch
{
documentStore.Dispose();
throw;
}
return documentStore;
}
private static IDocumentSession GetSession()
{
IDocumentSession session = Database.OpenSession();
session.Advanced.UseOptimisticConcurrency = true;
return session;
}
}
Next, when retrieving the data, use the existing session:
public class CustomVariableGroupData : DataAccessLayerBase, ICustomVariableGroupData
{
public IEnumerable<CustomVariableGroup> GetAll()
{
return Session.Query<CustomVariableGroup>();
}
}
Finally, when saving, get the eTag and save.
public class GenericData : DataAccessLayerBase, IGenericData
{
public void Save<T>(T objectToSave)
{
Guid eTag = (Guid)Session.Advanced.GetEtagFor(objectToSave);
Session.Store(objectToSave, eTag);
Session.SaveChanges();
}
}
If another instance of the UI is running, and changes the object, a concurrency exception will occur. And that's what we wanted.
I just looked at the title of this post again, and realized this doesn't answer the question of how to set concurrency in the server config file. However, since it can now be set once in the data layer, that's good enough for me.

Ninject, Generic Referential Bindings

I think this falls under the concept of contextual binding, but the Ninject documentation, while very thorough, does not have any examples close enough to my current situation for me to really be certain. I'm still pretty confused.
I basically have classes that represent parameter structures for queries. For instance..
class CurrentUser {
string Email { get; set; }
}
And then an interface that represents its database retrieval (in the data layer)
class CurrentUserQuery : IQueryFor<CurrentUser> {
public CurrentUserQuery(ISession session) {
this.session = session;
}
public Member ExecuteQuery(CurrentUser parameters) {
var member = session.Query<Member>().Where(n => n.Email == CurrentUser.Email);
// validation logic
return member;
}
}
Now then, what I want to do is to establish a simple class that can take a given object and from it get the IQueryFor<T> class, construct it from my Ninject.IKernel (constructor parameter), and perform the ExecuteQuery method on it, passing through the given object.
The only way I have been able to do this was to basically do the following...
Bind<IQueryFor<CurrentUser>>().To<CurrentUserQuery>();
This solves the problem for that one query. But I anticipate there will be a great number of queries... so this method will become not only tedious, but also very prone to redundancy.
I was wondering if there is an inherit way in Ninject to incorporate this kind of behavior.
:-
In the end, my (ideal) way of using this would be ...
class HomeController : Controller {
public HomeController(ITransit transit) {
// injection of the transit service
}
public ActionResult CurrentMember() {
var member = transit.Send(new CurrentUser{ Email = User.Identity.Name });
}
}
Obviously that's not going to work right, since the Send method has no way of knowing the return type.
I've been dissecting Rhino Service Bus extensively and project Alexandria to try and make my light, light, lightweight implementation.
Update
I have been able to get a fairly desired result using .NET 4.0 dynamic objects, such as the following...
dynamic Send<T>(object message);
And then declaring my interface...
public interface IQueryFor<T,K>
{
K Execute(T message);
}
And then its use ...
public class TestCurrentMember
{
public string Email { get; set; }
}
public class TestCurrentMemberQuery : IConsumerFor<TestCurrentMember, Member>
{
private readonly ISession session;
public TestCurrentMemberQuery(ISession session) {
this.session = session;
}
public Member Execute(TestCurrentMember user)
{
// query the session for the current member
var member = session.Query<Member>()
.Where(n => n.Email == user.Email).SingleOrDefault();
return member;
}
}
And then in my Controller...
var member = Transit.Send<TestCurrentMemberQuery>(
new TestCurrentMember {
Email = User.Identity.Name
}
);
effectively using the <T> as my 'Hey, This is what implements the query parameters!'. It does work, but I feel pretty uncomfortable with it. Is this an inappropriate use of the dynamic function of .NET 4.0? Or is this more the reason why it exists in the first place?
Update (2)
For the sake of consistency and keeping this post relative to just the initial question, I'm opening up a different question for the dynamic issue.
Yes, you should be able to handle this with Ninject Conventions. I am just learning the Conventions part of Ninject, and the documentation is sparse; however, the source code for the Conventions extension is quite light and easy to read/navigate, also Remo Gloor is very helpful both here and on the mailing list.
The first thing I would try is a GenericBindingGenerator (changing the filters and scope as needed for your application):
internal class YourModule : NinjectModule
{
public override void Load()
{
Kernel.Scan(a => {
a.From(System.Reflection.Assembly.GetExecutingAssembly());
a.InTransientScope();
a.BindWith(new GenericBindingGenerator(typeof(IQueryFor<>)));
});
}
}
The heart of any BindingGenerator is this interface:
public interface IBindingGenerator
{
void Process(Type type, Func<IContext, object> scopeCallback, IKernel kernel);
}
The Default Binding Generator simply checks if the name of the class matches the name of the interface:
public void Process(Type type, Func<IContext, object> scopeCallback, IKernel kernel)
{
if (!type.IsInterface && !type.IsAbstract)
{
Type service = type.GetInterface("I" + type.Name, false);
if (service != null)
{
kernel.Bind(service).To(type).InScope(scopeCallback);
}
}
}
The GenericBindingGenerator takes a type as a constructor argument, and checks interfaces on classes scanned to see if the Generic definitions of those interfaces match the type passed into the constructor:
public GenericBindingGenerator(Type contractType)
{
if (!contractType.IsGenericType && !contractType.ContainsGenericParameters)
{
throw new ArgumentException("The contract must be an open generic type.", "contractType");
}
this._contractType = contractType;
}
public void Process(Type type, Func<IContext, object> scopeCallback, IKernel kernel)
{
Type service = this.ResolveClosingInterface(type);
if (service != null)
{
kernel.Bind(service).To(type).InScope(scopeCallback);
}
}
public Type ResolveClosingInterface(Type targetType)
{
if (!targetType.IsInterface && !targetType.IsAbstract)
{
do
{
foreach (Type type in targetType.GetInterfaces())
{
if (type.IsGenericType && (type.GetGenericTypeDefinition() == this._contractType))
{
return type;
}
}
targetType = targetType.BaseType;
}
while (targetType != TypeOfObject);
}
return null;
}
So, when the Conventions extension scans the class CurrentUserQuery it will see the interface IQueryFor<CurrentUser>. The generic definition of that interface is IQueryFor<>, so it will match and that type should get registered for that interface.
Lastly, there is a RegexBindingGenerator. It tries to match interfaces of the classes scanned to a Regex given as a constructor argument. If you want to see the details of how that operates, you should be able to peruse the source code for it now.
Also, you should be able to write any implementation of IBindingGenerator that you may need, as the contract is quite simple.

Where to store data for current WCF call? Is ThreadStatic safe?

While my service executes, many classes will need to access User.Current (that is my own User class). Can I safely store _currentUser in a [ThreadStatic] variable? Does WCF reuse its threads? If that is the case, when will it clean-up the ThreadStatic data? If using ThreadStatic is not safe, where should I put that data? Is there a place inside OperationContext.Current where I can store that kind of data?
Edit 12/14/2009: I can assert that using a ThreadStatic variable is not safe. WCF threads are in a thread pool and the ThreadStatic variable are never reinitialized.
There's a blog post which suggests implementing an IExtension<T>. You may also take a look at this discussion.
Here's a suggested implementation:
public class WcfOperationContext : IExtension<OperationContext>
{
private readonly IDictionary<string, object> items;
private WcfOperationContext()
{
items = new Dictionary<string, object>();
}
public IDictionary<string, object> Items
{
get { return items; }
}
public static WcfOperationContext Current
{
get
{
WcfOperationContext context = OperationContext.Current.Extensions.Find<WcfOperationContext>();
if (context == null)
{
context = new WcfOperationContext();
OperationContext.Current.Extensions.Add(context);
}
return context;
}
}
public void Attach(OperationContext owner) { }
public void Detach(OperationContext owner) { }
}
Which you could use like that:
WcfOperationContext.Current.Items["user"] = _currentUser;
var user = WcfOperationContext.Current.Items["user"] as MyUser;
An alternative solution without adding extra drived class.
OperationContext operationContext = OperationContext.Current;
operationContext.IncomingMessageProperties.Add("SessionKey", "ABCDEFG");
To get the value
var ccc = aaa.IncomingMessageProperties["SessionKey"];
That's it
I found that we miss the data or current context when we make async call with multiple thread switching. To handle such scenario you can try to use CallContext. It's supposed to be used in .NET remoting but it should also work in such scenario.
Set the data in the CallContext:
DataObject data = new DataObject() { RequestId = "1234" };
CallContext.SetData("DataSet", data);
Retrieving shared data from the CallContext:
var data = CallContext.GetData("DataSet") as DataObject;
// Shared data object has to implement ILogicalThreadAffinative
public class DataObject : ILogicalThreadAffinative
{
public string Message { get; set; }
public string Status { get; set; }
}
Why ILogicalThreadAffinative ?
When a remote method call is made to an object in another AppDomain,the current CallContext class generates a LogicalCallContext that travels along with the call to the remote location.
Only objects that expose the ILogicalThreadAffinative interface and are stored in the CallContext are propagated outside the AppDomain.

POCO's, DTO's, DLL's and Anaemic Domain Models

I was looking at the differences between POCO and DTO (It appears that POCO's are dto's with behaviour (methods?))and came across this article by Martin Fowler on the anaemic domain model.
Through lack of understanding, I think I have created one of these anaemic domain models.
In one of my applications I have my business domain entities defined in a 'dto' dll. They have a lot of properties with getter's and setter's and not much else. My business logic code (populate, calculate) is in another 'bll' dll, and my data access code is in a 'dal' dll. 'Best practice' I thought.
So typically I create a dto like so:
dto.BusinessObject bo = new dto.BusinessObject(...)
and pass it to the bll layer like so:
bll.BusinessObject.Populate(bo);
which in turn, performs some logic and passes it to the dal layer like so:
dal.BusinessObject.Populate(bo);
From my understanding, to make my dto's into POCO's I need to make the business logic and behaviour (methods) part of the object. So instead of the code above it is more like:
poco.BusinessObject bo = new poco.BusinessObject(...)
bo.Populate();
ie. I am calling the method on the object rather than passing the object to the method.
My question is - how can I do this and still retain the 'best practice' layering of concerns (separate dll's etc...). Doesn't calling the method on the object mean that the method must be defined in the object?
Please help my confusion.
Typically, you don't want to introduce persistence into your domain objects, since it is not part of that business model (an airplane does not construct itself, it flies passengers/cargo from one location to another). You should use the repository pattern, an ORM framework, or some other data access pattern to manage the persistent storage and retreival of an object's state.
Where the anemic domain model comes in to play is when you're doing things like this:
IAirplaneService service = ...;
Airplane plane = ...;
service.FlyAirplaneToAirport(plane, "IAD");
In this case, the management of the airplane's state (whether it's flying, where it's at, what's the departure time/airport, what's the arrival time/airport, what's the flight plan, etc) is delegated to something external to the plane... the AirplaneService instance.
A POCO way of implementing this would be to design your interface this way:
Airplane plane = ...;
plane.FlyToAirport("IAD");
This is more discoverable, since developers know where to look to make an airplane fly (just tell the airplane to do it). It also allows you to ensure that state is only managed internally. You can then make things like current location read-only, and ensure that it's only changed in one place. With an anemic domain object, since state is set externally, discovering where state is changed becomes increasingly difficult as the scale of your domain increases.
I think the best way to clarify this is by definition:
DTO: Data Transfer Objects:
They only serve for data transportation typically between presentation layer and service layer. Nothing less or more. Generally it is implemented as class with gets and sets.
public class ClientDTO
{
public long Id {get;set;}
public string Name {get;set;}
}
BO: Business Objects:
Business objects represents the business elements and naturally the best practice says they should contain business logic also. As said by Michael Meadows, it is also good practice to isolate data access from this objects.
public class Client
{
private long _id;
public long Id
{
get { return _id; }
protected set { _id = value; }
}
protected Client() { }
public Client(string name)
{
this.Name = name;
}
private string _name;
public string Name
{
get { return _name; }
set
{ // Notice that there is business logic inside (name existence checking)
// Persistence is isolated through the IClientDAO interface and a factory
IClientDAO clientDAO = DAOFactory.Instance.Get<IClientDAO>();
if (clientDAO.ExistsClientByName(value))
{
throw new ApplicationException("Another client with same name exists.");
}
_name = value;
}
}
public void CheckIfCanBeRemoved()
{
// Check if there are sales associated to client
if ( DAOFactory.Instance.GetDAO<ISaleDAO>().ExistsSalesFor(this) )
{
string msg = "Client can not be removed, there are sales associated to him/her.";
throw new ApplicationException(msg);
}
}
}
Service or Application Class
These classes represent the interaction between User and the System and they will make use of both ClientDTO and Client.
public class ClientRegistration
{
public void Insert(ClientDTO dto)
{
Client client = new Client(dto.Id,dto.Name); /// <-- Business logic inside the constructor
DAOFactory.Instance.Save(client);
}
public void Modify(ClientDTO dto)
{
Client client = DAOFactory.Instance.Get<Client>(dto.Id);
client.Name = dto.Name; // <--- Business logic inside the Name property
DAOFactory.Instance.Save(client);
}
public void Remove(ClientDTO dto)
{
Client client = DAOFactory.Instance.Get<Client>(dto.Id);
client.CheckIfCanBeRemoved() // <--- Business logic here
DAOFactory.Instance.Remove(client);
}
public ClientDTO Retrieve(string name)
{
Client client = DAOFactory.Instance.Get<IClientDAO>().FindByName(name);
if (client == null) { throw new ApplicationException("Client not found."); }
ClientDTO dto = new ClientDTO()
{
Id = client.Id,
Name = client.Name
}
}
}
Personally I don't find those Anaemic Domain Models so bad; I really like the idea of having domain objects that represent only data, not behaviour. I think the major downside with this approach is discoverability of the code; you need to know which actions that are available to use them. One way to get around that and still keep the behaviour code decoupled from the model is to introduce interfaces for the behaviour:
interface ISomeDomainObjectBehaviour
{
SomeDomainObject Get(int Id);
void Save(SomeDomainObject data);
void Delete(int Id);
}
class SomeDomainObjectSqlBehaviour : ISomeDomainObjectBehaviour
{
SomeDomainObject ISomeDomainObjectBehaviour.Get(int Id)
{
// code to get object from database
}
void ISomeDomainObjectBehaviour.Save(SomeDomainObject data)
{
// code to store object in database
}
void ISomeDomainObjectBehaviour.Delete(int Id)
{
// code to remove object from database
}
}
class SomeDomainObject
{
private ISomeDomainObjectBehaviour _behaviour = null;
public SomeDomainObject(ISomeDomainObjectBehaviour behaviour)
{
}
public int Id { get; set; }
public string Name { get; set; }
public int Size { get; set; }
public void Save()
{
if (_behaviour != null)
{
_behaviour.Save(this);
}
}
// add methods for getting, deleting, ...
}
That way you can keep the behaviour implementation separated from the model. The use of interface implementations that are injected into the model also makes the code rather easy to test, since you can easily mock the behaviour.