Understanding relations between model view and controller - model-view-controller

I went through a lot of readings about MVC and what each of these does is more or less clear. What I haven't understood yet is how they relate. I mean, I know about these relationships
but how are they implemented? What happens in an MVC framework?
I also have a few questions:
I read that a view can't be coupled with the controller, in other words it can't have a controller object inside, but then how does it use the proper controller if a view is supposed to trigger something in it?
How can the model update the view if its unique job is to represent data?
Is the business logic inside the controller or the model? I have read conflicting points of view

The most basic explination of MVC would be that you have each of the 3 layers.
Model
This contains your data. i.e database or set of classes.
View
This displays data to the user i.e your HTML page.
Contains controls for user interaction.
Controller
All access to data should go through this layer. i.e load data from your data source(model) and save data to your data source.
Carries out any data manipulation before saving or loading.
This create a separation of concerns theoretically allowing you to change anything in either layer without the other layer knowing or caring making for far more maintainable and readable code.
In practice this can become more complicated depending on how you wish to access data and display it although the basic principles still apply, occasionally meaning that each part of MVC pattern could be made up of smaller parts.
In terms of implementing it a good example would be ASP.Net MVC http://www.asp.net/mvc. the following could be a simple implementation of displaying some data via MVC using C#.
Model (C# class)
public class Person{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Controller
public ActionResult Index(){
return View(new Person() { FirstName = "Person", LastName = "1" });
}
View (Index.cshtml)
#model Person
Full name: #Html.Raw(Model.FirstName + " " + Model.LastName)
This would output onto the web page
Full name : Person 1
Please forgive me for any syntax errors, not tested.
More detailed post: http://www.tutorialspoint.com/design_pattern/mvc_pattern.htm

Related

Web API is it necessary to have ViewModels layer classes?

When I use Web (MVC), I always to create a separate classes layer. These classes often the same as DTO classes, but with attributes like [Display(Name = "Street")] and validation. But for web api Display attributes are not necessary, validation can be used by FluentValidation. Should Api controller returns ViewModels classes or DTO classes will be fine too?
the answer, as always is .... it depends.
If your API is serving multiple clients , apps etc, then returning DTOs is a better options.
ViewModels are specific to the MVC client and should already be prepared for display, meaning the data should already be formatted in a specific way, some fields maybe combined, they should satisfy whatever requirements the display pages have. They are called ViewNodels for a reason. The point is that they are rarely exactly the same as the data the API returns, which should be a bit more generic and follow a certain pattern to make sense to its users.
If your ViewModels are exactly the same and you only have one client then it's up to you if you want to create a set of duplicated classed just to avoid having the attributes.
Mapping from DTO to ViewModel and viceversa is not exactly complicated, but the process does introduce one more complication, one more layer.
Don't forget one thing though. API DTOs are supposed to return the data they have on any entity regardless of the requirements of any UI. Requirements can change anyway, new fields added or discarded. You're more than likely to leave the API alone when that happens and simply change your ViewModels.
Your ViewModels are specific to a UI page and should contain only the data required by that page. This means that you can end up with multiple ViewModels for the same data, it's just that the display requirements are different for each.
My vote goes towards keeping the ViewModels and DTOs separate, even if, at this point in time they are exactly the same. Thins always change and this is one of those things you can actually be ready for.
Actually it depends on application's architecture how we want to return response. In this case yes we can return DTO classes but i think that would not be the good approach because we should create a separate Resource classes that will map with DTO and then return. Just see the below example:
public class CustomerDTO
{
public int ID { get; set; }
public string Name { get; set; }
public int DepartmentId { get; set; }
}
public class CustomerResource
{
[JsonObject]
public string Name { get; set; }
[JsonObject]
public string Department { get; set; }
}
Suppose we have CustomerDTO class and we want to return response in the following json format
{
"name":"Abc xyz",
"department":"Testing"
}
So in this case we should we have separate class that will return as a response to the end user as i created CustomerResource. In this scenario we will create a mapper that will map DTO with resource object.
And also with this implementation we can test resources independently

How do I bypass the limitations of what MVC-CORE controllers can pass to the view?

From what I've read, I'm supposed to be using ViewModels to populate my views in MVC, rather than the model directly. This should allow me to pass not just the contents of the model, but also other information such as login state, etc. to the view instead of using ViewBag or ViewData. I've followed the tutorials and I've had both a model and a viewmodel successfully sent to the view. The original problem I had was that I needed a paginated view, which is simple to do when passing a model alone, but becomes difficult when passing a viewmodel.
With a model of
public class Instructor {
public string forename { get; set; }
public string surname { get; set; }
}
and a viewmodel of
public class InstructorVM {
public Instructor Instructors { get; set; }
public string LoggedIn { get; set; }
}
I can create a paginated list of the instructors using the pure model Instructor but I can't pass InstructorVM to the view and paginate it as there are other properties that aren't required in the pagination LoggedIn cause issues. If I pass InstructorVM.Instructors to the view, I get the pagination, but don't get the LoggedIn and as this is just the model, I may has well have passed that through directly.
An alternative that was suggested was to convert/expand the viewmodel into a list or somesuch which would produce an object like this that gets passed to the view
instructor.forename = "dave", instructor.surname = "smith", LoggedIn="Hello brian"
instructor.forename = "alan", instructor.surname = "jones", LoggedIn="Hello brian"
instructor.forename = "paul", instructor.surname = "barns", LoggedIn="Hello brian"
where the LoggedIn value is repeated in every row and then retrieved in the row using Model[0].LoggedIn
Obviously, this problem is caused because you can only pass one object back from a method, either Instructor, InstructorVM, List<InstructorVM>, etc.
I'm trying to find out the best option to give me pagination (on part of the returned object) from a viewmodel while not replicating everything else in the viewmodel.
One suggestion was to use a JavaScript framework like React/Angular to break up the page into a more MVVM way of doing things, the problem with that being that despite looking for suggestions and reading 1001 "Best JS framework" lists via Google, they all assume I have already learned all of the frameworks and can thus pick the most suitable one from the options available.
When all I want to do is show a string and a paginated list from a viewmodel on a view. At this point I don't care how, I don't care if I have to learn a JS framework or if I can do it just using MVC core, but can someone tell me how to do this thing I could do quite simply in ASP.NET? If it's "use a JS framework" which one?
Thanks
I'm not exactly sure what the difficulty is here, as pagination and using a view model aren't factors that play on one another. Pagination is all about selecting a subset of items from a data store, which happens entirely in your initial query. For example, whereas you might originally have done something like:
var widgets = db.Widgets.ToList();
Instead you would do something like:
var widgets = db.Widgets.Skip((pageNumber - 1) * itemsPerPage).Take(itemsPerPage).ToList();
Using a view model is just a layer on top of this, where you then just map the queried data, no matter what it is onto instances of your view model:
var widgetViewModels = widgets.Select(w => new WidgetViewModel
{
...
});
If you're using a library like PagedList or similar, this behavior may not be immediately obvious, since the default implementation depends on having access to the queryset (in order to do the skip/take logic for you). However, PagedList, for example has StaticPagedList which allows you to create an IPagedList instance with an existing dataset:
var pagedWidgets = new StaticPagedList<WidgetViewModel>(widgetViewModels, pageNumber, itemsPerPage, totalItems);
There, the only part you'd be missing is totalItems, which is going to require an additional count query on the unfiltered queryset.
If you're using a different library, there should be some sort of similar functionality available. You'll just need to confer with the documentation.

Model view controller: shall the view know custom data types?

Very simple question: in a strict MVC design pattern we want to keep Model, View and Controller can the View layer know which custom data classes are defined in the model?
As example:
I got a CarViewController in the view layer and a Car object in the model layer. Whenever the model layer changes the controller object that "sits" between the model and the view notifies the CarViewController and in my current implementation passes a copy of the updated car data as an instance of the Car class. Is this correct?
My gut instinct would have said no because I would not want the view layer to know the details of the model objects. It is not strict decoupling. However if I pass specific values instead of passing the custom data model I would need to stick to standard/primitive values (E.g. int as number of wheels) and it may require more coding.
Have I understood MVC correctly? Is there any reason why the view should not know the custom classes of the model layer?
If I am understanding your question correctly, I would say that your view needs to know the details of your Car object in most of the cases. You can utilize metadata in this way like this:
Model:
public class Car
{
[Display(Name = "Number of wheels")]
public int Wheels { get; set; }
}
View:
#model Namespace.Models.Car
#* This will display whatever your [Display(Name="Value")] decorator defines
as a display name, also the editor will respect the data type decorator. *#
#Html.LabelFor(m => m.Wheels)
#Html.EditorFor(m => m.Wheels)
In this case if you basically pass down a primitive then all metadata for your model is lost.

In the MVC programming pattern, which category does the following code fall under?

If I have some code which is will HTTP request a remote website and extract data from it, or login to this website and extract data from it; what would I put this under? The model or the controller? I'm think that it is a model, because the controller should talk to the user and call upon my models to do stuff.
Is this correct?
Model is correct. The data crunching portion should be left to the models. The controllers direct the traffic between the models and views. Finally, views are used to display the data.
You would probably do this a view or controller. If you will need to do any large manipulation with the data, you could create and action that makes a request and then manipulates the data and then pass that data onto a view. If you will need simpler operations, and depending on your framework, you can make the request in the view itself.
You would possibly use all of the View, Model and controller. But if you don't want to display the result, it would likely be just the controller and model.
For example, the controller code would have an ActionResult method which would call your remote website.
e.g. your model
public class RemoteWSData
{
public string Code { get; set; }
public string Name { get; set; }
}
your controller:
public ActionResult GetRemoteWebsiteData()
{
RemoteWSData model = repository.GetRemoteWebsiteData();
string code = model.Code;
string name = model.Name;
}
with the repository above being a data access class. This data access class would contain references to the connections required to access the data or server and get these values from a web.config file.

Model binding in controller when form is posted - why to use view model instead of class from domain model?

I'm still reasonably new to ASP.NET MVC 3. I have come across view models and their use for passing data from a controller to the view. In my recent question on model binding two experts suggested that I should use view models for model binding as well.
This is something I haven't come across before. But both guys have assured me that it is best practise. Could someone maybe shed some light on the reasons why view models are more suitable for model binding?
Here is an example situation: I have a simple class in my domain model.
public class TestParent
{
public int TestParentID { get; set; }
public string Name { get; set; }
public string Comment { get; set; }
}
And this is my controller:
public class TestController : Controller
{
private EFDbTestParentRepository testParentRepository = new EFDbTestParentRepository();
private EFDbTestChildRepository testChildRepository = new EFDbTestChildRepository();
public ActionResult ListParents()
{
return View(testParentRepository.TestParents);
}
public ViewResult EditParent(int testParentID)
{
return View(testParentRepository.TestParents.First(tp => tp.TestParentID == testParentID));
}
[HttpPost]
public ActionResult EditParent(TestParent testParent)
{
if (ModelState.IsValid)
{
testParentRepository.SaveTestParent(testParent);
TempData["message"] = string.Format("Changes to test parents have been saved: {0} (ID = {1})",
testParent.Name,
testParent.TestParentID);
return RedirectToAction("ListParents");
}
// something wrong with the data values
return View(testParent);
}
}
So in the third action method which gets invoked when an HTTP POST arrives I used TestParent for model binding. This felt quite convenient because the browser page that generates the HTTP POST request contains input fields for all properties of TestParent. And I actually thought that's the way the templates that Visual Studio provides for CRUD operations work as well.
However the recommendation that I got was that the signature of the third action method should read public ActionResult EditParent(TestParentViewModel viewModel).
It sounds appealing at first, but as your models and view actions get increasingly complex, you start to see the value of using ViewModels for (most) everything, especially input scenarios.
Case 1 - Most web frameworks are susceptible to over-posting. If you are binding straight to your domain model, it is very possible to over-post data and maliciously change something not belonging to the user. I find it cleaner to bind to an input view model than have long string lists of white lists or black lists, although there are some other interesting ways with binding to an interface.
Case 2 - As your input grows in complexity, you'll run into times when you need to submit and validate fields not directly in the domain model ('I Agree' checkboxes, etc)
Case 3 - More of a personal thing, but I find model binding to relational domain objects to be a giant pain at times. Easier to link them up in AutoMapper than deal with MVC's modelbinder for complicated object graphs. MVC's html helpers also work more smoothly against primitive types than deep relational models.
The negatives of using ViewModels is that it isn't very DRY.
So the moral of the story is, binding to domain models can be a viable solution for simple things, but as the complexity increases, it becomes easier to have a separate view model and then map between the two.

Resources