I've an ASP.NET MVC project with a domain and a data layer (contains just EF and migrations).
Now, I have to validate a Client's VATNumber field with a specific formula I'm having doubts where to place it.
I would like to use the Controller's ModelState to check if the field is valid, using a EF DataAnnotation ValidationAttribute, so I don't have to validate it in the Controller's Saving Method. But I'm conflicted having to put business logic in the data layer.
Is there some kind of alternative to ValidationAttribute, so it can be "injected"? Or I'm just looking at this wrongly?
Validation attributes is not part of Entity Framework.
If you want splite data layer from presentation layer, you can use Viewmodels and bind them on datamodels with Automapper. In this case you place domain validation on viewmodel and validation of datalayer on datamodel.
In very complicated cases you may have three models: viewmodel, domainmodel and datamodel, but in common cases viewmodel and datamodel is enough.
Related
Suppose I have a model which I need to validate. I can add some validate attributes to the properties I want to validate. And it works pretty fine. But at some point I want to validate this model depending on other models (I will need t query db). And here there are some options.
create a special validate attribute which will lack dependency injection
delegate this validation to some business layer (manager) and in controller
_
if (Model.IsValid) {
if(!await Manager.Create(myModel)) {
Model.CopyErrors(Manager.Errors); // Extension method for Model
}
}
So what is the correct way of handling such a situation?
P.S. I am using asp.net core and entity framework core
What you need is Fluent Validation
I am wondering if there is a way to generate a View Model from database table including validation (required,length,datatype). Of course I will edit it and enhance it.Otherwise it is a waste as I have to type in everything
We are implementing a "Dynamic" approach to validation in one of our projects where the validation rules are encoded in a database table and we override GetValidators() in a custom implementation of DataAnnotationsModelValidatorProvider to inject custom and/or standard validation attributes. These can then be propagated to the client if we want them to. As for creating a viewModel from the existing database, you can use t4 files to read the db schema and generate classes for you and inject validation attributes on the model as it is being created.
I have a 3-tier web application wit ha bunch of simple forms. One to list records, one to edit a single record, etc. The works.
I have a DataLayer where my EDMX is.
I have an App Layer where my POCOs are.
I haev a BusinessLayer with all my controller classes, etc. (not MVC!)
I have a UI layer where my web UI is.
The EDMX has many, many tables wit ha lot of navigation properties.
Of course, when I fetch the data in one of my controllers, e.g. GetCustomerById(int id), I create the Object context and close it when I'm done.
However, the ObjectContext is out of scope when I try to access the navigation properties in the UI layer.
Should I do (using MyContext = new MyContext()) {... } in the web layer?? that does not seem right.
Should I create another set of POCOs that I populate from the entities' data from the BizLayer?
What happens when I want to save data entered in a web form? Would I call a BizLayer controller e.g. SaveCustomer()?
My question is, how do you design the web UI layer if I want to be able to properly access the navigation properties of an entity?
Note:
EDMX is set to LazyLoading.
You want to use lazy loading in UI but it means that UI defines lifetime of your ObjectContext. There are many ways to achieve this without exposing the context to UI. You can for example use this simple approach:
You mentioned some controller which uses context and disposes it. So make your controller disposable and instead of disposing context in every method use single context for whole lifetime of the controller. Dispose the context in controller's Dispose method.
Instantiate your controller per request. So for example you can create instance of controller in Page.Load and dispose it in Page.Unload.
Use your controller and entities as you want. Whole processing of the request (between Load and Unload) will be in scope of single living context.
Anyway you should not need lazy loading in Web application too much. In your form you usually know exactly what entities you need so you should request them directly with eager loading.
In most of the MVP examples I've seen, the presenter calls some service, which calls some repository, which returns an entity. In most asp.net web applications that I have worked on, the logic is never that simple. In my last project, my presenter called a presenter service layer that had to jump through hoops to get the data that was to be shown on the screen.
Details: The service layer queries a database for, let's say, 8 entity objects, some of which are nested within each other, then the code maps those entities to one huge object base off of an XSD. That xsd object was then passed to a 3rd party library to do something with it. After it returned the processed xsd obj, the code then had to parse through that xsd object, using a middle layer view formatter class to extract and build what I call the "View Model" (I've heard some call it a DTO). This View model was then returned from the service layer to the presenter and then databound to a repeater.
Where does the logic for show/hide controls go? Should that be a member in the DTO or should the presenter derive this value? (I chose to have it as a member in the view model)
Is it ok to have nested ViewModels(DTOs) or should other user controls be used to break down the complexity?
What is a good way to wire up a presenter with all of the Pages/UserControls that use it; meaning one presenter with 5 IViews that require the same instance of the presenter. Should user controls be self contained or should they rely on the "parent" IView(page) to give it the proper presenter?
Instead of having a view model, why not just use the Interface that the Page implements and pass that to the service layer (through the presenter) and let the service hydrate the IView? (Doing this would cause the service layer to have a reference to it, isn't that bad?).
public class ViewModel
{
public bool ShowHeight { get; set; }
//Is there a bettter way to do this?
public List<NestedViewModel> NestedViewModel { get { return _nestedViewModel; } }
}
IMO, the view should manage itself in showing and hiding; it is the view and is responsible for managing the UI behaviour.
I think complexity is OK as long as its not too overbearing; you can break it down into nested subpresenters/views if you need to.
Most MVP frameworks populate the presenter/view relationship from the view, especially since ASP.NET runs in the context of the page (the page is the HTTP handler processing the request, so it's what is alive at that point). The page, during init, goes and establishes the view/presenter relationship. Most examples do it this way. I built an MVP framework and have also established this approach.
You could; that's considered passive view, though the presenter should still do the work, and not directly pass to the service layer.
This is my opinion and there are many ways to do this.
I am using in my views (asp mvc3/razor cshtml) references to the Request object (eg, #Request.Params["Name"]). Do you think this is a very bad practice? Should I rewrite the value in the controller Request.Params ["Name"] to ViewBag.Name and then use it in the view (#ViewBag.Name)?
Best practice is to use a model class. An instance of the model class is created or updated in your controller. Then the controller displays a strongly-typed view.
So I'd avoid direct access to the request from the view as well as the use of the view bag.
Should I rewrite the value in the controller Request.Params ["Name"] to ViewBag.Name and then use it in the view (#ViewBag.Name)?
Yes. You will avoid runtime errors if "Name" does not exist.
The IDE will not warn you of the NullReferenceException about to be thrown with the following code.
#Request.Params["Fake"].ToString()
Of course, you'll have to be careful about ViewBag.Fake being null as well.
I like to use the viewbag to store things not related to the model, for example if I have a dropdown containing locations. I like to store only the id of the selected location on the model and the locations in the viewbag, since is not needed to create a contact. I think that's the purpose of the viewbag.
For me the model is a bag or properties used in business operations, for example if I have a customer creation view using a NewCustomerModel, I don't wanna pollute my model with things like a IList<CustomerType> AND a SelectedCustomerTypeId property. I just want the second since is the one imma use to create the customer.