so when implementing entity framework code first in mvc, do we separate the view restrictions from view model? this is because for database first the model is generated(so i see the reason to separate it to view model but how about code first?)
The next questions i would ask is it ok to separate view model to another folder? since by default asp.net is MVC there is no view model inside
Model <--- what is this model call? data model? domain model? business model?
public class Student
{
public int ID { get; set; }
[StringLength(250)]
public string LastName { get; set; }
public string FirstMidName { get; set; }
public DateTime EnrollmentDate { get; set; }
}
View Model
public class Student
{
public int ID { get; set; }
[MaxLength(250)]
[Required]
public string LastName { get; set; }
[Required]
public string FirstMidName { get; set; }
[Required]
public DateTime EnrollmentDate { get; set; }
}
Your model that Used in mvc views is viewmodel.
your model that persist in database is domain model.
Your domain model may has some properties that you don't need use it in your client.
Your Service layer must return Dto (data transfer object) to your client and you can map dto to viewmodel .
First Question:
You should use partial class and metadata to seperate , just like below:
[MetadataType(typeof(StudentMD))]
public partial class Student
{
public class StudentMD
{
public int ID { get; set; }
[MaxLength(250)]
[Required]
public string LastName { get; set; }
[Required]
public string FirstMidName { get; set; }
[Required]
public DateTime EnrollmentDate { get; set; }
}
}
Second Question:
It's OK to add a folder name "View Model"
I did it in my project too!
Related
i am trying to define a database model in code-first to see and display which user is assigned as a specialist for the record data.
I have a very simple model for the user:
public class User
{
public int ID { get; set; }
public string userName { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
....
}
Next I have defined two (simple) models which define the data that can be edited by the user and the specialist should be assigned to using a dropdownlist:
public class Order
{
public int ID { get; set; }
public string orderNumber { get; set; }
public int specialistID { get; set; }
public virtual User specialist{ get; set; }
}
public class Part
{
public int ID { get; set; }
public string partNumber { get; set; }
public string description { get; set; }
public int specialistID { get; set; }
public virtual User specialist{ get; set; }
}
What kind of relation between the models can be used without having a navigation property for each table in the User model?
Do I need to use additional tables to define the relationship: User.Id-Order.specialistID and the relationship: User.Id-Part.specialistID ?
Is there a smarter way out-of-the-box by Entity Framework?
Many thanks for your answers.
Pascal
By default when you add forign-key constraint to the many-to-one table the Entity Framework add virtual property to the entity class and virtual ICollection to the User.
I'm having trouble understanding how to implement a ViewModel in Asp.net MVC, I have the following tables:
Form
ID, Data
Report
ID, FormID, Owner, Category, Status, SubmissionDate
ReportValues
ID, ReportID, Title, Value
I'm looking for a way to display and edit Report and ReportValues in the one ViewModel where ReportValues.ReportID = Report.ID
ReportValues will have multiple entries that relate to a Report.
I have had a look at similiar questions on here and tried following a tutorial ( http://techfunda.com/howto/262/list-data-using-viewmodel ) and coming up empty handed.
If you need any more information let me know and thanks in advance for any replies!
Your View Model is nothing more than a class. You can solve this many ways, but here's an example.
Create your 3 classes like you normally would.
public class Form
{
public int Id { get; set; }
public string Data { get; set; }
}
public class ReportValues
{
public int Id { get; set; }
public int ReportId { get; set; }
public string Title { get; set; }
public string Value { get; set; }
}
public class Report
{
public int Id { get; set; }
public int FormId { get; set; }
public string Owner { get; set; }
public string Category { get; set; }
public string Status { get; set; }
public DateTime SubmissionDate { get; set; }
}
Then, create your ViewModel class to include the three above classes like this.
public class ReportViewModel
{
public Form Form { get; set; }
public ReportValues ReportValues { get; set; }
public Report Report { get; set; }
}
In your view you can access your three classes and their properties as you would in your controller. Model.Form.Id
Depending on your data types, ReportValues will likely be a property of Report, but that's entirely up to your data structure. You will need to populate the classes using whatever method you want (Entity Framework, ADO, etc.) before you can pass them to your view and use them.
I am buys designing the model below:
public class LogModel
{
public class UserActivityLogs
{
[Key]
public int id { get; set; }
//Id of the user
public string userId { get; set; }
//Time of the log
public DateTime time { get; set; }
public LogActions action { get; set; }
}
// Types of actions to log
public class LogActions
{
[Key]
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
}
}
Now what I would like to know is do I need to add a table in the context for Logactions as well as UserActivityLogs or will EF see that the two tables are linked and create the log action table automatically?
Also have I specified my relationships correctly? What I was aiming for is that I can define multiple types of Logactions and then a userlog will then have a single log action associated to it.
First, don't use nested classes, it's a needless complication. Use namespaces to organize classes.
Second, don't use plural names for classes. One instance of class represents one entity. Also, use CamelCase names for properties.
Third, yes, Entity Framework will be aware of the associations between the two classes and create a database model with two tables and a foreign key.
So this leaves you with:
namespace MyApp.LogModel
{
public class UserActivityLog
{
[Key]
public int Id { get; set; }
public string UserId { get; set; }
public DateTime Time { get; set; }
public LogAction LogAction { get; set; }
}
public class LogAction
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
I have a UserFormModel which contains a UserModel which has a set of properties with the [Required] attribute set. I have read that MVC 3 out of the box will validate models within models by default. However when I submit an empty form in my view passing back a UserFormModel containing an empty UserModel the ModelState.IsValid is always true.
I have tried sending just the UserModel back to my controller and that validates ok. It just seem to be when I am working with complex models that it does not validate.
I have also tried it with the [Required] attribute on the User property within the UserFormModel (which I believe is not required for default behaviour to work) but still no validation takes place.
Any ideas on this one would be much appreciated.
public class UserFormModel
{
public UserModel User;
public IEnumerable<SelectListItem> Roles { get; set; }
}
public class UserModel : ModelBase
{
[Required]
public string UserName { get; set; }
public string Title { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
}
[HttpPost]
public ActionResult Create(UserFormModel userFormModel)
{
if (ModelState.IsValid)
{
// Do Something
}
}
You should use properties not fields. So instead of:
public UserModel User;
you should have:
public UserModel User { get; set; }
The reason for this is that the default model binder works only with properties.
I believe that validation only goes one model property deep in the model. For example if you have the following model
public class Product
{
public int ProductId { get; set; }
[Required]
public int ProductName { get; set; }
[Required]
public decimal Price { get; set; }
}
public class ProductViewModel
{
[Required]
public Product Product { get; set; }
}
The validation against the product object in the view model will work, the validation against the product class will not with one caveat. If the Product class is a POCO class used in the entity framework code first method, the validation will work against the database. Validation against a view model will only work one deep in my experience.
I'm searching for a good way for managing my view models and especially the classes used in these view models. I explain below with an example:
Let's say I would like to display a view which contains a project (title, content, category, ...) and below it a list of some related projects (of the same category). I created a view model especially for this view. Here it is:
public class ProjectDetailsViewModel
{
public ProjectFullViewModel OneProject { get; set; }
public IEnumerable<ProjectLightViewModel> RelatedProjects { get; set; }
// Below are the classes used in this view model
public class ProjectFullViewModel
{
public int ProjectID { get; set; }
public string Title { get; set; }
public string Slug { get; set; }
public string Category { get; set; }
public string Client { get; set; }
public int Year { get; set; }
public IEnumerable<Technology> Technologies { get; set; }
public byte[] ScreenshotData { get; set; }
public string ScreenshotName { get; set; }
public int ScreenshotLength { get; set; }
public string ScreenshotType { get; set; }
public byte[] BackgroundData { get; set; }
public string BackgroundName { get; set; }
public int BackgroundLength { get; set; }
public string BackgroundType { get; set; }
}
public class ProjectLightViewModel
{
public int ProjectID { get; set; }
public string Title { get; set; }
public string Slug { get; set; }
public string Category { get; set; }
public string Client { get; set; }
public string Year { get; set; }
}
}
As you can see, all classes used in this view model are contained in it. I think this is easier to keep en eye on what is used. What do you think? Is it a good/bad practice? Some suggestions? I noticed that when we have a lot of view models and classes used we can be a little confused. Don't blame me, I'm still learning ASP.NET MVC and I would like to make good choices...
Thanks.
I wouldn't use nested classes for view models. In order to reference them you will have to always specify the base class. That's could be particularly annoying when writing the mappings between your domain models and view models. If you are afraid of having many files containing your view models you could still place all the dependent view models inside the same .cs file as the parent model.
That is good practice. It is the use of View Models that allow you to pass or retrieve the necessary data to or from a View. That's what precisely makes them view models. Classes designed specifically for a View.
As for the concern of "too many" or confusion, that just comes down to your project/solution organization. Have enough logical separation so that it is evident where all your classes live.