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
Related
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 ;)
I am new in MVC. I have tried to read online articles about how to use display template in collection.
This is my Model
public class InsuranceListViewModel
{
public IList<InsuranceViewModel> InsuranceViewModelList { get; set; }
public InsuranceViewModel InsuranceViewModel { get; set; }
public List<InsuranceSummaryViewModel> InsuranceSummaryViewModelList { get; set; }
}
SummaryViewModel
public class InsuranceSummaryViewModel
{
public string FriendlyName { get; set; }
public int InsuranceId { get; set; }
public string GroupId { get; set; }
public string MemberId { get; set; }
public Nullable<System.DateTime> PolicyStartDate { get; set; }
public Nullable<System.DateTime> PolicyEndDate { get; set; }
}
InsurnaceDisplay.cshtml
#model P2PExchange.MVC.Web.Areas.Patient.Models.InsuranceSummaryViewModel
#Html.DisplayFor(x => x.InsuranceId)
#Html.DisplayFor(x => x.FriendlyName)
#Html.DisplayFor(x => x.GroupId)
#Html.DisplayFor(x => x.MemberId)
#Html.DisplayFor(x => x.PolicyStartDate)
#Html.DisplayFor(x => x.PolicyEndDate)
_Insurance.cshml
#model Models.InsuranceListViewModel
#Html.DisplayFor(x=>x.InsuranceSummaryViewModelList)
My above code it only displays insurance friendly name not all fields from display template.
Can someone please help/guide me how Can I display correct data on UI?
Your DisplayTemplate needs to be located in the /Views/Shared/DisplayTemplates or /Views/yourControllerName/DisplayTemplates folder and needs to be named to match the name of the class, i.e. InsuranceSummaryViewModel.cshtml
I am trying out Editor Template
My Model Class is
public class ResourceModel
{
public int ResourceId { get; set; }
public string ResourceName { get; set; }
public int CultureId { get; set; }
public string CultureName { get; set; }
public string Icon { get; set; }
public string Language { get; set; }
public int CulturalResourceId { get; set; }
public string ResourceValue { get; set; }
public int ResourceAreaId { get; set; }
public int ViewId { get; set; }
public string WebView { get; set; }
public int WebAreaId { get; set; }
public string AreaName { get; set; }
public string FinalResourceValue { get; set; }
public List<ResourceModel> ListResourceCulture { get; set; }
}
I have created a partial view for Editor Template and put that in a EditorTemplates folder inside Shared Folder with name ResourceModel.cshtml.The Following is my Editor Template
#model Mars.Model.ResourceModel
#{
Layout = null;
}
#Html.HiddenFor(m=>m.CultureId)
#Html.HiddenFor(m => m.CulturalResourceId)
#Html.DisplayFor(m => m.Language, new { #class="form-control"})
#Html.TextBoxFor(m => m.ResourceValue, new { #class="form-control"})
and I used #Html.EditorFor in the view page as
1.For the Create View
#Html.EditorFor(Model => Model.ListResourceCulture)
2.For the Edit View
#Html.EditorFor(Model => Model.ListResourceCulture)
These two views belong to same controller with different actions
The template works for the create page but the template doesn't works for the Edit page. The template does not get triggered.
I have a ViewModel as below:
public class CheckoutViewModel
{
public string ProductNumber { get; set; }
public string Name { get; set; }
public int Price { get; set; }
public Input UserInput;
public class Input
{
public string Email { get; set; }
public string Phone { get; set; }
}
}
And an action like this:
[HttpPost]
public ActionResult Index(CheckoutViewModel model)
{
// ...
return View();
}
And my model has bound as below:
#model GameUp.WebUI.ViewModels.CheckoutViewModel
#using (Html.BeginForm("Index", "Checkout", FormMethod.Post))
{
#Html.AntiForgeryToken()
<!-- some HTML -->
#Html.LabelFor(m => m.UserInput.Email)
#Html.TextBoxFor(m => m.UserInput.Email)
#Html.LabelFor(model => model.UserInput.Phone)
#Html.TextBoxFor(model => model.UserInput.Phone)
<button>Submit</button>
}
When I submit the form, the UserInput is null. I know ASP.NET MVC is able to bind nested types but in this code is not. Also I can get the Email and Phone values by:
var email = Request.Form["UserInput.Email"];
var phone = Request.Form["UserInput.Phone"];
Maybe I do something wrong! It's a simple model binding you can find everywhere in the web.
You forgot to put a setter in your UserInput, I don't think the setter is automatic. Anyway you can make it work by just putting a getter/setter in your UserInput and no need to do extra in your controller method:
public Input UserInput { get; set; }
Your complete model:
public class CheckoutViewModel
{
public string ProductNumber { get; set; }
public string Name { get; set; }
public int Price { get; set; }
public Input UserInput { get; set; }
public class Input
{
public string Email { get; set; }
public string Phone { 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();