MVC 5 Complex View Model binding is not working - asp.net

public class CreateProjeModel
{
public Proje Proje { get; set; }
public List<GeometryModel> GeometryList { get; set; }
public CreateProjeModel()
{
Proje = new Proje();
GeometryList = new List<GeometryModel>();
}
}
public class GeometryModel
{
public List<PointModel> PointList { get; set; }
public GeometryModel()
{
PointList = new List<PointModel>();
}
}
public class PointModel
{
public int X { get; set; }
public int Y { get; set; }
}
public class Proje : EntityBase
{
public int FirmaId { get; set; }
public int IlId { get; set; }
public int? IlceId { get; set; }
public int PlanTurId { get; set; }
public int EtudTurId { get; set; }
public int EtudAmacId { get; set; }
public int DilimId { get; set; }
public string Aciklama { get; set; }
public virtual Firma Firma { get; set; }
public virtual IL Il { get; set; }
public virtual ILCE Ilce { get; set; }
public virtual PlanTur PlanTur { get; set; }
public virtual EtudTur EtudTur { get; set; }
public virtual EtudAmac EtudAmac { get; set; }
public virtual Dilim Dilim { get; set; }
}
I have a complex model named CreateProjeModel. I'm using 'for' to loop collection properties and binding like below:
#Html.TextBoxFor(m => m.GeometryList[i].PointList[j].X)
Action is like below:
[HttpPost]
public async Task<ActionResult> Create(CreateProjeModel proje)
{
//ToDo
return View(proje);
}
Posted data is below:
When it comes to action, GeometryList is empty and Proje's properties are not set to post values. Where am I doing wrong?

Your problem is that your CreateProjeModel model has a property named Proje, but the parameter of your Create() method is also named proje. Your need to change the method signature to (say)
public async Task<ActionResult> Create(CreateProjeModel model)
where the parameter name is not the same as the nae of one of your properties

Related

Trying to recreate a solution given for a question, need a little assistance

Trying to recreate a solution given for ASP.NET MVC - Taking search criteria as input, and displaying the results, in the same View?, but not sure where to find the querymanager that derloopkat uses in his example.
[HttpPost]
public ActionResult Query(FormQueryModel model)
{
var queryManager = new QueryManager(model);
model.QueryResults = queryManager.GetResults();
return View(model);
}
My ViewModels
public class PartRequestInfoSearch
{
public int? Building { get; set; }
public int? PartType { get; set; }
public int? PartStatus { get; set; }
public Nullable<System.DateTime> tmpStartDate { get; set; }
public Nullable<System.DateTime> tmpEndDate { get; set; }
public int PageSize { get; set; }
public List<RequestedPartInfo> RequestedPartInfos { get; set; }
public PartRequestInfoSearch()
{
this.RequestedPartInfos = new List<RequestedPartInfo>();
}
}
}
public class RequestedPartInfo
{
public int idPartRequest { get; set; }
public string Building { get; set; }
public string RequestNumber { get; set; }
public string PartNumber { get; set; }
public string VendorPartNumber { get; set; }
public string PartDescription { get; set; }
public int StockQTY { get; set; }
public int RequestQTY { get; set; }
public int ShippedQTY { get; set; }
public string PartStatus { get; set; }
}

EF core and creating a many to many table. Creates extra field. Why ?

Why is there a UserProgramRefProgramCharacteristics.RefProgramCharacteristicsId field??? There should only be 2 fields not 3. Right? Below are the 3 classes and the OnModelCreating that is needed to create a many to many table
public class RefProgramCharacteristic
{
public int Id { get; set; }
public string ProgramCharacteristic { get; set; }
public List<UserProgramRefProgramCharacteristic> UserProgramRefProgramCharacteristics { get; set; }
// public ICollection<UserProgram> userPrograms { get; } = new List<UserProgram>();
// public virtual ICollection<UserProgram> UserPrograms { get; set; }
}
public class UserProgram
{
public int Id { get; set; }
//UserProgramSaved
public bool MyList { get; set; }
public float MyPriorityRating { get; set; }
public int Similarity { get; set; }
public bool Compare { get; set; }
//UserProgramSimilarity
public int OverallSimilarityScore { get; set; }
public int DeltaProfileElement1_WorkExp { get; set; }
public int DeltaProfileElement2_VolExp { get; set; }
public int DeltaProfileElement3_ResExp { get; set; }
public int DeltaProfileElement4_Pubs { get; set; }
public int DeltaProfileElement5_Step1 { get; set; }
public int DeltaProfileElement6_Step2ck { get; set; }
public int DeltaProfileElement7_Aoa { get; set; }
public int DeltaProfileElement8_Nspecialties { get; set; }
public int DeltaProfileElement9_PercentApps { get; set; }
//UserComparisonSaved
// public RefProgramCharacteristic RefProgramCharacteristic { get; set; }
public string RefProgramCharacteristicList { get; set; }
public string ApplicationUserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public int MedicalProgramId { get; set; }
public RefProgramDetailData MedicalProgram { get; set; }
public List<UserProgramRefProgramCharacteristic> UserProgramRefProgramCharacteristics { get; set; }
// public ICollection<RefProgramCharacteristic> RefProgramCharacteristics { get; } = new List<RefProgramCharacteristic>();
// public virtual ICollection<RefProgramCharacteristic> RefProgramCharacteristics { get; set; }
}
public class UserProgramRefProgramCharacteristic
{
// public int Id { get; set; }
public int UserProgramId { get; set; }
public UserProgram UserProgram { get; set; }
public int RefProgramCharacteristicsId { get; set; }
public RefProgramCharacteristic RefProgramCharacteristic { get; set; }
}
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<UserProgramRefProgramCharacteristic>()
.HasKey(t => new { t.UserProgramId, t.RefProgramCharacteristicsId });
base.OnModelCreating(builder);
}
Why is there a UserProgramRefProgramCharacteristics.RefProgramCharacteristicsId field?
Because you are telling EF Core to create such field here:
public int RefProgramCharacteristicsId { get; set; }
// ^
While the navigation property is called RefProgramCharacteristic (no s). And by EF Core conventions:
If the dependent entity contains a property named <primary key property name>, <navigation property name><primary key property name>, or <principal entity name><primary key property name> then it will be configured as the foreign key.
RefProgramCharacteristicsId does not match any of these rules, so EF Core creates a shadow FK property with default name RefProgramCharacteristicId.
Either rename the property to RefProgramCharacteristicId (best), or map it explicitly using ForeignKey data annotation:
[ForeignKey(nameof(RefProgramCharacteristicsId))]
public RefProgramCharacteristic RefProgramCharacteristic { get; set; }
or
[ForeignKey(nameof(RefProgramCharacteristic))]
public int RefProgramCharacteristicsId { get; set; }
or using HasForeignKey fluent API:
builder.Entity<UserProgramRefProgramCharacteristic>()
.HasOne(e => e.RefProgramCharacteristic)
.WithMany(e => e.UserProgramRefProgramCharacteristics)
.HasForeignKey(e => e.RefProgramCharacteristicsId);

Non lazy loading

i have a model looks like this.
public class TradeModel
{
public int id { get; set; }
public BaseProductModel baseProduct { get; set; }
public string productDescription { get; set; }
public List<byte[]> images { get; set; }
public int price { get; set; }
// Date infos
public DateTime estimatedShippingDate { get; set; }
}
What i want to do is. when i call post request i want to send an id of an existing baseProduct not the entire baseProductForm and that being created.
ive tried
[Required]
public int baseProductId { get; set; }
[ForeignKey("baseProductId")]
public virtual BaseProductModel baseProduct { get; set; }
something like this, but seems to be not working.
any possible solutions?
Your model:
public class TradeModel
{
public int id { get; set; }
public int baseProductId { get; set; }
public virtual BaseProductModel baseProduct { get; set; }
public string productDescription { get; set; }
public List<byte[]> images { get; set; }
public int price { get; set; }
// Date infos
public DateTime estimatedShippingDate { get; set; }
}
Your ViewModel:
public class TradeViewModel
{
public int id { get; set; }
public int baseProductId { get; set; }
public string productDescription { get; set; }
public List<byte[]> images { get; set; }
public int price { get; set; }
// Date infos
public DateTime estimatedShippingDate { get; set; }
}
Now you can pass only the baseProductId:
public IActionResult(TradeViewModel model)
{
// Your form will contain only the id anyway so the method below should work.
// Replace that with your actual context
//dbcontext.Trades.Add(new TradeModel { ... });
}

Edit multiple related tables on ASP.net MVC w/Entity Framework 6

I'll open with the statement that I am very new to .net and MVC so please bear with me. I'm using Visual Studio 2013 and learning as I go.
Essentially - I have a .net MVC database-first project connected to a SQL db. I used scaffolding to create 4 models -
(Survey_Header_Response) - base survey information, identifies which survey a respondent gets
(Survey_Question) holds a unique list of the questions for all surveys and provides the actual question text,
(Survey_Response) lists of all the questions in the survey identified in (Survey_Response_Header) and will hold the value of each answer on post,
(Response_Values) - holds a list of possible responses for each of the different questions in each survey . Information on these is as follows:
Note - models are scaffolded, so even if I change them, they change back on db update.
Survey_Response_Header model:
public partial class Survey_Response
{
public Survey_Response()
{
this.Response_Values = new HashSet<Response_Values>();
}
public int Survey_Response_RecID { get; set; }
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public string Response { get; set; }
public Nullable<System.DateTime> Date_Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public bool Responded { get; set; }
public string Survey_Qtr { get; set; }
public System.Guid Respondent_ID { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual ICollection<Response_Values> Response_Values { get; set; }
public virtual Survey_Response_Header Survey_Response_Header { get; set; }
}
Survey_Question:
public partial class Survey_Question
{
public Survey_Question()
{
this.Survey_Cat_SubCat = new HashSet<Survey_Cat_SubCat>();
this.Survey_Detail = new HashSet<Survey_Detail>();
this.Response_Values = new HashSet<Response_Values>();
this.Survey_Response = new HashSet<Survey_Response>();
}
public int Survey_Question_RecID { get; set; }
public string Question { get; set; }
public bool Inactive_Flag { get; set; }
public System.DateTime Date_Created { get; set; }
public string Created_By { get; set; }
public System.DateTime Date_Updated { get; set; }
public string Updated_By { get; set; }
public virtual ICollection<Survey_Cat_SubCat> Survey_Cat_SubCat { get; set; }
public virtual ICollection<Survey_Detail> Survey_Detail { get; set; }
public virtual ICollection<Response_Values> Response_Values { get; set; }
public virtual ICollection<Survey_Response> Survey_Response { get; set; }
}
Survey Response:
public Survey_Response()
{
this.Response_Values = new HashSet<Response_Values>();
}
public int Survey_Response_RecID { get; set; }
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public string Response { get; set; }
public Nullable<System.DateTime> Date_Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public bool Responded { get; set; }
public string Survey_Qtr { get; set; }
public System.Guid Respondent_ID { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual ICollection<Response_Values> Response_Values { get; set; }
public virtual Survey_Response_Header Survey_Response_Header { get; set; }
}
Response_Values:
public partial class Response_Values
{
public Response_Values()
{
this.Survey_Response = new HashSet<Survey_Response>();
}
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public int Value { get; set; }
public int Question_Type_RecID { get; set; }
public string Value_Label { get; set; }
public Nullable<System.DateTime> Date_Created { get; set; }
public string Created_By { get; set; }
public Nullable<System.DateTime> Date_Updated { get; set; }
public string Updated_By { get; set; }
public int Response_Value_RecID { get; set; }
public virtual Question_Type Question_Type { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual Survey Survey { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual ICollection<Survey_Response> Survey_Response { get; set; }
}
}
There is a many-to-many relationship between the Response_Values & Survey_Response tables through the use of a pure-join table not shown here.
ViewModels: (See edit below)
ResponseData (intended to hold Survey_Response data and reference related tables)
I apologize for the length of this question - I'm new at this so my coding is probably messy and my explanation long. Any help provided is much appreciated and will help me learn!
Edit:
Thanks for your reply. I understand where you're coming from, and I've attempted to build the controller but when I try to populate the ResponseData viewModel that contains the ICollection Survey_Response with data, I get an error "Cannot implicitly convert type 'System.Collections.Generic.List CustomerExperienceSurveyWeb.Models.Survey_Response' to 'System.Collections.Generic.ICollection CustomerExperienceSurveyWeb.ViewModels.SurveyResponseVM'. An explicit conversion exists (are you missing a cast?)"
Here's the relevant part of my controller code:
public ActionResult Edit(Guid id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
//Survey_Response_Header survey = db.Survey_Response_Header.Find(id);
var survey = db.Survey_Response_Header
.Include(i => i.Survey_Response)
.Where(i => i.Responded_ID == id)
.Select(i => new
{
ViewModel = new ResponseData
{
Responded_ID = i.Responded_ID,
Company_RecID = i.Company_RecID,
Contact = i.Contact,
Contact_RecID = i.Contact_RecID,
Date_Responsed = i.Date_Responsed,
Date_Sent = i.Date_Sent,
Responded = i.Responded,
Survey_Qtr = i.Survey_Qtr,
Survey_RecID = i.Survey_RecID,
SurveyResponse = i.Survey_Response.ToList() <<--- This is where the error shows
}
})
.Single();
Updated ResponseData viewModel:
public partial class ResponseData
{
public ResponseData()
{
this.SurveyResponse = new List<SurveyResponseVM>();
}
public System.Guid Responded_ID { get; set; }
public int Survey_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public Nullable<System.DateTime> Date_Responsed { get; set; }
public bool Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public string Survey_Qtr { get; set; }
public virtual Contact Contact { get; set; }
public virtual ICollection<SurveyResponseVM> SurveyResponse { get; set; }
}
Referenced SurveyResponseVM viewModel which is throwing the error:
public partial class SurveyResponseVM
{
public SurveyResponseVM()
{
this.Response_Values = new List<ValueData>();
}
public int Survey_Response_RecID { get; set; }
public int Survey_RecID { get; set; }
public int Survey_Question_RecID { get; set; }
public string Response { get; set; }
public Nullable<System.DateTime> Date_Responded { get; set; }
public int Contact_RecID { get; set; }
public int Company_RecID { get; set; }
public System.DateTime Date_Sent { get; set; }
public bool Responded { get; set; }
public string Survey_Qtr { get; set; }
public System.Guid Respondent_ID { get; set; }
public virtual Survey_Detail Survey_Detail { get; set; }
public virtual Survey_Question Survey_Question { get; set; }
public virtual ICollection<ValueData> Response_Values { get; set; }
public virtual Survey_Response_Header Survey_Response_Header { get; set; }
}
I know this means I'm not populating the ICollection part of the viewmodel correctly but I can't seem to figure out how it's supposed to be done. I've done days of research on the internet and I either don't know the right question to ask or I'm completely missing it. Any help you can give me is VERY appreciated!
So the controller is essentially responsible for populating a model and pass this model to a view for rendering, there doesn't need to correspond to a database table.
The way I normally tackle this is to look at what the function is being performed, in this case survey and create a SurveyController. In here you will have a bunch of actions that correspond to views that are responsible for retrieving the correct data from the database, populating a model and then passing the model to the view for rendering.
So if you wanted to display a list of questions, you may do something like this (apologies if this contains errors, no VS atm):
public class SurveyController : Controller
{
public ActionResult Index()
{
var model = new SurveyModel(); // This would contain any properties, like questions and their valid responses
return View(model);
}
}
public class SurveyModel
{
public IList<SurveyQuestionModel> Questions { get; set; }
}

How to make single view using viewmodel in asp.net mvc 4?

I have different models Image,Page & PageCategories
public class Image
{
public int ImageId { get; set; }
public string ImageTitle { get; set; }
public string ImageURL { get; set; }
}
public class Page
{
public int PageId { get; set; }
public string PageTitle { get; set; }
public string Content { get; set; }
public int PageCategoryId { get; set; }
public virtual PageCategory PageCategory { get; set; }
}
public class PageCategory
{
public int PageCategoryId { get; set; }
public string CategoryName { get; set;
public virtual ICollection<Page> Pages { get; set; }
}
DBContext Class is
class DemoContext:DbContext
{
public DbSet<PageCategory> PageCategories { get; set; }
public DbSet<Page> Pages { get; set; }
public DbSet<Image> Images { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
I am wondering how to get all the model data to the home page using ViewModel.
For Ex.:
How to get image list and Page list in home page from multiple models?
You may want something like this :
viewModel :
//Create a viewModel with all the properties that you need
public class ViewModel
{
public int ImageId { get; set; }
public string ImageTitle { get; set; }
public string ImageURL { get; set; }
public int PageId { get; set; }
public string PageTitle { get; set; }
public string Content { get; set; }
public int PageCategoryId { get; set; }
public string CategoryName { get; set; }
}
Controller :
...
using (DemoContext db = new DemoContext()){
List<ImagePageViewModel> viewData = (from p in db.Page
join pc from db.PageCategory on p.PageCategoryId equals pc.PageCategoryId
select new ViewModel(){
PageTitle=p.PageTitle,
CategoryName = pc.CategoryName
//... set every property you want
})
}
return View(viewData );
note: I didn't add Image to the query because there is no explicit relation
between Image and the others table so i let you do it.
Create another class and define all above three into it. like below
public class MyView
{
public List<Image> Images { get; set; }
public List<Page> Pages { get; set; }
public List<PageCategory> PageCategories { get; set; }
}
Controller Action:-
public ActionResult Index()
{
MyView myView = // Get it using your logic
return View(myView);
}
finally got my answer:
public class ViewModelDemo
{
public IEnumerable<Image> images { get; set; }
public IEnumerable<Pages> pages { get; set; }
public IEnumerable<PageCategory> pagecategories { get; set; }
}
Then in HomeController
private DemoContext db=new DemoContext();
public ActionResult Index()
{
ViewModelDemo vm = new ViewModelDemo();
vm.images = db.Images.ToList();
vm.pages=db.Pagess.ToList();
vm.pagecategories=db.PageCategories.ToList();
return View(vm);
}

Resources