Say I have this model:
public class Person
{
public int PersonId { get; set; }
[Required]
[MinLength(2)]
public string Name { get; set; }
[Phone]
public string PhoneNumber { get; set; }
[EmailAddress]
public string Email { get; set; }
}
but in my controller I want to add a temporary binding of data just to be passed once to a View such that:
Person.temp = new string();
and in each Person object in my controller I can add a unique Person.temp before it is sent to its view:
for (i = 0; i < 5; i++)
{
Person per = new Person();
per.temp = "example" + i;
per.PersonId = i;
per.Email = "555example#stack.co";
listofPersons.Add(per)
}
return(listofPersons)
public class Person
{
public int PersonId { get; set; }
[Required]
[MinLength(2)]
public string Name { get; set; }
[Phone]
public string PhoneNumber { get; set; }
[EmailAddress]
public string Email { get; set; }
[NotMapped]
public string Temp {get;set;}
}
Have your tried marking it as NotMapped ?
Related
I have the code below:
public class Author
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public List<Blog> Blogs { get; set; }
}
and the Blog class itself:
public class Blog
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime PublicationDate { get; set; }
}
I instantiate the list property in Program class (main method) by this way:
lBlog.Add(new Blog { Id = 1, Title = "War & Peace", PublicationDate = new DateTime(2020, 02, 23) });
So far - good. But, when I'm trying to add it to author object it's empty
author.Blogs.AddRange(lBlog);
You should initialize Blogs list in Author class constructor
public class Author
{
public Author()
{
Blogs = new List<Blog>();
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public List<Blog> Blogs { get; set; }
}
Or use property initializer for that (it's available from C# 6). In this case make sense to make a property readonly (to prevent overwriting a property from outside)
public class Author
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public List<Blog> Blogs { get; } = new List<Blog>();
}
Try this:
public class Author
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public List<Blog> Blogs { get; set; } = new List<Blog>();
}
I'm having a client, and it sending the following Signature to the Library
Client UI Signature :
namespace Library.Model
{
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public string streetName { get; set; }
public string City { get; set; }
public string State { get; set; }
}
}
Library DB Structure:
namespace Library.Data
{
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public int AddressId { get; set; }
public Address AddressInfo { get; set; }
}
public class Address
{
public int AddressId { get; set; }
public string streetName { get; set; }
public string City { get; set; }
public string State { get; set; }
}
}
Here I'm doing the mapping process from Client UI model to DB Structured model. How could I use the DB structured model as like Client model instead of the Client model.
Kindly assist me how efficiently we can share the DB Structured model in Client?
Note: But the Client the Signature should be
public class Person
{
public int PersonId { get; set; }
public string Name { get; set; }
public string streetName { get; set; }
public string City { get; set; }
public string State { get; set; }
}
Kindly refer Update a class property based on another Property of a calss properties value in the Setter - I need the solution similar to this.
i think you can use PersonViewModel to make this and it will be like you mention
public class PersonViewModel
{
public int PersonId { get; set; }
public string Name { get; set; }
public string streetName { get; set; }
public string City { get; set; }
public string State { get; set; }
}
Make join and file this object
PersonViewModel persons = new PersonViewModel ();
I wish it will help you :)
I have been trying to make this happen for a few hours now.I have two models within my model folder called Models, i am trying to pull data from the model to display it in the view, i am aware of only one model statement can be applied to the view. So i have Created a ViewModels which contain the properties that i would like to reference in the view. now when i run the the application im getting a compilation Error which says:
"Compiler Error Message: CS0246: The type or namespace name 'Models' could not be found (are you missing a using directive or an assembly reference?)"
I would appreciate a bit of help of if there is any other way of doing it feel free to advice.
New ViewModel created
public class MainModelscs <T> where T :class
{
public StoreAudit StoreAudit { get; set; }
public StoreQuestions StoreQuestions { get; set; }
public List<string> StoreWindow { get; set; }
public IPagedList<T> IndexList { get; set; }
}
ViewMode PROPERTIES inside my view,
#model PopMarketing.ViewModel.MainModelscs<PopMarketing.Models>
Model 1
public class StoreQuestions
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int ReviewId { get; set; }
public int AuditId { get; set; }
public int QuestionOne { get; set; }
public string QuestionTwo { get; set; }
public string QuestionThree { get; set; }
public string QuestionFour { get; set; }
}
Model 2
[Key]
[Column(Order = 1)]
public int AuditId { get; set; }
public string Date { get; set; }
public int StoreNumber { get; set; }
public string StoreName { get; set; }
public string Address { get; set; }
public string Manager { get; set; }
Controller Method
public class AuditController : Controller
{
private PopMarketingContext db = new PopMarketingContext();
//
// GET: /Audit/
private const string PASSWORD = "MarchJava2016";
public ActionResult Index(string searchString)
{
int number;
int check;
bool result = Int32.TryParse(searchString, out number);
if (result)
{
check = Convert.ToInt32(searchString);
var shops = from s in db.StoreAudit
select s;
if (!String.IsNullOrEmpty(searchString))
{
shops = shops.Where(s => s.StoreName.ToUpper().Contains(searchString.ToUpper()) ||
s.StoreNumber.Equals(check));
}
return View(shops.ToList());
}
else
{
var shops = from s in db.StoreAudit
select s;
if (!String.IsNullOrEmpty(searchString))
{
shops = shops.Where(s => s.StoreName.ToUpper().Contains(searchString.ToUpper()));
}
return View(shops.ToList());
}
}
Jaimin is correct, in #model you pass the class you want to use as model, not the directory or namespace of the class.
As for using viewmodels correctly:
Let's say I have two classes:
class Student
{
public string name;
public string mentor;
}
class Teacher
{
public string name;
public string salary;
}
And i want to have a view show both their names. I can create a viewmodel like this:
class StudentAndTeacherVM
{
public Teacher teacher;
public Student student;
}
The controller would look like this:
public ActionResult Index()
{
var student = new Student();
*fill student*
var teacher = new Teacher();
*fill teacher*
var model = new PersonVM();
model.teacher = teacher;
model.student = student;
return view(model);
}
Now you can reach them in the view by:
#Model.student.name
#Model.teacher.name
Or if I want to be as efficient as possible, I could also just put in the names into the VM.
controller:
public ActionResult Index()
{
var student = new Student();
*fill student*
var teacher = new Teacher();
*fill teacher*
var model = new PersonVM();
model.teacherName = teacher.name;
model.studentName= student.name;
return view(model);
}
View:
class StudentAndTeacherVM
{
public string teacherName;
public string studentName;
}
Create instance of MainModelscs in your action
. . .
i.e. MainModelscs <string> Obj = new MainModelscs <string> ;
. . .
Then pass this to the view.
return View(Obj);
Now in your view,
#model PopMarketing.ViewModel.MainModelscs<string>
(take T as your model name not the namespace!)
Sorry, i got much late than i said. But here is how you can join two tables, map them to a model and pass to the view. The first one of the class whose properties correspond to the comments table of the database.
public class Comments
{
public int ID { get; set; }
public string CommentText { get; set; }
public string Username { get; set; }
public int Upvote { get; set; }
public int Downvote { get; set; }
public int InappropriateFlags { get; set; }
public int PostId { get; set; }
public string ControllerName { get; set; }
public int ReplyTo { get; set; }
public bool replied { get; set; }
}
Now another user profiles table which is needed to be joined with the comments table.
public class UserProfile
{
public int ID { get; set; }
public string Username { get; set; }
public string DisplayName { get; set; }
public int Reputation { get; set; }
public DateTime DateOfRegistration { get; set; }
public int Money { get; set; }
public string ImageUrl { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Country { get; set; }
public string State { get; set; }
public string City { get; set; }
public string Location { get; set; }
public int? PostalCode { get; set; }
public int ProfileViews { get; set; }
public string AboutMe { get; set; }
}
Now the much needed model for handling the join of these two tables. I haven't included all the properties of both tables as i didn't need them in the view, but you can ofcourse include them. In that case, don't forget to update your data access query also.
public class CommentUserProfileJoin
{
public int ID { get; set; }
public string CommentText { get; set; }
public string Username { get; set; }
public string DisplayName { get; set; }
public int Upvote { get; set; }
public int Downvote { get; set; }
public int InappropriateFlags { get; set; }
public int PostId { get; set; }
public string ControllerName { get; set; }
public int ReplyTo { get; set; }
public bool replied { get; set; }
public int UserProfileId { get; set; }
}
I am using dapper ORM. So this is the data access code that creates a join and maps it to the join table written above.
public IEnumerable<CommentUserProfileJoin > GetComments(int postId, string controllerName, int replyTo)
{
IEnumerable<CommentUserProfileJoin> comments;
const string query = "Select c.[id], c.[CommentText], c.[Username], c.[Upvote], c.[Downvote], c.[InappropriateFlags], c.[PostId], c.[ControllerName], c.[ReplyTo], c.[replied], u.[id] as UserProfileId, u.displayname from Main.Comments c LEFT JOIN Profile.UserProfiles u on c.username = u.username where c.PostId = #postId and c.ControllerName = #contName and c.ReplyTo = #ReplyTo order by ID desc";
comments = conObj.Query<CommentUserProfileJoin>(query, new { postId = postId, contName = controllerName, ReplyTo = replyTo });
return comments;
}
so now i have the model for the join of two tables, i can use it in any view like this
#model IEnumerable<DataAccessLayer.Models.CommentUserProfileJoin>
Hope this helps you. Also, unintentionally, i may not have followed best practices. I will be glad if someone can notify them through comments. Thanks
I'm doing some experimental programming to get caught up with ASP MVC.
I created a project for buildings containing rooms. A very simple one to many relationship. I am trying to get scaffolding to work, and from older MVC examples it looks like this should just work. However, the BuildingId field in Rooms isn't mapping to the Building model - no select list in the view.
My models are:
namespace BuildingManagement.Models
{
public class Building
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Address { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string Province { get; set; }
public string PostalCode { get; set; }
[Display(Name = "Phone")]
[DataType(DataType.PhoneNumber)]
[Required]
public string PhoneMain { get; set; }
[Display(Name = "Contact")]
[Required]
public string ContactName { get; set; }
public string Description { get; set; }
public virtual ICollection<Room> Rooms { get; set; }
}
}
and
namespace BuildingManagement.Models
{
public class Room
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Type { get; set; }
public int BuildingId { get; set; }
}
}
I generated the controller with views using Entity Framework, it created the forms but not with the expected Building select list in the Room edit view. It displays an integer input field instead.
What am I missing?
You should change this:
public class Room
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Type { get; set; }
public int BuildingId { get; set; }
}
to
public class Room
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Type { get; set; }
[ForeignKey("ContainingBuilding")]
public int BuildingId { get; set; }
public virtual Building ContainingBuilding{ get; set;}
}
This way the scaffolding will generate a select list for the building.
public List<SelectListItem> CountryListItems {get; set;}
public int CountryId {get; set;}
sample model above
Model.CountryListItems= new List<SelectListItem>();
CountryListItems.Add(new SelectListItem
{
Text = "Albania",
Value = "1"
});
CountryListItems.Add(new SelectListItem
{
Text = "Bangladesh",
Value = "2",
Selected = true
});
CountryListItems.Add(new SelectListItem
{
Text = "Canada",
Value = "3"
});
The sample code above can be used in controller or other generator model class.
#Html.DropDownListFor(model => model.CountryId, model.CountryListItems, "-- Select Status --")
sample view block above.
In class I have this :
public class CustomerMvc
{
public int Id { get; set; }
[Required(ErrorMessage = "LastName mandatory.")]
public string LastName { get; set; }
[EmailValidation(ErrorMessage = "Email not valid.")]
public string Email { get; set; }
}
In another class, I have this :
public class CartMvc
{
public CustomerMvc Customer { get; set; }
[Required(ErrorMessage = "VAT mandatory.")]
public int VatId { get; set; }
}
A Save method int the controller, receive a model type CartMvc. The problem is, in this case, I don't want validate the property type CustomerMvc but only VatId.
Is there a way to bypass, in this case, the validation on CustomerMvc ? Other way ?
Thanks,
You could use a view model:
public class SaveCustomerMvcViewModel
{
public int Id { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
and then:
public class SaveCartMvcViewModel
{
public SaveCustomerMvcViewModel Customer { get; set; }
[Required(ErrorMessage = "VAT mandatory.")]
public int VatId { get; set; }
}
Now of course your Save controller action will take the appropriate view model as parameter:
[HttpPost]
public ActionResult Save(SaveCartMvcViewModel model)
{
...
}
And as a side remark, putting the [Required] attribute on a non-nullable integer property (your VatId property) hardly makes any sense because a non-nullable integer will always have a value. If you want to validate that the user actually entered some value you'd better use a nullable integer on your view model:
public class SaveCartMvcViewModel
{
public SaveCustomerMvcViewModel Customer { get; set; }
[Required(ErrorMessage = "VAT mandatory.")]
public int? VatId { get; set; }
}