I have following model classes, using VS 2017, EF and MVC 5.0
public class Album
{
public virtual int AlbumId { get; set; }
public virtual int GenreId { get; set; }
public virtual int ArtistId { get; set; }
public virtual string Title { get; set; }
public virtual decimal Price { get; set; }
public virtual string AlbumArtUrl { get; set; }
public virtual Genre Genre { get; set; }
public virtual Artist Artist { get; set; }
}
public class Genre
{
public virtual int GenreId { get; set; }
[Display(Name="Genre Name")]
public virtual string Name { get; set; }
public virtual string Description { get; set; }
public virtual List<Album> Albums { get; set; }
}
In the View, I have following code
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.AlbumId)
<div class="form-group">
#Html.LabelFor(model => model.GenreId, "GenreId", new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("GenreId", String.Empty)
#Html.ValidationMessageFor(model => model.GenreId)
</div>
</div>
When I run the code through VS, the view is displayed with GenreId with a dropdown list box. The dropdown includes a blank value , in addition to the values present in the table Genre.
When I select blank from the dropdown and click "save", an error message is displayed
GenreId field is required
I don't understand where the message is coming from.
In the model class Album, there is no Required annotation for the GenreId property. So how does ASP.NET MVC know to validate the GenreId?
Also, why is a blank value displayed in the dropdown list ?
public class Album
{
public virtual int AlbumId { get; set; }
public virtual int GenreId { get; set; }
public virtual int ArtistId { get; set; }
public virtual string Title { get; set; }
public virtual decimal Price { get; set; }
public virtual string AlbumArtUrl { get; set; }
public virtual Genre Genre { get; set; }
public virtual Artist Artist { get; set; }
}
According to your poco class GenreId have to be int value and can not be null.
if you write like this in the below, you generate non-required field.
public virtual Nullable<int> GenreId { get; set; }
Lastly, Razor and MVC can generate default error message if you use or etc.
#Html.ValidationMessageFor()
Note: You use string.empty in the second parameter. This parameter can set default value of Dropdown.
#Html.DropDownList(,string.empty)
Hva a nice coding ;)
Related
I have a asp mvc 5 project using entity framework code-first. I created the controllers and views with scaffolding. Although i have not specified in the model that the Due date be [Required] and the item in the table has a value of NOT NULL.
Yet I am still getting this message on the POST
The DueDate field is required.
The model is really basic
public class Project
{
public int ProjectId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public DateTime StartDate { get; set; }
public DateTime DueDate { get; set; }
public int ClientId { get; set; }
public virtual Client Client { get; set; }
}
}
This is a Datetime2 datatype using EditorFor
<div class="input-group">
#Html.EditorFor(model => model.DueDate, new { #class = "form-control datepicker" })
<div class="input-group-addon">
<i class="entypo-calendar"></i>
</div>
</div>
It is also using jquery bootstrap datepicker, Although i doubt these has any effect on this functionality. Really confused how this field is a required field yet it has not been set as such in any area of the solution or database.
That's normal. DateTime is a value type meaning that it will always require a value. The model metadeata provider in ASP.NET MVC automatically adds the required attribute to non-nullable data types. You could use a nullable DateTime:
public class Project
{
public int ProjectId { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public DateTime StartDate { get; set; }
public DateTime? DueDate { get; set; }
public int ClientId { get; set; }
public virtual Client Client { get; set; }
}
I have two model classes in one-to-one relationship:
class Person
{
public int PersonID { get; set; }
public int DetailPersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DetailPerson DetailPerson { get; set; }
}
class DetailPerson
{
public int DetailPersonID { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
}
and the code for the edit page view:
#using (Html.BeginForm())
{
#Html.HiddenFor(m => m.PersonID)
#Html.LabelFor(m => m.FirstName)
#Html.TextBoxFor(m => m.FirstName)
#Html.LabelFor(m => m.LastName)
#Html.TextBoxFor(m => m.LastName)
#Html.LabelFor(m => m.DetailPerson.Address)
#Html.TextBoxFor(m => m.DetailPerson.Address)
#Html.LabelFor(m => m.DetailPerson.PhoneNumber)
#Html.TextBoxFor(m => m.DetailPerson.PhoneNumber)
<input type="submit" value="Edit">
}
The EF scaffold uses this code to update data:
db.Entry(person).State = System.Data.EntityState.Modified;
db.saveChanges();
When I submit the edit form, I got an error like this:
A foreign key value cannot be inserted because a corresponding primary key value does not exist. [ Foreign key constraint name = FK_dbo.People_dbo.DetailPersons_DetailPersonID ]
But if I do this:
Person p = db.Persons.Find(person.PersonID);
p.DetailPerson = person.DetailPerson;
p.FirstName = person.FirstName;
p.LastName = person.LastName;
db.saveChanges();
update data success without error
I want to know why the first way causse an error,
when I set the breakpoint at the line containing EntityState.Modified,
but the foreign key value ( DetailPersonID ) is 0.
Then, I added #Html.HiddenFor(m => m.DetailPersonID) on the edit form.
I got another error:
A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.
I still update database on the other way,
I am just curious why the first way which is EF standart to update data got an error.
You shouldn't use two classes if there is a one-to-one relationship since EF will normalize the db into the corresponding form anyway. Combine your classes like this.
public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
}
if you must have separate classes (not recommended), do it like this:
public class Person
{
public int PersonID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int DetailPersonID { get; set; }
public virtual DetailPerson DetailPerson { get; set; }
}
public class DetailPerson
{
public int PersonID { get; set; }
public virtual Person Person { get; set; }
public int DetailPersonID { get; set; }
public string Address { get; set; }
public string PhoneNumber { get; set; }
}
Then when you retrieve your object, do it like this:
// include the detail when retrieving the parent
Person person = db.People.Include(p=>p.DetailPerson).Single(p=>p.PersonId == whateverIdYou Need);
// modify whatever you like
person.DetailPerson.Address = "my new address";
// then your previous statement will work
db.Entry(person).State = System.Data.EntityState.Modified;
db.saveChanges();
here is my model
namespace chPayroll.Models.CustInformations
{
public class CustContact
{
public int cId { get; set; }
public int cNoType { get; set; }
public string cNo1 { get; set; }
public string cNo2 { get; set; }
public string cNo3 { get; set; }
public List<CustContact> contact { get; set; }
}
}
here is my editorTemplates
#model chPayroll.Models.CustInformations.CustContact
#Html.TextBoxFor(model => model.cNo1)
#Html.TextBoxFor(model => model.cNo2)
#Html.TextBoxFor(model => model.cNo3)
I need to show three textbox for taking email,three text box for taking telephone no. in view. how can I add the items to the list contact defined in the model so that it shows like this
email:--textbox1----textbox2----textbox3--
telephone:--textbox1----textbox2----textbox3--
and sends value to the controller
actually I am trying to send my data in list named contact here ie inside list at
index 0-email1-email2-email3
index 1-tel1-tel2-tel3
#Sanjay: you have a strange construct in your view model:
public class CustContact
{
public List<CustContact> contact;
}
Even if it compiles and machine understands it, I wouldn't use it as it is - you trying to lift yourself from the ground by pulling your hair up :)
It should be defined something along these lines (following your naming conventions & logic):
public class CustContact // single
{
public int cId { get; set; }
public int cNoType { get; set; }
public string cNo1 { get; set; } // those are actual phones, emails etc data
public string cNo2 { get; set; }
public string cNo3 { get; set; }
}
public class CustContacts // plural
{
public List<CustContact> Contacts;
}
View:
#model CustContacts
#EditorFor(m => Model)
Editor template:
#model CustContact
#Html.EditorFor(m => m.cNo1)
#Html.EditorFor(m => m.cNo2)
#Html.EditorFor(m => m.cNo3)
For brevity, we don't deal here with annotations, decorations, error handling etc.
Hope this helps.
Based on the comment on the question, I would build the models as below
public class CustContact
{
public int cId { get; set; }
public int cNoType { get; set; }
public string cNo1 { get; set; }
public string cNo2 { get; set; }
public string cNo3 { get; set; }
}
public class Customer
{
public CustContact Email {get; set;}
public CustContact Telephone {get; set;}
}
then create an editor template for Customer and in that editor template have following logic
#Html.EditorFor(model => model.Email)
#Html.EditorFor(model => model.Telephone)
Hope this helps
I am new to asp.net and c#, I have been trying to duplicate and app done in php using MVC3, generating the code from the same database. I have a question about showing the detail records in my "Details" view.
namespace MvcApplication5.Models
{
[DataContract(IsReference = true)]
[KnownType(typeof(masterDomain))]
[KnownType(typeof(masterFIP))]
[KnownType(typeof(masterSFPF))]
[KnownType(typeof(rgCountiesServed))]
[KnownType(typeof(rgKeyword))]
[KnownType(typeof(rgServicesProvided))]
public partial class rgOrganization
{
public rgOrganization()
{
this.rgCountiesServeds = new HashSet<rgCountiesServed>();
this.rgKeywords = new HashSet<rgKeyword>();
this.rgServicesProvideds = new HashSet<rgServicesProvided>();
}
[DataMember]
public int orgID { get; set; }
[DataMember]
public string ORGANIZATION { get; set; }
[DataMember]
public string CONTACT_PERSON { get; set; }
[DataMember]
public string PHONE_NUMBER { get; set; }
[DataMember]
public string FAX_NUMBER { get; set; }
[DataMember]
public string EMAIL_ADDRESS { get; set; }
[DataMember]
public string WEBSITE { get; set; }
[DataMember]
public string STREET_1 { get; set; }
[DataMember]
public string STREET_2 { get; set; }
[DataMember]
public string CITY { get; set; }
[DataMember]
public string ZIP_CODE { get; set; }
[DataMember]
public string COUNTY { get; set; }
[DataMember]
public string FIPS { get; set; }
[DataMember]
public string MAILING_ADDRESS { get; set; }
[DataMember]
public Nullable<int> SFPF { get; set; }
[DataMember]
public Nullable<int> DOMAIN { get; set; }
[DataMember]
public virtual masterDomain masterDomain { get; set; }
[DataMember]
public virtual masterFIP masterFIP { get; set; }
[DataMember]
public virtual masterSFPF masterSFPF { get; set; }
[DataMember]
public virtual ICollection<rgCountiesServed> rgCountiesServeds { get; set; }
[DataMember]
public virtual ICollection<rgKeyword> rgKeywords { get; set; }
[DataMember]
public virtual ICollection<rgServicesProvided> rgServicesProvideds { get; set; }
}
View Code
#model MvcApplication5.Models.rgOrganization
#{
ViewBag.Title = #Html.DisplayFor(model => model.ORGANIZATION);
}
#section Scripts {
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false"></script>
}
<h2>#Html.DisplayFor(model => model.ORGANIZATION)</h2>
<h3><span id="mailing_address">
#Html.DisplayFor(model => model.MAILING_ADDRESS)
</span></h3>
<fieldset>
<legend> #Html.DisplayFor(model => model.COUNTY) COUNTY</legend>
<div class="display-field">
<strong>#Html.DisplayFor(model => model.ORGANIZATION)</strong>
</div>
<div class="display-field">
#Html.DisplayFor(model => model.CONTACT_PERSON)
</div>
<!-- would like to display services provided here -->
</fieldset>
My question is how do I access the 'rgCountiesServeds'and 'rgServicesProvideds' via Razor?
They appear to be members of your model.
So you can access the collection as
model.rgServicesProvided
To iterate through the collection, do something like this:
#foreach (var serv in model.ServicesProvided) {
Service is #serv.ToString()<br/>
}
Replace serv.ToString() with whatever property you want to display.
If I understand what you're asking, you can access the rgCountiedServeds and rgServicesProvideds just like the other properties of rgOrganization. They are collections and properties of your model so you can loop over them in the View or create a drop down list for each of those properties. I.e.,
#Html.DropDownList("DropDownCounties", Model.rgCountiesServeds)
My model classes are:
public class User
{
public User()
{
Polls = new List<Poll>();
}
public int Id { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
ICollection<Poll> Polls { get; set; }
}
public class Poll
{
public int Id { get; set; }
public int PositiveCount { get; set; }
public int NegativeCount { get; set; }
public String Description { get; set; }
public User User { get; set; }
}
public class PollsContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Poll> Polls { get; set; }
}
EF created a table User_Id column for Polls table.
In the Create view of the Poll, I want to specify the UserId for new poll belongs too, but intellisense shows there is no access to model.UserId, there is a model.User.Id, which is not allowing me create a Poll for existing user and rather creates new User with new Id and no association is created.
<div class="editor-label">
#Html.LabelFor(model => model.User.Id)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.User.Id)
#Html.ValidationMessageFor(model => model.User.Id)
</div>
What is the right way of creating a new Poll for an existing User then ?
public class Poll
{
public int Id { get; set; }
public int PositiveCount { get; set; }
public int NegativeCount { get; set; }
public String Description { get; set; }
public int UserId { get; set; }
public User User { get; set; }
}
I think your Poll class should look like:
public class Poll
{
public int Id { get; set; }
public int PositiveCount { get; set; }
public int NegativeCount { get; set; }
public String Description { get; set; }
public int User_Id { get; set; }
public User User { get; set; }
}
If you have a column in your Poll table User_Id, then your model should also have this column. You can then just assign a User_Id to a Poll and Entity Framework will take care of the correct linking to the right User object.
Further, consider making your association properties (Poll.User and User.Polls) virtual in order to use the lazy loading mechanisms of Entity Framework.
See this