Most painless multi-tenancy implementation using ASP.NET, NHibernate / Fluent NHibernate - asp.net-mvc

I'm trying to implement multi-tenancy in an ASP.NET MVC application I have, that uses NHibernate. Though I have control over the database for multi-tenancy. I'm trying to figure out the best way to filter our database queries using NHibernate.
I would like to know if there is a painless way where I can append a condition (something like WHERE InstanceID = 1) to every CRUD query to the DB using NHibernate.
I looked at global filters. But I wasn't sure if I'm using it the right way. I tried something like this.
NHibernateSession.GetDefaultSessionFactory().GetCurrentSession()
.EnableFilter("instance-filter").SetParameter("InstanceId", "2");
But it didn't seem to work. Any good example of NHibernate global filters / any good approach of filtering all DB queries with a condition would be highly appreciated.

I've been looking for the same thing for a small project of mine that's still in planning phase. The most complete implementation of using a single database that I came upon is written by Michael Valenty in his blog post: Bolt-on Multi-Tenancy in ASP.NET MVC with Unity and NHibernate: Part II – Commingled Data. He's also using global filters.
Just for the sake of completeness, here are the mappings he used:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<filter-def name="tenant">
<filter-param name="id" type="System.Int32" />
</filter-def>
</hibernate-mapping>
And for each entity:
<class name="User" table="[user]">
<id name="Id" column="user_id">
<generator class="identity" />
</id>
<property name="Username" />
<property name="Email" />
<filter name="tenant" condition="tenant_id = :id" />
</class>
After that, he uses his IoC container of choice to inject the parameter value to instance of ISession.
session.EnableFilter("tenant").SetParameter("id", c.Resolve<Tenant>().Id);
There's also an interceptor to implement - to write the value of current tenant id when saving the entity (OnSave method), and also to check whether the given entity belongs to current tenant when loading the entity by id (OnLoad method). OnLoad override is necessary because tenant filter won't be applied when loading entity by id.

Related

Breeze doesn't post navigation properties

I inherited an OData service that exposes - among other things - a type called Evaluation. This type contains a lot of primitive type properties (int, bool mostly) and two navigation properties/links to other entities.
Breeze is configured to use the v3/'original' odata adapter:
breeze.config.initializeAdapterInstance('dataService', 'odata', true);
If I create a new entity
var manager = new breeze.EntityManager('odataEndPointHere');
manager.fetchMetadata().then(() => {
var newEvaluation = manager.createEntity('Evaluation', {Name:'Foo'});
});
then this newEvaluation will reference all primitive fields and the navigation properties (called Validation - a TPH type - and Replacements - a ~normal~ 1:1 entity relation). If I expand() that relation, I can query for existing Evaluations and will see the expected Validation value.
Grabbing an existing Validation instance and assigning it seems to work as well:
manager.fetchEntityByKey('Validation', existingIdHere).then(validation => {
newEvaluation.Validation = validation; // works, while assigning a non-entity throws
});
But if I call manager.saveChanges(); the server reports that there's no (mandatory) Validation link. Looking at the POST to the $batch endpoint I see that breeze really only posts a subset of the Evaluation type, only posts the primitive fields and none of the navigation properties. This happens for both existing (fetched and updated) and new (createEntity) objects.
Now, I understand that I've yet to create a small test case - given that this is a service that I cannot directly control I'm still trying to figure out how I'm going to provide a reduced recipe for reproduction.
That said:
breeze can query all my entities, just fine. Expanding the navigation properties works flawlessly
breeze completely ignores the very same properties during saveChanges() for me
(unrelated?) breeze offers no way for me to set the FK ID only (http://breeze.github.io/doc-js/navigation-properties.html, "Setting the Foreign Key directly") although it does list the navigation properties in manager.metadataStore.getEntityType("Evaluation").navigationProperties
Edit:
The $metadata result contain this for the entities in question:
<EntityType>
<!-- snip the rest --->
<NavigationProperty Name="Evaluations" Relationship="MyNamespace.Entities.FK_Evaluation_Validation" ToRole="Evaluation" FromRole="Validation" />
</EntityType>
and later:
<AssociationSet Name="FK_Evaluation_Validation" Association="MyNamespace.Entities.FK_Evaluation_Validation">
<End Role="Validation" EntitySet="Validations" />
<End Role="Evaluation" EntitySet="Evaluations" />
</AssociationSet>

How to set SimpleMembershipProvider to require unique email?

I started a new MVC 4 application using VS 2012 and I noticed it is recommending the use of SimpleMembershipProvider.
I like the idea and all the goodies of the WebSecurity class (which helps a lot).
I'd like to be able to set the RequiresUniqueEmail property to true the documentation doesn't have a suggestion on how to accomplish that.
Can you add the property requiresUniqueEmail="true" to the
<membership>
<providers>
<add name="SimpleMembershipProvider"
type="whatever your assembly name is"
...
requiresUniqueEmail="true"/>
tag in your web.config? That's how it's done for the default membership provider. I would imagine it would be the same for the Simple version (unless that feature was not implemented).

ASP.NET MVC - Database entities or ViewModels?

I am currently working on an ASP.NET MVC project.
Some developers on the team want to bind the auto-generated database entities directly to the Views.
Other developers want to create tailor-made ViewModel's and bind those to the Views.
Objectively, what are the pros and cons of both approaches?
(By "database entities" I am referring to the auto generated classes that an ORM framework generates, such as LINQ to SQL, Entity Framework or LLBLGen).
Definitely use view models in your views, and use something like AutoMapper to create view models from entities easily.
Cons:
Sometimes it feels like you are duplicating code, specifically, when the view model and the entity have the exact same properties
Pros:
You often need to represent an object in a simpler format (often called flattening), but you need full fidelity on the server side. This allows you to transition between the two without mucking up your domain model with presentation cruft.
Aggregate roots often have a lots of value objects and additional entities that are irrelevant to a specific view, and omitting them in a view model makes it easier to work with.
Your entities will have lots of two way references that are sensible in terms of an API, but create pure hell when serializing them for JSON, XML, etc. View models will eliminate these circular references.
You may often use the same entity but in different ways for different views. Trying to balance both needs on one type can create a huge mess.
The orthodoxy is that you should never use your raw database entities in your views. Like any rule, it is there to be broken if you know your entities well and you understand the consequences, but there are very good reasons not to break that rule, particularly when working in teams and with code that will be maintained in future by people who might not understand the rule or the entities as well as you do. The main reasons are:
ORM lazy loading. Imagine your Customer has a lazy loaded collection Orders. You pass Customer off to the View and it iterates over Orders. You get an N*1 select on the Orders table. But it also means that your database connection still needs to be open in the View. There is a pattern that people use 'Transaction per Action' which disposes of the database context in the Action_Executed event, which happens before your View is rendered. So you could be trying to access the database after it has been disposed. Even if you are not doing that now, someone in future might decide to implement that pattern because it is fashionable.
The concerns of the ViewModel are different to the db Model. For example, you typically decorate your ViewModel properties with validation attributes. These typically are different or only concern the UI not the db. If you bind to your database entities you will find all these UI concerns polluting you DB entities.
Related to 2 - the requirements of the ViewModel may demand computed or derived properties. For example, a Fullname constructed from First and Last names. These kind of things are best kept in the ViewModel.
You can unit-test your ViewModels in isolation from the database. ViewModels can end up containing quite a lot of logic which needs to be unit-tested. This is easier to test if it is not tied to your database (as with EF entities).
In general, creating and maintaining ViewModels (even without AutoMapper) is not an overhead and you will find it is a much better pattern of development overall. I would recommend it for everything but the simplest cases (lookup lists of static data, for example).
I believe using view models is the only way to go, so no pros for ORM entities:) View models not only provide data for view, but they also define how view should look (by defining templates) or how it should validate (by adding data annotations or implementing IDataErrorInfo).
Using view models:
Pros:
View models contain only properties required by view, nothing else.
View models may contain specific validation rules using data annotations or IDataErrorInfo.
View models can combine values from different database entities.
View models document themselves and are not tied to any framework.
View models protect you from forged POSTs, containing values, that were not provided in form, but were contained in ORM entities.
You can specify easily display templates for view models and reuse them in many places using DisplayFor or EditorFor helpers.
Using ORM entities:
Cons:
ORM entities already contain data annotations, that can mess up your validation. Example: Password field in user may be markes as Required, but it is not required when you change only basic user info.
ORM entities are strongly tied to Framework (Entity Framework) and may be not easy to implement rules in.
ORM entities can contain properties for more than one view, but it is hard to separate validation rules for different views.
Using ORM entities with lazy loading can lead you to executing SQL queries when views are rendered. It shouldn't happen.
Using ORM entities can lead to using huge SQL queries instead on small ones. When you want to display dropdown with first name and last name, you should only retrieve first name and last name from database, not whole entities.
Thanks for the answers so far - they have been a big help in understanding the pros/cons of both approaches. I have one thing to add that no one else has mentioned.
Over-posting attack
A worrying disadvantage with binding directly against DB entities is an "over-posting attack". This is where the attacker, using a tool no more advanced than FireBug, can insert form fields that are not intended to be editable by the user, but which do exist on the DB entity.
Consider an "Edit my profile" page. Your view might look like this:
#using(Html.BeginForm() {
<div>
#Html.LabelFor(x=> x.FirstName)
#Html.TextBoxFor(x=> x.FirstName)
</div>
<div>
#Html.LabelFor(x=> x.LastName)
#Html.TextBoxFor(x=> x.LastName)
</div>
<input type="Submit" value="Save" />
}
It would render the following HTML:
<form action="/profile/edit" method="post">
<div>
<label for="FirstName">FirstName</label>
<input type="text" name="FirstName" value="" />
</div>
<div>
<label for="LastName">LastName</label>
<input type="text" name="LastName" value="" />
</div>
<input type="Submit" value="Save" />
</form>
Using FireBug, an attacker merely needs to insert a chunk of HTML inside the form:
<input type="hidden" name="IsAdmin" value="true" />
...and suddenly users are able change data in very unexpected and harmful ways.
Here are some even scarier hidden form fields:
<input type="hidden" name="ShoppingCart.Items[0].Price" value="0.01" />
<input type="hidden" name="BankAccount.Balance" value="1000000" />
<input type="hidden" name="User.Administrator.Password" value="hackedPassword" />
Ouch!
Info taken from:
http://hendryluk.wordpress.com/tag/asp-net-mvc/
I once tried to develop an app which used NHibernate entities directly in ASP.NET views. I ran into many problems with Lazy loading and deferred SQL execution running directly from the views rather than in the business logic layer or even controllers. Moving to a viewmodels and using automapper seemed to solve all these problems and make the app easier to test, debug and maintain.
I also found that view models were helpful in holding all the associated data I needed on a page. Some developers like to use the dynamic ViewBag for this, but this is bad for testing and debugging.
In particular, view models made it easy when you wanted to pick associated entities from dropdown lists.
AutoMapper was a lifesaver on this project, as it saved having to write a ton of mapping code, all I had to do was create the view models and then the controllers automapped from entities to view models.
Do not expose backend-entities to the client.
Real world application have behaviour -not CRUD. It you databind your entities to the view it will just be a matter of time before you dig into muddy hack when behaviour is required on the clientside.
I was just about to add exactly the same sentiment as hackedbychinese. also i'd add, with fk's to lookup lists, you just HAVE to use viewmodels as the entity model merely will hold a pointer to a single id within that table. A viewmodel allows you to pass the required populated list into the view - voila.
Also, a viewmodel can contain discreet logic where required, this would definately NOT be the case with the entity model. Also, your validations may vary depending on the use of your view, therefore different validations can be applied per 'view' requirement.
The purpose of a ViewModel is mainly separation of concerns - decoupling the View from the implementation details of the Model.
Using DB entities in your views, especially your forms is a massive security issue. Take the following POCO object
public class User
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public bool IsAdmin { get; set; }
}
Now say you are presenting a view that allows a user to change their email. The MVC method for processing the form result when using Db Entities instead of view models would look like: (unless you don't use model binding, in which case you are making more work for yourself)
public class HomeController : Controller
{
[HttpPost]
public ActionResult ChangeEmail(User user)
{
//....
}
}
Model binding in Asp.net works by looking for GET or POST parameters matching the names of the properties in the model. Therefore, all the user has to do is add IsAdmin=true to the POSt parameters and viola, the model passed into the ChangeEmail function will have the IsAdmin property set to true, which could very easily be accidentally added into the database, giving users free access to change data they didn't have access to change.
This goes for user permissions, changing who owns an entity (make your question be associated with me instead of you), change original creation dates, etc...

Efficient JSF Pagination

Whats the most efficient way of doing pagination in JSF 2.0 app?
I use Primefaces datatable and it is intelligent enough to perform
pagination by itself with no coding at all.
<p:dataTable var="car" value="#{carBean.cars}" paginator="true" rows="10">
<!-- Multiple columns here-->
</p:dataTable>
The thing that I see, is that I need to place my bean to session scoped or greater.
#ManagedBean
#SessionScoped
public class CarBean{
public List<Car> getCars(){
//return data from DB
}
}
I wanted to know is there another efficient way on how to perform this?
I used EJB/JPA at the backend by the way. Would like to know any links or tutorials
to learn more about this.
Thanks.
You need to use LazyDataModel in order to have only the rows in memory which the client actually needs to see. See also the example in PrimeFaces showcase. This does pagination at DB level which is what you ultimately want.
RichFaces supports by the way the same in flavor of ArrangableDataModel, here's the RichFaces showcase example.
In a production app, we've used a lazy datamodel to deal with 700000 records in db. I'd suggest using M3 which has fixes on lazy datatable cases.
I have found that the built in pagination feature of the Primefaces data table is one of the best features and did a good amount of load testing on it, bringing in recordsets with over 30,000 Hibernate entities and found the performance to be lackluster. This of course means that you will have 30,000 entities in session so I have the following in my web.xml to help by storing session on the server side.
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
This will reduce the size of the ViewState allowing request/response size to be greatly reduced however server side memory can suffer enormously by doing this.
Another potential option in some JSF implementations to help mitigate the size of ViewStat or session memory usage is compression. The following link describes a number of SUN RI and MyFaces JSF configuration parameters that can be set, some of which give the option of compression of the session state. http://publib.boulder.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.express.doc%2Finfo%2Fexp%2Fae%2Frweb_jsfengine.html
As far as learning more about how the Primefaces DataTable pagination feature works, why not go straight to the source? Primefaces is after all an open source project, so just look at the code and see what you can learn: http://code.google.com/p/primefaces/source/browse/#svn%2Fprimefaces
Important note depending on which version of Primefaces you are using. Starting with 3.0.M2 (I think) if you want to use the row select feature you must implement a SelectableDataModel. This breaks a lot of legacy code and there were a number of bitches about that.
Easiest thing to do is to create an inner class like this:
private MyDataModel dataModel = null;
public MyDataModel getDataModel() {
if (dataModel != null) return dataModel;
dataModel = new MyDataModel(some list);
return dataModel;
}
public static class MyDataModel extends ListDataModel<SomeRecord>
implements SelectableDataModel<SomeRecord> {
MyDataModel(List<SomeRecord> source) {
super(source);
}
etc.
Then the value attribute to p:dataTable becomes #{bean.dataModel}.
Good luck.

strong-typed profile values in ASP.NET membership (MVC)

I've been using ASP.NET MVC with membership-based login for several years and everything is working fine (it's now MVC3, but membership didn't change since the first version which was MVC1). Now I need to add a value into the profile (just one value, of very seldom use - so it doesn't warrant custom membership provider or custom tables)
I got it working through profile.SetPropertyValue("myprop"), but I would really want to get profile.myprop to work. Is it possible?
I saw some advise to have a custom class MyProfile : ProfileBase and have myprop as a property of that class. For some reason, casting ProfileBase.Create(currentUser.UserName) to MyProfile gives me an error (illegal cast).
Is there an example somewhere of ASP MVC application with Profile, similar to this Old Post by ScottGu?
Joel Spolsky had a great answer to this question on this post. You're basically on the right track.
If you're getting the illegal cast error, its most likely due to a problem in the config file. Make sure this is included; more specifically the <profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile"> section.
<profile defaultProvider="SqlProvider" inherits="YourNamespace.AccountProfile">
<providers>
<clear />
<add name="SqlProvider"
type="System.Web.Profile.SqlProfileProvider"
connectionStringName="sqlServerMembership" />
</providers>
</profile>

Resources