Using different models for one view for GET and POST - asp.net-mvc-4

I've seen multiple answers on this so I'm really confused.
Using one single view, can you use one model for the GET action and a different model for the POST? As an example, here's what I've got--here's an example of a ViewModel I have:
public class ModelAViewModel {
public ModelB modB { get; set; }
public ModelC modC { get; set; }
}
I currently use ModelAViewModel to do a GET to display data from ModelB and ModelC. I was wondering if I could also do a POST of just ModelB and then make a new object of ModelC in the POST function.
Might be bad coding standards, but a new requirement of a feature came in to display ModelC's data, and I was wondering if this was possible without refactoring.

In general, always just go for it. If it doesn't work, then you can ask for advice, but just try it and see what happens.
Since you're here already, though, I can tell you that this is fine. If you don't post anything for modC, it will just be null on POST. Also, the model validator doesn't validate null instance properties, so you can still have required properties and such on ModelC and as long as you don't post anything at all related to it, you won't get errors.

Related

ValidateInput(false) vs AllowHtml

I have a form that is used to create a memo, to do that I am using a rich text editor to provide some styling, this creates html tags in order to apply style. When I post that text, the mvc throws an error to prevent potentially dangerous scripts, so I have to specifically allow it.
I have found 2 ways of doing this, one is to decorate the controller method with [ValidateInput(false)] and the other is to decorate the ViewModel attribute with [AllowHtml]. To me, [AllowHtml] looks much nicer, but I have only found that approach used 1 time and the [ValidateInput(false)] seems to be the preferred way.
Which method should I use and what are the differences between the two?
ValidateInput and AllowHTML are directly connected with XSS security issues.
So let us first try to understand XSS.
XSS (cross-site scripting) is a security attack where the attacker injects malicious code while doing data entry. Now the good news is that XSS is by default prevented in MVC. So if any one tries to post JavaScript or HTML code he lands with the below error.
But in real time there are scenarios where HTML has to be allowed, like HTML editors. So for those kind of scenarios you can decorate your action with the below attribute.
[ValidateInput(false)]
public ActionResult PostProduct(Product obj)
{
return View(obj);
}
But wait, there is a problem here. The problem is we have allowed HTML on the complete action which can be dangerous. So if we can have more granular control on the field or property level that would really create a neat, tidy and professional solution.
That’s where AllowHTML is useful. You can see in the below code I have decorated “AllowHTML” on the product class property level.
public class Product
{
public string ProductName { get; set; }
[AllowHtml]
public string ProductDescription { get; set; }
}
So summarizing “ValidateInput” allows scripts and HTML to be posted on action level while “AllowHTML” is on a more granular level.
I would recommend to use “AllowHTML” more until you are very sure that the whole action needs to be naked.
I would recommend you to read the blog post Preventing XSS Attacks in ASP.NET MVC using ValidateInput and AllowHTML which demonstrates step by step about the importance of these two attributes with an example.
if use Bind Include best way is AllowHtml otherwise
you can use ValidateInput(false) to disable all Validaton in controll

Proper design technique

I am creating an asp.net mvc4 application that will ask the user a set of questions based on a particular criteria that they enter. Each question is stored in a table and only those questions that meet the criteria will be displayed to the end user.
I am using a viewmodel that combines information from a couple of different tables. Basically it has a list of Questions and an inspection id to tie all the test together. My question is what is the proper oo design technique for populating the viewmodel.
Should the method / methods for populating the viewmodel reside within the viewmodel class itself? Basically passing the entities into the viewmodel and allow it to populate itself.
Should there be a new class that you send in the entities in and it returns the viewmodel?
Or is there a better way to do this.
yes, your approach is valid.
Consider the following example in your model:
public List<Questions> Questions
{
get {
QuestionRepository Rep = new QuestionRepository();
return Rep.ObtainQuestions(ClientAge,ClientType)
}
}
public int ClientAge { get; set; }
public ClientTypeEnum ClientType { get; set; }
the getter in the Questions property includes all the logic. as long as the clientAge and the ClientType properties have valid values, the question list will be populated. this avoids having to set the data in every action method where you need to populate the property.
in the example I am getting the data from a repository but you could get it from an ORM like entity framework, or any other source.
you can google the term skinny controllers and read up more on the recomendations and best practices.

DDD: Where to put logic in aggregation root

Still experimenting with DDD and have some doubts, maybe someone would help me.
Lets say that I have 2 models:
public class Event
{
User Creator;
List<User> Members;
}
public class User {}
My problem is that I cannot see place for logic that I want to implement. I need 3 actions:
User join event
User leave event
Creator remove user from event (only Creator can remove users)
For now I just created domain service EventUserService that calls Event.RemoveUser/AddUser and ie. checks if CurrentUser (provided by UserService) is creator of event (have rights to remove other users).
Maybe that approach is ok, but I still feel that I should putt that logic into aggregation roots, ie. :
User.JoinEvent(Event) - i can add passed Event to User.Events collection (bidirectionall) base on some logic.
User.LeaveEvent(Event) - analogous to JoinEvent.
User.RemoveUserFromEvent(User,Event) - I can have CreatedEvents collection in User and for Event from that collection I can call Event.RemoveUser(User) - this way I will make sure that only creator can kick someone.
Or
Evet.RemoveUser(UserToRemove) - but how I will make sure that its called by creator ?
If first two method looks ok (at least for me), 3rd one would create Event.RemoveUser (to manage Event members collection) method that could be used to bypass logic residing in User.RemoveUserFromEvent.
So, in the end I have 2 questions:
What is your approach in situation like this where two aggregation roots works together and one operation is determine by logic residing in both of them? Maybe some kind of methoods like User.CanJoinEvent(Event) ?
What about creating "danger" point like User.RemoveUserFromEvent
Maybe someone can putt a little bit light on that for me, every help would be nice.
public class Event
{
User Creator;
List<User> Members;
}
Don't do that. You are breaking Law Of Demeter and the Event class has no control over the changes in Members or the users in that list. You should instead define methods in the Event class which is used to handle the members.
Now, if you do that change, i.e. have something like this:
public class Event
{
User Creator { get private set; }
bool IsMember(string name);
void AddMember(User user);
}
You'll suddenly have solid places to generate the events.
but how I will make sure that its called by creator ?
In .NET you can use Thread.CurrentPrinicpal to get information about the logged in user. It do however require that you implement your own IPrincipal/IIdentity.
Remember: You should ALWAYS make sure that the models are in a valid state in DDD. That usually means that all setters should be private: http://blog.gauffin.org/2012/06/protect-your-data/

asp.net mvc without entity framework

I am learning asp.net mvc and went through a great tutorial that demonstrated it. The tutorial also used Entity Framework.
We have our own data access class which I have to use.
I am a little bit confused as to what I need to do to bridge the gap between our class and MVC framework.
For example, in the tutorial, inside of MovieController.cs file, there is a Edit method, that looks like this:
[HttpPost]
public ActionResult Edit(Movie movie)
{
if (ModelState.IsValid)
{
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
If I don't use the Entity framework, what would it look like? Will I still need to use ModelState.IsValid and save the state like it's done
db.Entry(movie).State = EntityState.Modified;
Please advise. A clearly written example of using asp.net mvc without the use of Entity framework would be great.
What I need to know is what role does state play here and whether it is mandatory to use or is it just a part of how the Entity framework operates.
I would re-write this as:
[HttpPost]
public ActionResult Edit(Movie movie)
{
myDBObject.SaveChanges();
return RedirectToAction("Index");
}
Where myDBObject is my custom database access object.
The examples you see out there where controllers use directly some data access framework such as Entity Framework are bad examples. The whole internet is polluted with such stuff. I can hardly look at it without having my eyes hurt. I consider those as bad practices. Data access should be separated and abstracted in a repository. So for example:
public interface IMoviesRepository
{
Movie Get(int id);
void Save(Movie movie);
}
then you could have some implementation of this interface using plain ADO.NET, EF, NHibernate, a remote web service call, some custom ORM or really whatever:
public class MyCustomFrameworkMoviesRepository: IMoviesRepository
{
...
}
and the controller will take this repository interface as constructor argument:
public class MoviesController: Controller
{
private readonly IMoviesRepository _repository;
public MoviesController(IMoviesRepository repository)
{
_repository = repository;
}
public ActionResult Index(int id)
{
var movie = _repository.Get(id);
return View(movie);
}
[HttpPost]
public ActionResult Index(Movie movie)
{
if (!ModelState.IsValid)
{
return View(movie);
}
_repository.Save(movie);
return RedirectToAction("Success");
}
}
and the last part is to configure your dependency injection framework to pass the correct implementation of the repository into the controller. Now as you can see the way the data is fetched is completely decoupled from the controller logic. It is the way it should be. Always try to avoid the strong coupling between the different layers of your application.
And to answer your question about the State property : this is something completely specific to EF, seeing something like this in a controller is a really pity.
And to bring this even further and improve it you would introduce view models. View models are classes which are specifically designed to meet the requirements of a given view. So for example Movie is a domain model. Domain models should never be directly passed to views. Controller actions should never take domain models as action arguments. You should define view models which will contain only what is required by the given view and then perform the mapping between the view models and the domain models. Frameworks such as AutoMapper make this very simple.
hmm.
MVC and entity framework really have nothing to do with each other; they just work well together.
the if (ModelState.IsValid) validates your view model. If you are not using view objects with validators, it's a little pointless; if you are, then it's quite valuable.
inside the if (ModelState.IsValid) brackets, you would take the post data from your web page (usually a view model) and apply it to the object that will persist it to the database. EF is often used because once it's set up, it's fairly easy to maintain, and a lot less code to write.
db.Entry(movie).State = EntityState.Modified;
db.SaveChanges();
are both EF-related. These would need to be replaced by your repository class methods and objects.
return RedirectToAction("Index");
is MVC. Upon successful persistence to your data store, return the control to the index page.
return View(movie);
is used to redirect back to the original view, because something failed validation.
You would still check ModelState.IsValid, but otherwise your code would look like what you have.
This assumes that your model has DataAnnotations attributes on it, though, which is what ModelState.IsValid is using to check. Those attributes can be used on any C# class' properties - not just Entity Framework.
You might end up creating specific view models for this purpose.
You need to make some connection between the Movie object (passed in on the http POST) and your database methods (myDBObject).
Maybe you want to say myDBObject.SaveChanges(movie) and assuming your db code knows how to handle the object Movie then you'll be fine.

Choose between one-to-one and component in NHibernate

I am trying to map classes User and Profile, just as the following:
public class User
{
public long ID { get; set; }
public string LoginName { get; set; }
public Profile Profile { get; set; }
}
public class Profile
{
//the ID is the same with User's ID
public long ID { get; protected set; }
public string NickName { get; set; }
public Gender Gender { get; set; }
}
So, they can be mapped as both one-to-one and componenet relationship. And I find some people appraise the component and think one-to-one is a bad practise, why? For performance reason? But they are designed as two separate tables in many scenarios(asp.net2.0 Membership, for example).
How should I choose? Which aspects should I consider? I know component means "value object" but not an enitity, but does this mean some further things?
ps: And what confused me more is the opinion that the many-to-one should be used even it's one-to-one relationship in real world!
The key should be in your use cases for this class. Don't take ASP.NET Membership as an example, because its design is terrible.
You need to answer these questions:
Does a Profile make sense as an entity of its own?
Do you have references to the Profile anywhere else in your domain?
Can you have a User without a Profile?
Does it have a behavior of its own?
Would you extend (inherit) Profile for some reason?
Do most use cases just deal with the user (and its LoginName, not just the ID) but not the profile?
If most questions are true, you have a good case for using one-to-one (I disagree with #Falcon; this is actually one of the legitimate uses for one-to-one)
Otherwise, a Component will work fine. It doesn't have an ID, so you can remove that property.
You should use neither.
One-To-One
You have the user and the profile in different database tables but both share a mutually exclusive PK:
See http://jagregory.com/writings/i-think-you-mean-a-many-to-one-sir/
Pretty bad design practice for relational databases, it's messy and does not necessarily enforce constraints for the relationship.
Component
You can use component to get a clean Object-Model from a messy relational database, profile and user data are both stored in the same database table but they should be separated in your object model (like you want it, judging from your code). Lazy loading probably isn't supported, which will cause high database traffic.
Reference
Imho, you should use a Reference. It's conceptual kinda like one-to-one but a user references a profile. The profiles can be stored in their own table, can be loaded lazily (performance) and are not dependent on a user.
Regarding your confusion:
Just read the link I supplied. Technically, you need a many to one for a properly designed database-scheme, as that is what is technically possible and will be mapped. I know it's confusing. If you just need to map one-side, think of a reference instead of a one-to-one.