Answered by:
Can some one point out why this viewmodel is not populating the Index View (entity frame works (willing to pay for a working view model solution via Paypal)

Question
-
User2130491911 posted
Here is the source codes it contains the database model The Viewmode The Controller The View And plenty confusion :)
At this point I am willing to play someone for a small solution showing a view model working just direct message me and we can talk it out for what I am looking to understand. I think the only way I can understand view models is to pay for the help
What I am happy about is that my fields are the same name that is in the view model
What I am unhappy about is that there is no data displaying in the Index view.
There are records in the Database (nd before any one gets mad that I have another post in the view model thread I posted this here because I did not want it to get lost and that I feel this is a different question)
Database Table using EF
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated from a template. // // Manual changes to this file may cause unexpected behavior in your application. // Manual changes to this file will be overwritten if the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ namespace CMS.Models { using System; using System.Collections.Generic; public partial class JD_JUDGE_MASTER_TBL { public int JD_REC_ID { get; set; } public string JD_ID_CODE { get; set; } public string JD_TYPE_DESCRIPTION { get; set; } } }
The View Model Class (some one in another thread said this is not a view model but did not give ANY reason why )
if this is not a view model some one please tell me why as in most of microsoft examples their view models look like what I have here
I think that user was trying to mess me up by play a joke on me
namespace CMS.ViewModelsClasses { public class JUDGE_MASTER_DETAILS_VM_CLASS //Class Name { public JD_JUDGE_MASTER_TBL VM_JUDGE_DETAILS { get; set; } //Field public JUDGE_MASTER_DETAILS_VM_CLASS() { } //C# Constructor //DATA ELEMENTS FROM TABLE [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public Nullable<int> JD_REC_ID { get; set; } [Key] [Required] public string JD_ID_CODE { get; set; } [DisplayName("JUDGE TYPE")] public string JD_TYPE_DESCRIPTION { get; set; } } }
The Controller
using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Linq; using System.Net; using System.Web; using System.Web.Mvc; using CMS.Models; using CMS.ViewModelsClasses; namespace CMS.Controllers { public class JDController : Controller { private CONTESTANTS_DB_Entities db = new CONTESTANTS_DB_Entities(); // GET: JD public ActionResult Index() { List<JUDGE_MASTER_DETAILS_VM_CLASS> JDVM_LIST = new List<JUDGE_MASTER_DETAILS_VM_CLASS>(); //Holds List Of Judges return View(JDVM_LIST.ToList()); //return View(db.JD_JUDGE_MASTER_TBL.ToList()); } // GET: JD/Details/5 public ActionResult Details(string id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } JD_JUDGE_MASTER_TBL jD_JUDGE_MASTER_TBL = db.JD_JUDGE_MASTER_TBL.Find(id); if (jD_JUDGE_MASTER_TBL == null) { return HttpNotFound(); } return View(jD_JUDGE_MASTER_TBL); } // GET: JD/Create public ActionResult Create() { return View(); } // POST: JD/Create // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public ActionResult Create([Bind(Include = "JD_REC_ID,JD_ID_CODE,JD_TYPE_DESCRIPTION")] JD_JUDGE_MASTER_TBL jD_JUDGE_MASTER_TBL) { if (ModelState.IsValid) { db.JD_JUDGE_MASTER_TBL.Add(jD_JUDGE_MASTER_TBL); db.SaveChanges(); return RedirectToAction("Index"); } return View(jD_JUDGE_MASTER_TBL); } // GET: JD/Edit/5 public ActionResult Edit(string id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } JD_JUDGE_MASTER_TBL jD_JUDGE_MASTER_TBL = db.JD_JUDGE_MASTER_TBL.Find(id); if (jD_JUDGE_MASTER_TBL == null) { return HttpNotFound(); } return View(jD_JUDGE_MASTER_TBL); } // POST: JD/Edit/5 // To protect from overposting attacks, please enable the specific properties you want to bind to, for // more details see https://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] public ActionResult Edit([Bind(Include = "JD_REC_ID,JD_ID_CODE,JD_TYPE_DESCRIPTION")] JD_JUDGE_MASTER_TBL jD_JUDGE_MASTER_TBL) { if (ModelState.IsValid) { db.Entry(jD_JUDGE_MASTER_TBL).State = EntityState.Modified; db.SaveChanges(); return RedirectToAction("Index"); } return View(jD_JUDGE_MASTER_TBL); } // GET: JD/Delete/5 public ActionResult Delete(string id) { if (id == null) { return new HttpStatusCodeResult(HttpStatusCode.BadRequest); } JD_JUDGE_MASTER_TBL jD_JUDGE_MASTER_TBL = db.JD_JUDGE_MASTER_TBL.Find(id); if (jD_JUDGE_MASTER_TBL == null) { return HttpNotFound(); } return View(jD_JUDGE_MASTER_TBL); } // POST: JD/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public ActionResult DeleteConfirmed(string id) { JD_JUDGE_MASTER_TBL jD_JUDGE_MASTER_TBL = db.JD_JUDGE_MASTER_TBL.Find(id); db.JD_JUDGE_MASTER_TBL.Remove(jD_JUDGE_MASTER_TBL); db.SaveChanges(); return RedirectToAction("Index"); } protected override void Dispose(bool disposing) { if (disposing) { db.Dispose(); } base.Dispose(disposing); } } }
This piece here is what seems to allow it to work but does not populate the view model with table data
List<JUDGE_MASTER_DETAILS_VM_CLASS> JDVM_LIST = new List<JUDGE_MASTER_DETAILS_VM_CLASS>(); //Holds List Of Judges return View(JDVM_LIST.ToList());
The view
The Index view @*@model IEnumerable<CMS.Models.JD_JUDGE_MASTER_TBL>*@ @model IEnumerable<CMS.ViewModelsClasses.JUDGE_MASTER_DETAILS_VM_CLASS> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.JD_REC_ID) </th> <th> @Html.DisplayNameFor(model => model.JD_TYPE_DESCRIPTION) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.JD_REC_ID) </td> <td> @Html.DisplayFor(modelItem => item.JD_TYPE_DESCRIPTION) </td> <td> @Html.ActionLink("Edit", "Edit", new { id = item.JD_ID_CODE }) | @Html.ActionLink("Details", "Details", new { id = item.JD_ID_CODE }) | @Html.ActionLink("Delete", "Delete", new { id = item.JD_ID_CODE }) </td> </tr> } </table>
At this point f you have a pay pal account I will pay you for a working example
Just message me and we can talk out the details
@*@model IEnumerable<CMS.Models.JD_JUDGE_MASTER_TBL>*@ @model IEnumerable<CMS.ViewModelsClasses.JUDGE_MASTER_DETAILS_VM_CLASS> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.JD_REC_ID) </th> <th> @Html.DisplayNameFor(model => model.JD_TYPE_DESCRIPTION) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.JD_REC_ID) </td> <td> @Html.DisplayFor(modelItem => item.JD_TYPE_DESCRIPTION) </td> <td> @Html.ActionLink("Edit", "Edit", new { id = item.JD_ID_CODE }) | @Html.ActionLink("Details", "Details", new { id = item.JD_ID_CODE }) | @Html.ActionLink("Delete", "Delete", new { id = item.JD_ID_CODE }) </td> </tr> } </table>
Wednesday, September 9, 2020 2:21 AM
Answers
-
User-821857111 posted
What I am happy about is that my fields are the same name that is in the view modelThat would make me unhappy. The database field names look like they were created in the 1990s - lots of abbreviation, caps and underscores .Yuk. One of the primary purposes of the ViewModel is to create a class that holds the data for the view, but has property names that you actually want to appear in your UI.What I am unhappy about is that there is no data displaying in the Index view.You don't appear to make any database calls in your controller's Index method.You have your JD_JUDGE_MASTER_TBL entity class, which maps to a table named JD_JUDGE_MASTER_TBL. You want to display a list of them in the Index page. Your ViewModel should have a List property, and each item in the list should have properties that can be mapped to the properties in your entity class. But ideally, you want the property names in the ViewModel class to be human readable:
public class JudgeViewModel
{
public int Id {get;set;}
public int RecordId {get;set;}
public string Description {get;set;}
}
public JudgeMasterDetailsViewModel
{
public List<JudgeViewModel> Judges - new List<JudgeViewModel>();
}The @model declaration for the View should be
@model JudgeMasterDetailsViewModel
The Index method should call the db and project the data to the view model:
public ActionResult Index()
{
var model = new JudgeMasterDetailsViewModel
{
Judges = db.JD_JUDGE_MASTER_TBL.Select(x => new JudgeViewModel{ Id = x.JD_ID_CODE, RecordId = x.JD_REC_ID, Description = JD_TYPE_DESCRIPTION}).ToList()
};
return View(model);
}In your Index View, you access the data via the Model.Judges property:
@foreach (var item in Model.Judges) { <tr> <td> @Html.DisplayFor(modelItem => item.RecordId) </td> <td> @Html.DisplayFor(modelItem => item.Description) </td> <td> @Html.ActionLink("Edit", "Edit", new { id = item.Id }) | @Html.ActionLink("Details", "Details", new { id = item.Id}) | @Html.ActionLink("Delete", "Delete", new { id = item.Id }) </td> </tr> }
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, September 9, 2020 7:19 AM
All replies
-
User-821857111 posted
What I am happy about is that my fields are the same name that is in the view modelThat would make me unhappy. The database field names look like they were created in the 1990s - lots of abbreviation, caps and underscores .Yuk. One of the primary purposes of the ViewModel is to create a class that holds the data for the view, but has property names that you actually want to appear in your UI.What I am unhappy about is that there is no data displaying in the Index view.You don't appear to make any database calls in your controller's Index method.You have your JD_JUDGE_MASTER_TBL entity class, which maps to a table named JD_JUDGE_MASTER_TBL. You want to display a list of them in the Index page. Your ViewModel should have a List property, and each item in the list should have properties that can be mapped to the properties in your entity class. But ideally, you want the property names in the ViewModel class to be human readable:
public class JudgeViewModel
{
public int Id {get;set;}
public int RecordId {get;set;}
public string Description {get;set;}
}
public JudgeMasterDetailsViewModel
{
public List<JudgeViewModel> Judges - new List<JudgeViewModel>();
}The @model declaration for the View should be
@model JudgeMasterDetailsViewModel
The Index method should call the db and project the data to the view model:
public ActionResult Index()
{
var model = new JudgeMasterDetailsViewModel
{
Judges = db.JD_JUDGE_MASTER_TBL.Select(x => new JudgeViewModel{ Id = x.JD_ID_CODE, RecordId = x.JD_REC_ID, Description = JD_TYPE_DESCRIPTION}).ToList()
};
return View(model);
}In your Index View, you access the data via the Model.Judges property:
@foreach (var item in Model.Judges) { <tr> <td> @Html.DisplayFor(modelItem => item.RecordId) </td> <td> @Html.DisplayFor(modelItem => item.Description) </td> <td> @Html.ActionLink("Edit", "Edit", new { id = item.Id }) | @Html.ActionLink("Details", "Details", new { id = item.Id}) | @Html.ActionLink("Delete", "Delete", new { id = item.Id }) </td> </tr> }
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, September 9, 2020 7:19 AM -
User2130491911 posted
Update:
I think i have the data structure figured out.. it was not minus it was =
So I have this now and it compiles:
using CMS.Models; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel; namespace CMS.ViewModelsClasses { public class JUDGE_MASTER_VM_CLASS //Class Name { public class JUDGE_MASTER_VIEWMODEL { //public JD_JUDGE_MASTER_TBL VM_JUDGE_DETAILS { get; set; } //Field //public JUDGE_MASTER_DETAILS_VM_CLASS() { } //C# Constructor //DATA ELEMENTS FROM TABLE [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int JD_REC_ID { get; set; } [Key] [Required] public string JD_ID_CODE { get; set; } [DisplayName("JUDGE TYPE")] public string JD_TYPE_DESCRIPTION { get; set; } } public class JUDGE_MASTER_LIST_VIEWMODEL { public List<JUDGE_MASTER_VIEWMODEL> JUDGE_LIST = new List<JUDGE_MASTER_VIEWMODEL>(); } } }
Thanls
Many thank yous for the very detail explanation.
So this is interesting...
Judges = db.JD_JUDGE_MASTER_TBL.Select(x => new JudgeViewModel{ Id = x.JD_ID_CODE, RecordId = x.JD_REC_ID, Description = JD_TYPE_DESCRIPTION}).ToList()
So if the data base has 100's of fields that mean I would have to map them like you did here? There is no way to just do a select all with the so-called lambda option?
My issue with this view model thing was how you linked the database. So what I have 2 tables? So I have seen examples where they do joins in but I just don't see how that is workable if you have 5 tables in your sql database backend your lambda expression would be awfully complex correct? Can I use a Sql view (I know EF does not like Views because for some silly reason it can read the Identity field.
I will give this a try but I am still very confused how it all works but this post makes it better...
So this is your view model:
public class JudgeViewModel { public int Id {get;set;} public int RecordId {get;set;} public string Description {get;set;} } public JudgeMasterDetailsViewModel { public List<JudgeViewModel> Judges - new List<JudgeViewModel>(); }
Is this all in one Class file or are these 2 different Class files? I notice that there in no namespace stuff like you see in the microsoft examples that I have studied over the years.
Also as asked before...what if you had two tables? Do you put those view models into one file and then in the controller create the complex lambda expression with all the sql (linq sql)
Maybe a final clarity question what If I want to create a drop down list do I put a select list option into a view model file if its multiple view model files...
So for example a drop down List of Values (this just me down last time and I have to give up the project)
Would I make something like this (pseudo code so don't mind the syntax)
// for drop down list public class JudgeViewModel { public int Id {get;set;} public int RecordId {get;set;} public string Description {get;set;} } public JudgeMasterDetailsViewModel_SelectList { public SelectList<JudgeViewModel> Judges - new List<JudgeViewModel>(); }
Or can it all be in one view model file meaning if I needed a list and selectlist and needing the field name annotations I could do it all in one view model file for the judge table ?
As an example of the view model options in one file
public class JudgeViewModel { public int Id {get;set;} public int RecordId {get;set;} public string Description {get;set;} } public JudgeMasterDetailsViewModel { public List<JudgeViewModel> Judges - new List<JudgeViewModel>(); } //Same view model file with the selectlist in one file with 3 options public JudgeMasterDetailsViewModel_SelectList { public SelectList<JudgeViewModel> Judges - new List<JudgeViewModel>(); }
So can may items be in one view model?
Last question will each table have its own View Model File?
So in the controller if I had more than one view model file lets say my other table was called scores and it was related to the judges table
would my controller need to have a call to it as well as a call to the database as well?
Example
//Controller for more than one database table and more than one view model file. public ActionResult Index() { var model = new JudgeMasterDetailsViewModel var Model2 = new ScoresDetailsViewModel { Judges = db.JD_JUDGE_MASTER_TBL.Select(x => new JudgeViewModel{ Id = x.JD_ID_CODE, RecordId = x.JD_REC_ID, Description = JD_TYPE_DESCRIPTION}).ToList() Scores = db.SC_SCORES_MASTER_TBL.Select(s => new ScoresViewModels {id=......_).ToList() And then some how combine these model and Model2? }; return View(model); }
I guess some how I would have to find a way to combine the two model results?
So here is something I noticed in your source and it thew me for a loop
Judges = db.JD_JUDGE_MASTER_TBL.Select(x => new JudgeViewModel{ Id = x.JD_ID_CODE, RecordId = x.JD_REC_ID, Description = JD_TYPE_DESCRIPTION}).ToList()
the new JudgeViewModel part... you are making it a list here But I thought you had already made it a list in one of the view model files.
Can you share with me what it going on here.. you have this:
public class JudgeViewModel { public int Id {get;set;} public int RecordId {get;set;} public string Description {get;set;} } public JudgeMasterDetailsViewModel { public List<JudgeViewModel> Judges - new List<JudgeViewModel>(); }
But in the controller you have the following when you call out to the database
Judges = db.JD_JUDGE_MASTER_TBL.Select(x => new JudgeViewModel{ Id = x.JD_ID_CODE, RecordId = x.JD_REC_ID, Description = JD_TYPE_DESCRIPTION}).ToList()
It seems like you never use this:
public JudgeMasterDetailsViewModel { public List<JudgeViewModel> Judges - new List<JudgeViewModel>(); }
Why is the view model and why are you seemingly subtracting a list form a list? or am I reading this wrong?
Can you tell me what this structure represents?? this is very very very confusing
Its like you have the word list here but then in the controller you are making a list again??
Sorry for so may questions..but as I stated I am willing to pay for your time to get a working sample of this if it would be easier.
As I am really trying to understand this very confusing concept. Thanks SOOOOO much for all the help so far.
Wednesday, September 9, 2020 11:23 AM -
User2130491911 posted
Hello For some reason this part is not work for me
public ActionResult Index() { var model = new JudgeMasterDetailsViewModel { Judges = db.JD_JUDGE_MASTER_TBL.Select(x => new JudgeViewModel{ Id = x.JD_ID_CODE, RecordId = x.JD_REC_ID, Description = JD_TYPE_DESCRIPTION}).ToList() }; return View(model); }
I am not sure if I have the view model setup correctly as I get an error when I just us the word public and not public class in the view model like you have in your example and I am not sure were those 2 view models in two different classes or where they in the same file
So when it comes to populating the data I cannot render the fields that are in the view mode... even when I have them named the same way you named them ... any idea?
When I type this in as per your suggestion :
public JUDGE_MASTER_LIST_VIEWMODEL { public List<JUDGE_MASTER_VIEWMODEL> JUDGE_LIST = new List<JUDGE_MASTER_VIEWMODEL>(); }
I get an error...WHen I Add Class to it it compiles
So my view model looks like this I am assuming bot view models are suppose to be in one file?
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel; namespace CMS.ViewModelsClasses { public class JUDGE_MASTER_VM_CLASS //Class Name { public class JUDGE_MASTER_VIEWMODEL { //public JD_JUDGE_MASTER_TBL VM_JUDGE_DETAILS { get; set; } //Field //public JUDGE_MASTER_DETAILS_VM_CLASS() { } //C# Constructor //DATA ELEMENTS FROM TABLE //[DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int REC_ID{ get; set; } public string JD_CODE { get; set; } [DisplayName("JUDGE TYPE")] public string JD_TYPE { get; set; } public class JUDGE_MASTER_LIST_VIEWMODEL { public List<JUDGE_MASTER_VIEWMODEL> JUDGE_LIST = new List<JUDGE_MASTER_VIEWMODEL>(); } }
When I type model.(dot) it only shows JUDGE_LIST and not the field names...
Wednesday, September 9, 2020 6:05 PM -
User2130491911 posted
Hi There,
Let me ask this, so the way you have it above the for loop would repeat the field names over and over again so if I had lots of data rows the screen would be cluttered with field names rows as well as data field rows.
Is it safe to say with view models I am still at a point where I have to hard code the field names as there is no way to get them.
My Index view: Based on your amazing help;
@*@model IEnumerable<CMS.Models.JD_JUDGE_MASTER_TBL>*@ @model CMS.ViewModelsClasses.JUDGE_MASTER_LIST_VIEWMODEL @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @Html.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <th> @Html.DisplayNameFor(model => model.JUDGE_LIST.JD_REC_ID) </th> <th> @Html.DisplayNameFor(model => model.JD_TYPE_DESCRIPTION) </th> <th></th> </tr> @foreach (var item in Model.JUDGE_LIST) { <tr> <td> @Html.DisplayFor(modelItem => item.JD_CODE) </td> <td> @Html.DisplayFor(modelItem => item.JD_TYPE) </td> <td> @Html.ActionLink("Edit", "Edit", new { id = item.REC_ID}) | @Html.ActionLink("Details", "Details", new { id = item.REC_ID}) | @Html.ActionLink("Delete", "Delete", new { id = item.REC_ID}) </td> </tr> } </table>
So I get errors here...I am guessing this is a limitation of view models?
<th> @Html.DisplayNameFor(model => model.JUDGE_LIST.JUDGE_LIST.JD_REC_ID) </th> <th> @Html.DisplayNameFor(model => model.JD_TYPE_DESCRIPTION) </th> <th></th>
The model.(dot) options does not give me the ability to select the display name for field. Can some advise?
Wednesday, September 9, 2020 7:42 PM -
User2130491911 posted
Ok well I have been working on this all day and I am at my wits end...
Is there some easy way to make and view model for an Index view (which is a list ) that uses data annotation ???
I can't believe it's this difficult.
So I have the solution above working but I can display the data annotations so it does not work for the project.
When I make a view model and replace it in the view it telles me it needsan IEnumberable list which I am guessing the basic database table is that... so it confuses me that a viewmodel can just work in a index view like a table.
I think my only choice at this point is to go in the the model and make the annotation there and just make a copy on the hard drive of the file and replace after each update.
As stated before. I am willing to pay one of you for a working view model solution that reads from a database and puts values in an idex view a create view a delete view and an edit view with data annotations. Just name your price 3 digits is fine. meaning I'm play hundreds just to understand view models
Wednesday, September 9, 2020 9:27 PM -
User-474980206 posted
a view model is just an object passed to a view. the html helpers used in a view use data anotations to help with the rendering. there is nothing tricky about view models. the datatype the action passes to the view via
return View(model)
must match the model datatype in the view. this is no different than call any method. if so declarepublic void MyMethod(List<int> data) {}
you can not call it like:
MyMethod(1); // invalid datatype
a razor view the difference is that you use a directive to specify the model datatype rather than a parameter list.
you can use the entity models as view models, it just a bad practice. if you do not like the default data attributes or you codegen (which it looks like you do) you can use entity metadata to add you own custom data/validation attributes to the entity class
you really should learn C# better. It a typed language and requires types to match when used.
Wednesday, September 9, 2020 10:42 PM -
User2130491911 posted
Thanks I will look it to that.
I am not concerned with so called bad practices... what I want to know how to do is make the data annotations work and get a view model to work just like the tables do when you use the wizard to make the CRUD stuff.
I am pretty sure with me decorating the autogen code is horrible practice but it give me the outcome I want... the field names are on the screen and none of that dumb Ienum nonsense.
It blows my skull off my neck that the wizard can connect to the database and render it to screen yet attach a view model and boom some sort of weirdo IEnumerble message and nothing works...and then there does not appear to be a simple way to make that work.
I mean what if you have 50 fields to render to screen... you have Lambda all those bad boys in code ??
Which means every page you use that list you have to do that??? When the data annotation option is looking at you in the face???
It beggars belief!!
As stated At this point I will pay for the help if someone is willing.
Wednesday, September 9, 2020 11:00 PM -
User-821857111 posted
I don't think View Models are necessarily the problem for you. I think your lack of basic C# and programming knowledge is the issue, based on the questions you have asked.
Using code generation wizards is all well and good, but as soon as you want to do something that's even slightly complex, they fall down. You cannot use them to build anything even mildly complex i.e. any application that is likely to provide value to the owners or users. You have to understand what the wizards are producing, and in order to do that, you must learn the programming language.
You have to have an interest and an aptitude for this. If you don't have either of those, then you are heading for nothing but frustration. Programming is not easy. If it was, and people were able to develop complex applications using nothing but wizards, programmers would not be in such demand as they are.
Like Bruce said, you should really start by learning C# better - understand what a namespace is and what it is used for. How classes work and what they are used for. MVC is really, really hard for people who don't have a reasonable grasp of C# basics.
If you have money to spend and like videos, buy a Pluralsight subscription and do their C# course. Don't waste it on trying to get someone to teach you relatively advanced stuff when you don't know the basics. You need a foundation first.
I've just noticed - Pluralsight do a 10 days free offer.
Thursday, September 10, 2020 9:11 AM -
User2130491911 posted
Hi I have a subscription there and I got it just to understand view models and the vids were lacking as they do not connect to a data base. Like most demos the devs for what ever reason refuse to show that and seem to like to hard code data which fails to demo a real world situation.
My Solution was to put the data annotations in the wizard generated model. I have a copy of the changes stored in a text file. When I update the database those changes are erased but I can just copy and paste the changes back in. Its too bad that a view model does not work as easy as the actual model does.
So I was hoping view models would allow me to do it in one spot vs having to cut and paste a new file in every time we update the database via the wizard.
As I stated this is a part time thing I do here and the scope of what we need is very simple web front ends for sql back ends. that already exist. So I don't need any things that are complex.
You don't buy a jack hammer to hammer a nail into balsa wood do you? So what are you and Bruce even saying? Learn the complex things? I am trying to stay within scope of what I need to accomplish.
Based on the response.. I guess what I am asking to do cannot be done and sadly I guess I will have to live with that. I will keep searching and again.
Looking at your example you seem to know how to use view models, As I stated before I almost have your example working. It just does not do what I need it to do. I guess that makes me a bad programmer . :)
I would be willing to play you directly to get it working like I need it to work. 2 tables needing to have their data annotations flow into the views Index Edit Create and delete.
Thursday, September 10, 2020 3:53 PM -
User-821857111 posted
Back to your questions:
Yes, you will need to map values from your entities to the view model classes. You can do it manually like I have, or you can use a tool called Automapper. If you have "hundreds" of fields that need to go into the view, I suggest revisiting the design of your UI or your database.
If you want to retrieve joined data from more than one table, you design your viewmodel to represent the joined data. Think of it as a C# version of a database View. It's like a flattened version of the data that can also contain collections as needed.
I'm not surprised you couldn't get my code to work. It was illustrative only. Not a fully working example.
So you use your usual LINQ queries to get data, and then pour it into a ViewModel ("projection", it's know as) using similar syntax to what I posted.
Thursday, September 10, 2020 5:19 PM -
User2130491911 posted
Yes I saw automapper and that is way to complex for me.
I think we may be on different pages which may be the source of the confusion... so let me try yo clear it up with two files.
One is the auto generated code and the other is this so called view model
In the Auto generated code I have added these data annotations items
I am wanting to do the same thing is this so called view model .
So in the auto generated code the field names come over just as expected. When I do that with the so called view model. I get an error about IEnumberable. Which leads me to believe this is not doable.
Let me show:
Auto Code with the data annotation and it works a threat! No IEnum errors works as expected.
//------------------------------------------------------------------------------ // <auto-generated> // This code was generated from a template. // // Manual changes to this file may cause unexpected behavior in your application. // Manual changes to this file will be overwritten if the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ namespace CMS.Models { using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel; public partial class CM_CONTESTANTS_MASTER_DETAIL_TBL { public int MC_REC_ID { get; set; } [DisplayName("FIRST_NAME")] public string MC_CONTESTANT_FIRST_NAME { get; set; } [DisplayName("LAST_NAME")] public string MC_CONTESTANT_LAST_NAME { get; set; } [DisplayName("APP_DATE")] public Nullable<System.DateTime> MC_CONTESTANT_APPLICATION_DATE { get; set; }
In The So called view model I do the Same thing and blamo!! IEnum errors
using System.Web; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel; namespace CMS.ViewModelsClasses { public class CONTESTANT_MASTER_VIEWMODEL //Name of Class { //DATA ELEMENTS FROM TABLE [Key] [DisplayName("ID_CODE")] public int MCON_ID { get; set; } [DisplayName("FIRST_NAME)] public string MC_CONTESTANT_FIRST_NAME { get; set; } [DisplayName("LAST_NAME")] public string MC_CONTESTANT_LAST_NAME { get; set;
So the fact that I can assign fields in one file field names once time.. they can be used each time the model used. The wizards turn the that to a .ToList and all works as expected... view models... not so much....
So there is no where where you see code calling each field... it just calls the table. Your example as well as some other show you having to assign each item yet the wizard does not.
I would simply like to get those data annotations over on the view pages... no third party apps or addons no super complex bits of kit like auto mapper which is even more confusing then view models.
Is there a way to do this with a view model that is connected to or via a data base that already exist?
Thursday, September 10, 2020 5:46 PM