How to do Model validation in MVC with Web API 2? - c#

I am new to Web API2. My solution has 3 projects (MVC, WebAPI2, Class library for EF). I have below doubts.
1) Have kept WebAPI and MVC as separate projects for separation of concerns. Is it advisable or it is better to keep both in single project?
2) With WCF we can take service reference in MVC to avail all DB class models so that it will be easy in MVC to scaffold the controllers and to add Model validations. How to do that with Web API2 as I will not have reference in MVC for DB classes. Do I need to create duplicate DB class models in the MVC project for scaffolding purpose and model validation purpose?

Your title confuses me a fair bit, but model validation can be done with validation attributes. I will try and answer the questions in the body of your question post.
It depends on how you expect to use your MVC and WebApi projects.
Keep in mind you may make things easier for yourself if they in the same project so you don't need to worry too much about RPC. But who knows how you intend to use them.
WebAPI is normally used for integration with systems other than your own. For this reason (de)serialization and request/response handling is highly customizable. The models used for the WebAPI controller are often specified or provided to the system the interface is intended to integrate with.
The model used for the WebAPI or MVC controller should be separate to the entity model for your ORM. The reason you would want to do this is that the data in your entity model does not always fit the use of the view or the validation of the view model that is sent back to the controller from the view.
In both cases the models that interface your WebAPI and MVC controllers should be designed to accommodate your use cases and should be fairly decoupled from your entity models for persistence.
So to answer your second question you probably only need one set of entity models and probably only one dbcontext implementation, but have all of that in its own project so that if you do have separate MVC and WebAPI projects they both depend on that EF project.

Related

Implementing Repository Pattern with Generated Code

Is there a way to implement the repository pattern in Asp.NET MVC while also generating the controllers and views from a model?
One of the great features of Asp.NET MVC is that it will generate a lot of code for you based on your model. Unfortunately, it seems you need a model AND a DBContext class to do so. I have my MVC project referencing a repository, and both references the same models. Is there a way to generate the code using the model only?

Where to put Business Logic classes in an Entity Framework - ASP.NET MVC 4 Solution?

I have a Solution with one project is Entity Framework and have my ASP MVC project, I looking for some advice or opinion about the idea of create in top of my POCO objects and the DBContext, a Business Logic Layer with static classes that have the all the methods (example a ContactBLL class with GetContactByID, GetAllContacts, GetContactsByType) to allow the access to the model data and that can be accessed in the Controllers Actions. In that way I don't have to put the implementation code of this methods in Controller Actions methods, and it can be reusable invoking this methods in other Action Controllers. I will appreciate your opinion because it could guide me to respond a question I've asking to myself around a week based in the answer to this one (about where to define the DBContext and how use it).
You can create different projects according to core functionality.
Data Access Layer(DB context and repository etc.) you can make Project.DataAccess, it will have only db context class and repository.
Business Logic Layer(Project.Business) it will have business logic and make call to data access layer.
UI Layer(Project.WebUi) it is mvc project.
and so on.
for detail info you can see this http://prodinner.codeplex.com/ code
Create separate class library for your POCO,
then create another class library for your repository, this should
include only the interfaces needed for your repository
and the implementation will be on another class lib like Project.EF,
Project.NH which will include Entity Mapping, Migration, Repository
implementations. but in reality, chances are you wont be changing
your ORM lib once it was implemented because it will just cause you
a lot of headache(just my 2cents).
you'll create your business layer(class lib) and
web project as separate lib. Models folder of your MVC project will contain your ViewModels.
this is what Im using right now and of course not the best structure, it just something that Im happy with :). hope it helps.
In general, there are four standard projects in a ASP.NET MVC - Entity Framework solution. They are 1) MVC, 2) Core/Business Logic Layer(BLL), 3) Data Access Layer/DBContext (DAL) and 4) Common/Utility.
Standard MVC project consists three main elements which are Model, View and Controller. However, middle to complex solution usually cuts off the Model element from MVC project and moves it back to BLL, we call it as ViewModel(POCO). Following this structure, MVC project is now responsible for employ/use the services from BLL and control the UI through controller.
Business Logic Layer (BLL) is the core of implementing business logic. It is responsible for serving request from the MVC project and work with DAL to persist data. As said above, BLL is the place to define ViewModel, its relations as well interface/ abstract class to support implementing design pattern. Viewmodel(POCO) is likely mapping one-one to data entity at DAL but we do not use the data entity directly on View. Following this structure will help to increase the customization on ViewModel like adding constrains
DAL is the place for DBContext and its data entities.
Common project consist of shared functions like Logging which is used in 1) 2) and 3)
Please read more at
https://www.codeproject.com/Articles/70061/Architecture-Guide-ASP-NET-MVC-Framework-N-tier-En
https://chsakell.com/2015/02/15/asp-net-mvc-solution-architecture-best-practices/

How can I refactor my database access code outside my MVC project but keep my viewmodels inside?

I have an asp.net-mvc website with the following folders:
Controllers
Scripts
Views
ViewModels
Models
DomainModel
I now want to access a lot of this business logic and database access code and data in another .net app (a windows console app so not web at all) so i am refactoring to remove as much stuff as possible outside of the MVC project and into other projects in the solution so that code could be shared with this other solutions.
I have 2 main issues;
My main issue is that I am struggling to find a place to put the code that generates the ViewModel because a lot of this code I would like to reuse in my console app as the console app sends email which requires the same data that is in the view.
Another main issue is that i am struggling to see how i can move my database access code out of the MVC project while still having the ViewModels inside when many of my functions that instantiate my viewmodels start with a bunch of database access code.
Here is a bit of the detail and my process so far:
Step 1 - Move DomainModel into another project - success
So moving the DomainModel project was simple (as that was a lot of raw objects with some business logic on top - nothing web about it).
Step 2 - Thin out controllers - success
I have thinned out as much of my controllers as possible and moved any business logic or complicated data access logic into the Models folder. When i tried to move the models folder outside the MVC project a few things broke:
Step 3 - Attempt to move Models folder outside MVC Project - struggle
In thinning out the controllers, I have a number of different controller actions that go to a model class and return my ViewModel that i pass back into the view. Something like this (in my controller class):
public ActionResult ApplicationDetail(int id)
{
AppDetailViewModel applicationViewModel = Model.GenerateAppDetailViewModel(id);
return View(applicationViewModel);
}
So files in my Model folder are dependency on the ViewModel classes. I do want to centralize the GenerateAppDetailViewModel() function as that is used in multiple different controllers. Also, in my console app (which sends out email, i often want to get all the data that happens to be on some view so my code "wants" to leverage the viewmodel as well .. if i move it out of the MVC project then I can reuse but i think have the dependency issue (clearly i don't need SelectListItem in my console app but in other cases where they are just container objects of different data needed to generate a view I do want to reuse)
or another thing that broke was the dependency on:
System.Web.Mvc
because I have a lot of code that:
queries a table in a database
Converts that into a collection of objects (i am using nhibernate)
Convert that into either some DTO object (which is sitting in ViewModels folder) or a List of SelectListItem objects (to be used to populate dropdowns in the view) which is part of System.web.mvc.
I wanted to look for suggestions on the best way to break out this dependency so i can move as much code out of the MVC project as possible for reuse.
The issue is that if i try to suck my ViewModel code into the Model folder and into another project then again i get stuck because the ViewModel classes have a lot of dependency on
System.Web.Mvc
due to things like SelectListItem.
Should i have 2 view models folders (one in the MVC project that has specific system.web.mvc references and another one that sits in a different project?). It seems like the dependency on SelectListItem is what keeps causing the contention
In most examples that i have seen ViewModels do have a dependency on System.Web.Mvc such as this tutorial
I have seen these questions:
Asp.Net MVC SelectList Refactoring Question?
Where should selectlist logic sit in ASP.NET MVC, view, model or controller?
which are sort of related but not sure they answer my specific overall refactoring question stated.
View models are specific to the particular application. I guess that the view models would differ between your web application and your console application. So have each application define its own view models and the corresponding mapping between the domain models and the view models. Don't have your domain models posses methods that convert them to view models because this way you are completely tying your domain layer to the UI layer which is the worst thing to happen. Use a mapping layer (which will be specific to each application type). AutoMapper is a great example of a mapping layer that you could have.
Don't even try to reuse ASP.NET MVC view models in a console application. As you have already found out they will contain references to System.Web.Mvc because for example a dropDownList in ASP.NET MVC is represented with the IEnumerable<SelectListItem> class whereas in a Console Application, god knows, maybe an IEnumerable<SomeItemViewModel>.
Conclusion: View models and mapping back and forth between the domain and view models belong to the UI layer (a.k.a ASP.NET MVC, Console, WPF, ...).
I understand what you want to achieve, and I must tell you: it's absolutely normal to reuse the same ViewModels for different UI layers. After all, VM is part of MVVM pattern, and that pattern is all about separating concerns. And, separation means the ability to replace lower-level layers with another implementations. That is the purpose of separate software layers (among others).
For the beginning, you must assume that your MVC web project is MVVM-based. That will mentally help you make correct decisions. I guess you already did this since you use ViewModel term.
Make ViewModels become platform independent. It's possible, and it has nothing to do with SelectListItem. After all, SelectListItem simply contains the option text/value pair, plus the flag whether it's selected or not. You obviously can express the same information in a different way. After passing this Generic kind of ViewModel to the MVC, you can convert the generic "SelectListItem" to the MVC SelectListItem. Yes, it is sort of mapping, and it does not matter whether it takes place in the MVC view or before passing it to the View. But it must happen on the UI layer (MVC web project), since it's a platform specific mapping concern.
You mentioned data access code: that's a separate software layer, usually abstractly injected into the ViewModels. I foresee no problems with this part.
Hence, you will end up having different software layers (most likely in different .NET libraries): Data Access Layer, ViewModel layer, MVC Web layer.
There is a possibility of having MVC ViewModels as well (one passed from Controller to View) defined in the MVC project, but those will be simply handling (probably accepting) the generic ViewModels and exposing things in the MVC View-specific terms (mapping, inheritance, your imagination?). And this is normal too - after all, MVC is a web-based UI and it definitely has platform-specific differences that must be handled on the platform level, not before. MVC specific ViewModel would be a good place to handle the mapping from generic to MVC SelectListItem.
Once this refactoring is done, there's nothing stopping you from implementing another UI layer - Console application that you are mentioning, by utilizing the same generic ViewModels as the other UI layer - MVC Web project. When using the generic ViewModels in the console application, if you face the Console platform-specific issues, you can come up with the platform-specific ViewModels in the same way as I explained above for the MVC-specific ViewModels.
You can create viewmodels in controller with extension methods:
Controller:
public ActionResult ApplicationDetail(int id)
{
var model = _serviceLayer.GetSomeModel(id);
var viewModel = model.CreateInstance(model);
return View(viewModel);
}
Create this SomeModelExtensions in your mvc project
public class SomeModelExtensions {
public AppDetailViewModel CreateInstance(this SomeModel model) {
var viewModel = new AppDetailViewModel();
// here you create viewmodel object from model with logic
return viewModel;
}
}
In general I use the following setup/architecture when laying out an MVC app where I may need to reuse the models:
MVC Project: everything web related. I define ViewModels here and map them to the domain models.
Models Project: class library with all your domain logic.
Repository project: This is a class library which access the DB and the Domain Models.
The way it works is that the MVC project will use the (hopefully injected) Repository library to get the Domain Model and map it to its own ViewModel.
If you want to separate the mapping as well, you can put the Mapping Layer, as others have suggested (using AutoMapper eventually), in a separate project. The mapping layer will reference the repositories (and the domain models), while the MVC app will only reference the Mapping layer.
The problem is that the mapping layer, in creating ViewModels, will need a reference to System.Web.Mvc as you found out and you cannot escape this. This is why others have said, and I agree, that you should have a mapping layer per project.
A nice way to get around this is to have a further generic mapping layer with mapping classes defined for the common cases (like the email). Then in the specific child classes you can define the mapping for specific cases (like the ones depending on System.Web.Mvc).
So the end stack would be something like the following, dependencies going down. Of course everything should be interface based.
MVC App Console App
| |
| |
MVC Specific Mapper Console Specific Mapper
\ /
\ /
\ /
GenericMapper <- EmailMapper and EmailViewModel can be implemented here
| |
| |
Repository |
| |
| |
DomainModels
The above is not struggle free and probably the effort of splitting the mapping apart is not worth the candle if there are only one or two common cases. That way, from the Generic Mapper down you are free from the System.Web.Mvc library, while above you are free to forget about DB access code (In a sense the Mapper will act as a Repository for the App).
I assume the MVC web will use the same data as the console app + extra fields, right?
so, what about inheritance your ViewModel from Model? That way you would be able to reuse the model and get custom fields on your ViewModel as needed.
public class AppDetailModel
{
public int ID { get; set; }
public string Name { get; set; }
}
public class AppDetailViewModel : AppDetailModel
{
public string ViewProperty { get; set; }
}

Using web service in MVC, new Model or not?

I'm going to develop a web-based system with MVC4 which will use web services (WCF, exactly) for getting data from data provider (I can't use direct connection to SQL)
So, I have a question about using the web services in this project. Is this correct to use directly web service models as MVC model or I should create separate models for my MVC project and then map web service models to the models in MVC with an object-mapper (such as EmitMapper)?
Note: Consider that the web services may changes a lot.
No, don't use your WCF serializable proxy classes as MVC Viewmodels - this will couple the SOA back end to your MVC front end unnecessarily.
The 2 classes have entirely different concerns - e.g. you may want to decorate your ViewModels with DataAnnotations like UIHint etc which aren't applicable to your WCF classes (and similarly, your WCF Proxy classes may have serialization attributes).
Also, as your screens evolve, you will typically find that you may need to diverge the 2 models significantly - e.g. your screens need properties which your Service doesn't need, and vice versa.
So yes, separate classes for WCF data serialization and for MVC ViewModels, and as you've suggested, if you keep to a standard naming convention, mappers like AutoMapper will do most of the work for you.
I can only tell you what I would do.
Keep the models separate. As you say, the web services may change a lot. Having a halfway house may shield you from a lot of the implementation churn.
Also worth pointing out that:-
Easier to move to a different solution ( use a different strategy to populate the model )
Easier to unit test ( don't necessarily need a net connection to test that your model works )

What about the Model in Large ASP.NET MVC Project

I've been doing some research on using ASP.NET MVC and Entity Framework together for a fairly large project.
Most examples separate the .edmx file from the MVC project by moving it to a new DAL project. In this project you would also find repositories and interfaces.
While this approach makes perfect sense to me, there's one thing I can't seem to figure out: what about the Models in MVC? In most examples the Controllers address the repository interfaces from the DAL project directly, so the MVC Models are no longer used? Or is it a good idea to keep using them, but map them in the Controller?
There are 2 types of models:
domain models
view models
The domain models represent your domain entities. They could be the autogenerated EF classes from your database or coming from somewhere else such as proxies generated from a WCF service that you are consuming. Those should live in your domain layer.
View models on the other hand go in the Models folder in the ASP.NET MVC project. Those are specific classes that you define for each view. The controller actions will query your DAL layer to fetch one or more domain models and instantiate a view model which you have specifically defined for the given view that you want to render from this controller. So a view model could hold information from multiple domain models (just because in the given view you need all this information). Then the controller passes the view model to the view for displaying.

Categories

Resources