I have a simple question that I couldn't find any answer on the internet (probably because it's obvious).
When you're working on a MVC project, with a OOP language, the correct part to implement getters/setters components is the Model, the Controller, or both of them?
A Controller has a Model and is used as an interface for Associations, right? That's what's bothering me!
Thanks
With my experiance of C# ASP.NET MVC,
The Controller is the area where all you data is retrieve from the query strings and where you handle data from the user
The Model is where all you classed and logic is handled, so a list or variable would reference the model which is where you can add things like functions and data annotations.
The View is where you controller is referencing to. So if you set Public ActionResult Index() { Return View(); }
within the controller then it will try to return the view corresponding with the name and in this case Index.
Related
I am trying to understand the MVC Pattern, and I finally understand a lot of it. There is one concept that I don't quite understand yet. I have looked through all the posts on here that try to explain MVC, but this one question isn't answered clearly yet.
Do you create variables in the model or the controller or both?
I can see someone passing variables from the controller to the model to change the data held within the variables, but would it be better to create them in the model then just call their values from the controller? Or would it be better to create variables in the model, and copy their values to the same variables in the controller?
If you know, please explain why one is better than the other, please. I am asking to understand, not just to know the right answer. Thank you.
If I give a straight forward answer for
Do you create variables in the model or the controller or both?
It doesn't really matter.
The main idea behind Model and Controller is
Controller resides only Presentation Logic.
Model resides only Business Logic.
So that, if you want to present your model with a different presentation logic, you can get your existing Model out and plug it with a new Controller without any problem because your business logic & presentation logic is decoupled(not mixed with each other).
This is the best diagram I found for MVC architecture. Hope you can upgrade your understanding with this.
So in terms of variables, in Model you should make variables only for business logic purpose. In Controller, it's only for presentation purpose. :))
Persistent data needed throughout the lifetime of the application should be held within the Model. Model method calls to set, get and manipulate the data within the Model should be done by the Controller.
Temporary data needed by the application or the view (for any reason) can be held in the controller... but no persistent data should ever be held within the controller, as it's considered to be a bad MVC design pattern implementation to do so.
I need to do a master-details view when I click on a row. I have the code in a branch here's the commit link.
let urlDetail = this.router.generate('energy-details', {model: this.model});
this.router.navigate(urlDetail);
This works, but the query string is awful. How do I send the model across in memory?
This was really hard to find an example for. https://github.com/softchris/aurelia was the best one.
Is there a better way to do master-detail views? I'm new to Aurelia.
http://localhost:5000/#/energy-details?model%5BdataSeriesId%5D=ES&model%5BcountryId%5D=392&model%5BcountryName%5D=Japan&model%5BtransactionCode%5D=01&model%5BcommodityTransactionId%5D=ES01&model%5BcommodityTransactionName%5D=Electricity%20-%20solar%20production%2C%20public&model%5Byear%5D=2000&model%5Bunit%5D=Kilowatt-hours%2C%20million&model%5Bquantity%5D=2&model%5BfootnoteSequenceId%5D=0.
Reconsider if you just don't want to use id. Quite often in a mater-details you need to make a new query to get more data anyway.
If not possible for your use case, maybe it makes sense to have a DataManager singleton.
Create a DataManager class that you inject in your List and Detail ViewModel. By default every injected class is a singleton in aurelia
In the list ViewModel, make sure your data is saved in the DataManager
Routing by passing the id only
In the details ViewModel call your method getModelById(id) of the DataManger
I'm learning ASP.NET MVC from the book Pro ASP.NET MVC 4 (which I love so far, by the way).
I'm still in the beginning chapters and it's showing me the System.ComponentModel.DataAnnotations namespace attributes, how to sprinkle my model class with these annotations, and then how to use them to check if the model is valid (ModelState.IsValid in the Controller).
For example:
public class GuestResponse
{
[Required(ErrorMessage = "Please enter your name"]
public string Name { get; set; }
}
...
public ViewResult RsvpForm(GuestResponse guestResponse)
{
if(ModelState.IsValid)
{
return View("Thanks", guestResponse);
}
}
There are a couple things about this that make me uneasy.
Why do I want a bunch of attributes littered throughout my domain model? I like my domain model pure and free from any stuff that is implementation specific, and any real world model would be too complex to just use declarative validation like this.
Aren't the ErrorMessage parameters of the validation attributes somewhat View related? Doesn't something like that belong in the UI layer? For example...what if due to space constraints I want the mobile version to instead of saying "Please enter your name" say "Name required"? But here it is in my model!
Why do I want to use ModelState.IsValid to determine the status of the model? Shouldn't the model tell me? I understand that ModelState is making use of the DataAnnotations attributes that are in my model, but this seems like it would only work for very simple models. A more complex model might not even have a valid/invalid state, it might just have various stages and states. I'm sort of rambling here, but I don't like the idea of declaratively saying what makes my model valid or invalid.
Any advice, reassurance, or validation of these thoughts would be appreciated.
Here are my answers to your questions:
1) Why do I want a bunch of attributes littered throughout my domain model? I like my domain model pure and free from any stuff that is
implementation specific, and any real world model would be too complex
to just use declarative validation like this.
You absolutely don't want this. What you want is to have a view model which is specifically designed for the purposes of your view. It is this view model that will contain the data annotations, not your domain model. Then the controller will map between the domain model and the view model and will pass the view model to the view. Think of the view model as the projection of one or more domain models. In order to simplify the mapping between your domain and view models you may checkout AutoMapper. The basic rule of thumb is that a view should not be aware of your domain models.
2) Aren't the ErrorMessage parameters of the validation attributes somewhat View related? Doesn't something like that belong in the UI
layer? For example...what if due to space constraints I want the
mobile version to instead of saying "Please enter your name" say "Name
required"? But here it is in my model!
Completely agree with you. That's the reason why you should have a view model class which is specifically designed for the purposes of the view.
3) Why do I want to use ModelState.IsValid to determine the status of the
model? Shouldn't the model tell me? I understand that ModelState is
making use of the DataAnnotations attributes that are in my model, but
this seems like it would only work for very simple models. A more
complex model might not even have a valid/invalid state, it might just
have various stages and states. I'm sort of rambling here, but I don't
like the idea of declaratively saying what makes my model valid or
invalid.
Once again I agree with you. Declarative validation (such as what you get out of the box with Data Annotations) works great for Hello World type of applications but once you start writing real world applications with complex validation rules you quickly realize that the declarative approach simply doesn't cut the mustard. It is for this reason that I use FluentValidation.NET. It provides you with a very nice and fluent syntax to express arbitrarily complex validation rules, it integrates easily with ASP.NET MVC and allows to unit test your validation rules in complete isolation.
Data annotations is just one way of doing it. You can also use the Fluent API for defining the schema of your database and mapping ER. The annotations are tightly coupled with the front-end jQuery validation codes thus comes in handy and easier.
And yes indeed if you don't want annotations in your business logic you can use view models in your UI layer. That would entirely depend on the scope and size of the application as to the extent of view models that you would end up using.
Here's some blog you can refer to clear up your doubts on EF
http://msdn.microsoft.com/en-us/data/jj591620.aspx
Hope this gets you going.
The answer to this is very dependent on the problem you are attempting to solve. For instance does your domain contain complex business logic or is the application CRUD-based. You should attempt to pick the best for the problem you are trying to solve.
I guess there are 2 extremes when thinking about these "domain models" they can simply be data transfer objects between the database and UI, or, they can be complex DDD type object that model the business problem. If they are the former then why not keep them as simple as possible. On the otherhand complex business domains would be hard to implement well using a 'single' model which is shared between view and db. In reality you are probably somewhere in the middle.
2 & 3. Yes they are, but does that matter for your "note" application, how about for your shipping app?
In the Model View Controller pattern where should data transformation occur?
I have a Model that stores very specific mathematical data. I need to convert that data for a physics simulator(that only accepts data in a certain format) and I'm wondering where the code for that should sit? In general where do you place code that transforms one Model into another type of Model?
Personally, I like to put this code in the constructor of the derived type of model. In this way, the code that does the conversion is in the class that needs to use it. I find this way of organizing the code makes it easier to understand, test and maintain.
Using your example, say you have a class as follows (you did not mention what language you were using, so I'll give the code below in C#, but it is very similar in java):
public class MathematicalData
{
//members of class
}
Let's say you need to take the members of an instance of MathematicalData and transform them into another class named PhysicsSimulator. I would require the constructor to PhysicsSimulator to take an instance of MathematicalData as an input parameter, and then populate the members of PhysicsSimulator in this contructor:
public class PhysicsSimulator
{
//constructor
public PhysicsSimulator(MathematicalData input)
{
//put code here to use the members of input to populate members of this instance of PhysicsSimulator
}
}
If the only way you want to create an instace of PhysicsSimulator is by using an instance of MathematicalData, then I would not create a default constructor for PhysicsSimulator. In this way, the only way to create a PhysicsSimulator would be to pass in a MathematicalData instance.
It looks to me that you need to design an Adapter interface to achieve this. Making the constructor of the target(PhysicsSimulator) accept the source(MathData) object would tie them both such that when the source changes for whatever reason the target has to change.
An adapter will limit the changes to the adapter and will not force the target to change for every change in the source.
Hope this helps.
Here is a typical pattern I follow for an MVC web app. Input from the web lands in the Model, and then the Controller takes responsibility for transforming the web Model to the Business Tier model before calling the Business Tier action.
To keep the Controller from being bloated with transformation code, I'll offload transformations to AutoMapper whenever it's a fit.
I'm fairly new to MVC4, EF5 and ASP.Net, and I don't seem to be able to find a good answer anywhere.
Basically, Should everything be done through the viewmodel or is it Ok to also incorporate viewbag?
Say I have a method which populates a drop down list, and I am using a viewmodel to represent the output for the view.
Am I ok to use Viewbag.DropDown = PopulateDropdown(); or would it be better to incorporate
this into the ViewModel, by creating a property to hold the List<SelectListItem> created by PopulateDropdown(); ?
I know how handy ViewBag is, but I'm yet to see any solid reason as to not use it? If anyone could also offer me some more insight, that would be fantastic.
Basically, Should everything be done through the viewmodel or is it Ok
to also incorporate viewbag?
Everything should be done inside a view model. That's what a view model is. A class that you specifically define to meet the requirements of your view. Don't mix ViewBags with ViewModels. It is no longer clear for the view where is the information coming from. Either use only a view model (approach that I recommend) or only use ViewBags. But don't mix the 2.
So in your particular example you would have a property on your view model which is of type IENumerable<SelectListItem> and inside your view you will use the strongly typed version of the Html.DropDownListFor helper to bind to the model:
#Html.DropDownListFor(x => x.ProductId, Model.Products)
Obviously those are only my 2 cents. Other people will say that mixing ViewModels and ViewBags is fine and I respect their opinion.
Prefer ViewModels over the ViewBag wherever you can. Create Strongly typed views. It makes your code cleaner, less fragile, less error-prone, and easy to maintain.
ViewBags are just dictionaries of dynamically typed objects so you lose:
Compile time checking
The ability to refactor with confidence (you lose the support of the tools)
IDE support - such as the ability to navigate to all usages
Intellisense
For bonus points making extensive use of the ViewBag also misses the point of using the MVC pattern
I get the impression ViewBags were created to solve an edge-case problem in asp.net and people use them instead of creating view models as was originally intended in the design of the platform, to the detriment of their work.
with thanks to Why not to use ViewBag heavily?