am very new to ASP.NET USING MVC Controllers...so here is my scenario.Am developing an Online Admission system where students come and fill in their required records to be processed for admission.I have different classes that holds specific information about the student.My student class is:
public class Student
{
public int ID { get; set; }
[Required]
public string NAME { get; set; }
[Required]
public string FIRSTNAME { get; set; }
[Required]
public string LASTNAME { get; set; }
public virtual ICollection<Enrollment> Enrollments { get; set; }
}
I have another class called Enrollments where the user Enters all the courses as well as the Grade
public class Enrollment
{
public int EnrollmentID { get; set; }
public int CourseID { get; set; }
public int StudentID { get; set; }
public Grade Grade { get; set; }
public virtual Student Student
{
get;
set;
}
public virtual Course Course { get; set; }
}
public enum Grade
{
A,B,C,D,E,F
}
}
AND different more classes.I HAVE A CONTROLLER called Registration, where i will create the views for each Classes.
SO IN my first View which takes all the student Details,after the Record has been saved.
when the user Clicks next,i want to pass the ID number of the student class to my next view which is the Enrollment View and save the records along with the ID number of the student class which is acting as a foreign key in the enrollment class and database.
Have been trying so hard 2 implement this but with no success.I would appreciate a simple example to demonstrate how to achieve this because am not too good using the mvc framework as i recently started using ASP.NET.
First lets make it clear this is MVC and not web forms. In MVC the flow goes like this
View ----> Controller----->Model then back to controller and so on in usual cases.
Now what you probably want to do is pass a value(here ID ) from the form in first view to another view, this should probably be done like this.
Say for eg. your textbox storing ID is named "tb1" then write the following code in your controller
int id = (Request.Form["tb1"]).toString();
//now we'll store this id in a ViewState varibale like so
ViewData["id"] = id;
//don't worry about the data type of ViewData["id"], it would adapt automatically
Then after proper redirection, i.e. return of the second view from your controller, just access this ViewState variable any where you need like so:
#ViewData["id"]
Please note that this is Razor syntax and your views need to be in .cshtml pages rather than .aspx pages
You Can use ViewBag.MyProp = "XYZ";
and in our view you can retrieve this as :
var name = "#ViewBag.MyProp"
Related
I am new to ASP.NET MVC. Using Entity Framework 6, I am working on a project to store employee skills in a database. The user can enter a new skill into a list of skills. I would like to keep track of who added the new skill. I have a table of all of the employees.
These are the models for the two tables.
public partial class Skill
{
public int ID { get; set; }
public string Skill { get; set; }
[ScaffoldColumn(false)]
public int LastActionUserID { get; set; }
public virtual Employee Employees { get; set; }
}
public partial class Employee
{
public int ID { get; set; }
public string EmployeeLAN { get; set; }
public int LastActionUserID { get; set; }
public virtual Employee Employees { get; set; }//References itself for LastActionUserID
public virtual ICollection<Skill> Skills{ get; set; } //Omitted in initial question
}
There is a 1 to Many mapping of Employee to Skill. I can get the current user's EmployeeLAN but how do I get the id of that Employee record to put into the Skill table automatically when then new skill is created? Must I convert the table to an enumerable object and use SingleOrDefault or LINQ? Or is there an easier way using EF6? Also, setting this automatically when a new skill is created would be done in the controller, correct?
You're on the right track and you should continue to use EF6.
The Employee class should have a Skills list. That way you can call myEmployee.Skills and have a list of all the skills available.
public partial class Employee
{
public int ID { get; set; }
public string EmployeeLAN { get; set; }
public int LastActionUserID { get; set; }
public virtual ICollection<Skill> Skills{ get; set; }
}
Also, setting this automatically when a new skill is created would be done in the controller, correct?
You'll need to add to the Skills list, call AddOrUpdate() to mark this as changed, then SaveChanges() to persist it to the database.
I recommend learning more from the MSDN docs and Julie Learman's
Entity Framework videos on Pluralsight
I am relatively new to MVC and I am working on making a webshop in MVC.
My current model for displaying products (or shopping cart items):
public class ShoppingCartItems
{
public virtual int ID { get; set; }
[Required]
public virtual string ProductName { get; set; }
public virtual int CategoryID { get; set; }
public virtual DateTime DateAdded { get; set; }
[Required]
[DataType(DataType.Currency)]
public virtual decimal ProductPrice { get; set; }
public virtual int AmountAvailable { get; set; }
}
Should I add a property here in order to make a connection between a user who has logged in and the products the user chose to add to the shoppingcart or should I take a look at this matter in the controller instead (or make use of both controller and model to relate the two)?
In this example I also make use of a CategoryID which should point to a category class containing the (available) option values of categories. How do I make such a relationship in MVC between classes?
To identify user who is logged you could use Membership, Simple Membership, Identity or implement your own authetication. You can read more for example here. http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity. For category problem you can just add property of type Category to your model. Details depend on what ORM you are using.
As my domain classes I have Person and FavoritePerson classes as follows.
public class CompanyPerson : ICompanyPerson
{
[Key]
public Guid PersonId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
public class CompanyFavoritePerson : IFavoritePerson
{
[Key]
public Guid FavoritePersonId { get; set; }
[Column(TypeName = "datetime2")]
public DateTime CreateDate { get; set; }
public Guid? CompanyPerson_PersonId { get; set; }
[StringLength(128)]
public string CompanyUser_UserId { get; set; }
public virtual CompanyPerson CompanyPerson { get; set; }
public virtual CompanyUser CompanyUser { get; set; }
}
In my web application I will need to show List of Favorite Person. So my view model is like this;
public class FavoritePersonViewModel
{
public Guid FavoritePersonId { get; set; }
public DateTime CreateDate { get; set; }
public Guid? CompanyPerson_PersonId { get; set; }
public string CompanyUser_UserId { get; set; }
//Option1: PersonViewModel PersonViewModel {get; set; }
//Option2: public string Title {get;set;}
}
Since I need to show Title of the favorite user in the list (where title belongs to Person class) which way will match with best practices?
Referencing a viewModel from another viewModel or extend viewModel with required extra attributes and fill them in business layer?
After some more research on this topic; I found out at this question
What is ViewModel in MVC?
it is clearly stated that:
View models can combine values from different database entities.
As like below;
So now you have data from the Employees and Departments tables in one
view model. You will just then need to add the following two
properties to your view model and populate it with data:
public int DepartmentId { get; set; }
public IEnumerable<Department> Departments { get; set; }
So I am going with Option 2.
The ViewModel pattern is just one of many patterns that fall into the 'Separated Presentation Pattern' bucket.
It's very important that you think about the requirements of your view before designing the ViewModel. For instance, if you have two widgets in your view and every widget has its own ViewModel, composite ViewModel is suitable in the situation, but if the view is just one that uses multiple domain classes, whether you have View model for each one, composite ViewModel is not suitable because it increases the complexity and every change in one ViewModel can break your code.
Thus, based upon your question
As my domain classes I have Person and FavoritePerson classes.
Since I need to show Title of the favorite user in the list (where title belongs to Person class).
It seems to me that composite ViewModel is not a good choice and you should design a new ViewModel.
It is also worth to read the ViewModel Best Practices
I have a situation where I have a many to many relationship in my model between Student and Lesson. In most cases Lessons are 1 on 1 where a single student attends the lesson but there are situations where a lesson is shared by more than one student (hence the many to many).
So my ViewModel looks a little like this:
public class ScheduleViewModel
{
public Lesson Lesson { get; set; }
public List<StudentViewModel> Students { get; set; }
public List<StudentViewModel> AllStudents { get; set; }
}
In the View I would bind the Lesson properties using DisplayFor to show the details of the Lesson. Then I would have a DropDownListFor which uses AllStudents as its source. When a user selects a Student from the list a second DropDown would be generated (etc) allowing further Students to be added. These selections will be added to the Students property of my ViewModel.
In the past I would have handled this is javascript and managed the updating via JSON and AJAX. My instinct is that I should be using MVC Templates for this but in my research I've not found an example that has this exact scenario (or of course I may be barking up the wrong tree).
I have no code for my View at the moment as I'm really stuck on the right strategy to use in this case.
I hope that makes sense and any help on this greatly appreciated.
Many Thanks
Simon.
Your Lesson class should have a binding for Students, something like this:
Lesson.cs
public class Lesson
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<Student> Students { get; set; }
}
Then in your Student class you would bind a relation to lessons:
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public virtual List<Lesson> Lessons { get; set; }
}
Now you have a many-to-many relationship between Lesson and Student.
Your viewmodel would then look more like this:
public class ScheduleViewModel
{
public Lesson Lesson { get; set; }
// All students property
public List<Student> Students { get; set; }
}
Your Lesson property now contains all the information about your lesson, including which Students are connected to it, because it has a List of Students. You want to add the selected students from your view to this list.
The Students property is used to display all students in the database.
one for customer, and one for address.
Required Functionality When a customer registers, they enter their personal details such as name, tel as well as their address details in the same view.
Current Functionality
At present, EF scaffolding provides a dropdown list of addresses to choose from.
Current Code
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
[Required]
public string Surname { get; set; }
[Required]
...
Customer Fields
...
public int AddressId { get; set; }
public virtual Address Address { get; set; }
}
public class Address
{
[Key]
public int AddressId { get; set; }
...
Address Fields
...
// Navigation Properties
public virtual List<Customer> Customer { get; set; }
}
When seeding the database, I can do so as follows:
new List<Customer>
{
new Customer
{
** Customer Fields ** ,
Address = new Address { ** Address Fields ** }
}
}.ForEach(c => context.Customers.Add(c));
base.Seed(context);
My thoughts
My initial thoughts are that I should create a 3rd Data model called CustomerWithAddress which is essentially a composite of customer and address models. This would allow me to scaffold a strongly typed view.
Alternatively, is it possible for a controller to pass 2 models to 1 view?
I don't know if this is the best way of tackling this problem, or in fact if it is possible. Any thoughts?
If your customer model has an address property, then you will be able to access it from your view. e.g.
#Html.DisplayTextFor(x => model.Address.Addressline1)
Your viewmodel Idea is a good one, but it's not necessary for this particular case.
EDIT: As my friend below pointed out, you may need to manually load the Address property if you are employing lazy loading.