Populating Drop Down Box with Db Data - c#

Have managed to get this working now. As expected it was simpler than I was making it. Hopefully this can save someone looking to do the same thing some time in the future. Have amended code below to the working code.
Thanks for the help all.
Partial View Returning the Drop Down:
#model Project.Models.Item
#Html.DropDownListFor(m=>m.CategoryId,new SelectList(ViewBag.CategoryList,"CategoryId","CategoryName"),"Select")
Controller:
[HttpGet]
public ActionResult Create()
{
ViewBag.CategoryList = db.Categorys.ToList();
ViewBag.DesignerList = db.Designers.ToList();
return View();
}
item Model:
public class Item
{
public Item()
{
this.Images = new List<Image>();
}
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[ScaffoldColumn(false)]
public int ItemId { get; set; }
public int CategoryId { get; set; }
public int DesignerId { get; set; }
public int ImageId { get; set; }
[Required(ErrorMessage="Please Enter the Items Name ")]
[StringLength(150,MinimumLength=2)]
public string ItemName { get; set; }
[Required(ErrorMessage = "Price Cannot be Negative ")]
[Range(0,999999.99)]
public decimal ItemPrice { get; set; }
[StringLength(1000,MinimumLength=2)]
public string ItemDescription { get; set; }
[Range(4,22)]
public int ItemSize { get; set; }
//Files Being Uploaded by the User
public HttpPostedFileBase[] Files { get; set; }
public virtual Category Category { get; set; }
public virtual Designer Designer { get; set; }
public virtual List<OrderDetail> OrderDetails { get; set; }
public virtual List<Image> Images { get; set; }
}
Category Model:
public class Category
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
[ScaffoldColumn(false)]
public int CategoryId { get; set; }
[Required(ErrorMessage="Must Supply a Category")]
[StringLength(250,MinimumLength=1)]
public string CategoryName { get; set; }
}

I don't know if I'm missing something in your code but I can't see any piece of code where you are populating the ViewBag.Categories collection.
In documentation second parameter is more about having Collection (IEnumerable) of SelectListItem objects than having SelectList collection of your entity objects. That is causing problem with populating the dropdown control.
Next thing that I noticed is that the first parameter (the expression) is selecting the Category object - I believe that is impossible to do with select list which stores only Value(Key) and the Text. You should use here integer property named like 'SelectedCategory'

check this code
it should be
#Html.DropDownListFor(model=>model.Category.CategoryName,ViewBag.Categories as SelectList,"-- Select Category--")
also in controller set ViewBag.Categories with your db values.

Related

Display specific field found by Id Entity Framework 6

I have thse two classes. The code works, I can add a Movie to an actor and viceversa.
However, on the frontend side I cannot display the Name of the entity I'm adding, I can only display the Id number.
If I use a DropDownListFor I can display the names of the actors but I can only save an actor through the Id field.
How do I make it so that I display only the actor name and still save it on the database?
public class Movie
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public int ActorId { get; set; }
[ForeignKey("ActorId")]
public ICollection<Actor> Actors { get; set; }
public int DirectorId { get; set; }
[ForeignKey("DirectorId")]
public Director Director { get; set; }
}
public class Actor
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int MovieId { get; set; }
[ForeignKey("MovieId")]
public ICollection<Movie> CreditedMovies { get; set; }
}
For your scenario you required view model with properties of DD as well.
MovieViewModel.cs
public class MovieViewModel
{
public Movie Movie{get;set;}
public List<SelectListItem> ActorDD {get;set;}
}
using above view model you will need to bind your DD like below
Controller
public ActionResult Home()
{
MovieViewModel model = new MovieViewModel();
model.ActorDD.Add(new SelectListItem { Text = "Actor1", Value = "1" });
model.ActorDD.Add(new SelectListItem { Text = "Actor2", Value = "2" });
model.ActorDD.Add(new SelectListItem { Text = "Actor3", Value = "3" });
return View(model);
}
Your view look like below.
Razor.cshtml
#Html.DropDownListFor(m=>m.Movie.ActorId, model.ActorDD)

How Do I Select an Object by Embedded Object Value 2 Levels Deep in C#?

I have an object that has an embedded list of objects, which itself has an embedded list of object, like so
namespace AppName.Models
{
[BindProperties]
public class WorkOrder
{
public string OrderNumber { get; set; }
public int FinishedGoodsToMake { get; set; }
public int Quantity { get; set; }
public List<FinishedGood> FinishedGoods { get; set; } = new List<FinishedGood>();
}
[BindProperties]
public class FinishedGood
{
public int ID { get; set; }
public string ProductCode { get; set; }
public List<RawMaterial> RawMaterials{ get; set; } = new List<RawMaterial>();
}
[BindProperties]
public class RawMaterial
{
public string ProductCode { get; set; }
public int Status { get; set; }
public string Description { get; set; }
}
}
In the RawMaterial object, the Status can have a value of 0, 1, 2 or 3. I need to process them grouped by this status. I think it would be easiest if I could just loop through statuses and select the object I need. So, let's say the work order has three FinishedGoods and each FinishedGood has four RawMaterials. I need to get a full WorkOrder object, with FinishedGoods and RawMaterials, only where RawMaterial.Status == 0. Is there any way to do this easily?
I could optionally map the object to iterate through each status also. Just looking for the easiest/ most elegant solution here. Thanks!

Entity Framework - Define Formular Template

I'm about to create an ASP.Net Web Application with MVC and EF for the following scenario:
Every month there are new people entering a department in our company. Until now we're using an Excel Spreadsheet to handle common "Workitems" such as granting filesystem permissions etc.
Now I want to handle those requests using a Webapplication but I'm stuck at creating the Model.
There are two different Requesttypes, "JoinRequest" and "ChangeRequest" for people joining the company and employees changing the department. For each request type there are different workitems defined. Those workitems should be displayed in the webapp when the corresponding request is selected. After the data is loaded the user has to enter the data for the workitems.
E.g.
[JoinRequest]
Add new Filesystem Access permission:
[ UNC Path ] [x] Read [ ] Read & Write
Here the user has to enter the UNC Path and the type of Accesslevel (R or RW).
For now I've got the following Model:
public abstract class DbItem {
[Key]
public int Id { get; set; }
public DateTime CreationDate { get; set; }
public DateTime? DeletionDate { get; set; }
public string CreatedBy { get; set; }
public string DeletedBy { get; set; }
public bool IsDeleted => DeletionDate != null;
}
public abstract class Request : DbItem {
public Department NewDepartment { get; set; }
public DateTime BeginDate { get; set; }
public DateTime? EndDate { get; set; }
public ContractType ContractType { get; set; }
public EmployeeType EmployeeType { get; set; }
public string Location { get; set; }
public string ContactUserId { get; set; }
[NotMapped]
public User Contact {
get {
if (!string.IsNullOrWhiteSpace(ContactUserId)) {
var userSearcher = new ActiveDirectoryUserSearcher();
return userSearcher.FindByUserID(ContactUserId);
}
return null;
}
}
public string Phonenumber { get; set; }
//public virtual List<RequestWorkItem> RequestWorkItems { get; set; }
public bool IsFinished { get; set; }
public abstract string GetRequestType();
}
public abstract class WorkItem : DbItem {
[Key]
[ForeignKey("Language")]
public int LanguageId { get; set; }
[NotMapped]
public virtual Language Language { get; set; }
public string WorkItemText { get; set; }
public virtual Category Category { get; set; }
}
public class JoinRequest : Request {
public Person Person { get; set; }
public override string GetRequestType() {
return "New";
}
}
public class FileSystemAccessWorkItem : AccessWorkItem {
public FileSystemAccessRight FileSystemAccessRight { get; set; }
public string FileSystemPath { get; set; }
}
So when a user visits the website a new request has to be created but for every request type a set of workitems has to be loaded from the database. Additionally for every workitem the data the user entered should be saved somehow.
I hope you understand what I'm looking for - If anything is unclear I'll do my best to explain it more precisely
Edit1:
When looking at my Models I think the only think I achived is defining my Requests (so e.g. a JoinRequest contains some specific WorkItems) but how can I achive that a user is able to use this "RequestTemplate" to create a new Request and fill in the data to the corresponding workitems. Do I need additional Models for that? Maybe an example?

View with multiple tables

I have two tables in my database that have similar data but not same.
I'd like to show these tables in the same view. Looking in internet the most suggested practice is to use a ViewModel class.
So... These are my class tables:
iCareIndoorAlert.cs
[Table("iCareIndoorAlerts")]
public class iCareIndoorAlert
{
[Key]
[DisplayName("ID Allarme iCare indoor")]
public long AlertID { get; set; }
[DisplayName("ID Messaggio")]
public long MessageID { get; set; }
public string UUID { get; set; }
public int MAG { get; set; }
public int MIN { get; set; }
[DisplayName("Distanza")]
public float Dist { get; set; }
[DisplayName("Data ora")]
public DateTime DateTime { get; set; }
public virtual HttpPop3 HttpPop3 { get; set; }
}
iCareOutdoorAlert.cs
[Table("iCareOutdoorAlerts")]
public class iCareOutdoorAlert
{
[Key]
[DisplayName("ID Allarme iCare outdoor")]
public long AlertID { get; set; }
[DisplayName("ID Messaggio")]
public long MessageID { get; set; }
[DisplayName("Latitudine")]
public float Lat { get; set; }
[DisplayName("Longitudine")]
public float Lon { get; set; }
[DisplayName("Accuracy")]
public float Acc { get; set; }
[DisplayName("Data ora")]
public DateTime DateTime { get; set; }
}
After I created a ViewModel folder with a iCareAlertViewModel.cs class:
public List<iCareIndoorAlert> iCareIndoorAlert { get; set; }
public List<iCareOutdoorAlert> iCareOutdoorAlert { get; set; }
And added there rows in the iCareEntities.cs:
public DbSet<iCareIndoorAlert> iCareIndoorAlerts { get; set; }
public DbSet<iCareOutdoorAlert> iCareOutdoorAlerts { get; set; }
public DbSet<iCareAlertViewModel> iCareAlertsViewModels { get; set; }
After I generated the iCareAlertController.cs and run the view Index.cshtml but I get the error "Key not found". So in the ViewModel I added a dummy variable with [Key] attribute and now a get an error that says that can't find the iCareAlertViewModel table...
What am I doing wrong?
Thank you
First, don't create a DbSet for your view model, that's not necessary. A view model is a POCO that sits between your data models (i.e. your entities) and your user interface.
What you probably need to do is define an interface that has the properties that are common to your two entities, so something like this:
public interface IAlert
{
long AlertID { get; set; }
long MessageID { get; set; }
//etc...
}
Now each entity can implement that interface:
public class iCareIndoorAlert : IAlert
{
//snip
}
Now your viewmodel:
public class AlertViewModel : IAlert
{
public long AlertID { get; set; }
public long MessageID { get; set; }
//snip
}
So your view will now be something like this:
#model IEnumerable<My.Assembly.AlertViewModel>
#foreach(var alert in Model)
{
#Html.DisplayFor(m => m.AlertID)
//etc
}
Finally you need something to map your entities to your view model, you can use a library like Automapper but manually, it's something like this (including the action method and return):
public ActionResult Index()
{
List<IAlert> alerts = GetOutdoorAlerts(); //for example
List<AlertViewModel> alertViewModels = alert
.Select(a => new AlertViewModel
{
AlertID = a.AlertID,
MessageID = a.MessageID,
//etc...
});
return View(alertViewModels);
}

Accessing Navigation Properties in a View

I have a Controller action the receives 2 URL parameters, which are foreign keys for the data model:
public ActionResult Create(SurveyResponseModel surveyresponsemodel, int MemberId, int ProgramId)
{
surveyresponsemodel.MemberId = MemberId;
surveyresponsemodel.ProgramId = ProgramId;
return View(surveyresponsemodel);
}
Here is the data model:
public class SurveyResponseModel
{
[Key]
public int ResponseId { get; set; }
public int MemberId { get; set; }
public int ProgramId { get; set; }
// "If yes, what changes did you make? Mark all that apply."
[DisplayName("Did you make any changes in your practice, research, or administration activities as a result of participating in this CME activity?")]
public string CmeChanges { get; set; }
[DisplayName("Better patient follow-up")]
public bool PatientFollowUp { get; set; }
public virtual SurveyProgramModel SurveyProgramModel { get; set; }
public virtual PersonModel PersonModel { get; set; }
And the Data Model for "SurveyProgramType"
public class SurveyProgramModel
{
[Key]
public int ProgramId { get; set; }
public int ProgramYear { get; set; }
public int ProgramStatusId { get; set; }
public string ProgramTitle { get; set; }
public int ProgramTypeId { get; set; }
public virtual SurveyProgramTypeModel ProgramType { get; set; }
public virtual ProgramStatusModel ProgramStatusModel { get; set; }
}
What I want to be able to do in my view, is retrieve the ProgramTitle by the URL parameter that is passed for ProgramId. So the view looks something like:
<div class="editor-label">
#Model.SurveyProgramModel.ProgramTitle
</div>
However, #Model.SurveyProgramModel.ProgramTitle is throwing an exception because it is null. I'm thinking I have my navigation property set up incorrectly. Any idea what that is?
Shouldn't you return your view model to the view?
public ActionResult Create(
SurveyResponseModel surveyresponsemodel) //, int MemberId, int ProgramId)
{
// MemberId and ProgramId arguments do not need to be defined
// They will be picked up my MVC model binder, since there are properties
// with the same name in SurveyResponseModel class
//surveyresponsemodel.MemberId = MemberId;
//surveyresponsemodel.ProgramId = ProgramId;
surveyresponsemodel.SurveyProgramModel = new SurveyProgramModel(); // new line
return View(surveyresponsemodel); // <- return your view model here
}
without passing the model to the view, you cant access the properties of the model in your view. thats the possible cause of the error.
public ~ActionResult PassModel(DemoModel _model, int id)
{
// your code goes here....
return View(_model); // pass the model to view ..so you can work on your model
}

Categories

Resources