question

JonJacobs-9073 avatar image
0 Votes"
JonJacobs-9073 asked YijingSun-MSFT commented

How do I Code the DropDownList in my View

I can't figure out how to implement the list in the Search Input Page view
Here are the relevant models:
[Table("WordSearch")]
public class WordSearch
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }

         [MaxLength(80)]
         [DisplayName("Exact Phrase")]
         public string ExactPhrase { get; set; }
    
         [MaxLength(80)]
         [DisplayName("Required Words")]
         public string RequiredWords { get; set; }
    
         [MaxLength(80)]
         [DisplayName("Alternate Words")]
         public string AlternateWords { get; set; }
    
         [NotMapped]        
         public int RangeId { get; set; }
    
         [DisplayName("Range of Books")]
         public ICollection<BibleBooks> Range { get; set; }
     }//class WordSearch
        
     [Table("BibleBooks")]
     public class BibleBooks
     {
         [Key]
         [Required]
         public int ID { get; set; }
    
         [MaxLength(20)]
         public string Name { get; set; }
    
         [DisplayName("OT-NT")]
         public string Kind { get; set; }
    
         public int Chapters { get; set; }
    
         [MaxLength(4)]
         public string Abbr { get; set; }
    
         //maps to a 1-record dummy table
         public int WordSearch_Id { get; set; }
     }//class BibleBooks
    
 (in the IdentityModels.cs file)
     public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
     {
         public DbSet<BibleStudy> BibleStudy { get; set; }
         public DbSet<Book> Book { get; set; }
         public DbSet<BibleBooks> BibleBooks { get; set; }
         public DbSet<WordSearch> WordSearches { get; set; }
    
         public ApplicationDbContext()
             : base("DefaultConnection", throwIfV1Schema: false)
         {
         }
    
         public static ApplicationDbContext Create()
         {
             return new ApplicationDbContext();
         }
    
     }

Here is the start of the view:

 @model JQJ.Models.WordSearch
    
 @{    
     ViewBag.Title = "Search Page";
 }
    
 <h2>Search Input Page</h2>
    
 @using (Html.BeginForm())
 {
     @Html.AntiForgeryToken()
    
     <div class="form-horizontal">
         <h4>Word Search</h4>
 ...

Here is where I'm stuck:

         <div class="form-group">
             @Html.LabelFor(model => model.Range, htmlAttributes: new { @class = "control-label col-md-2" })
             @Html.DropDownListFor(model => Model.Range,
             @* or @Html.DropDownList( ?? *@
         </div>

How do I finish that code for DropDownListFor or DropDownList ?
Thank you,

dotnet-aspnet-mvc
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

YijingSun-MSFT avatar image
1 Vote"
YijingSun-MSFT answered YijingSun-MSFT commented

Hi @JonJacobs-9073 ,
The format is:

 @Help.DropDownFor(string, IEnumerable, string, object)

There are two ways:
First,if you have no classes,you could directly add to the view.Just like this:

 @Html.DropDownListFor(model => model.Range,                
                   new List<SelectListItem> { 
                        new SelectListItem { Value = "0" , Text = "Range1" },
                        new SelectListItem { Value = "1" , Text = "Range2" },
                        new SelectListItem { Value = "2" , Text = "Range3" }
                     },
                   new { @class="myselect"})

Second,it fills from db context
In the controller:

 MyViewModel model = new MyViewModel();
 // Select the data to display (lots of ways to do this)
 var states= from s in dbcontext.Range
                  where s.SomeProperty == someValue // if you want to filer the results
                  select s
 // Assign select list (this sets the value to the ID property and the display text to the Name property)
 model.StateList = new SelectList(states, "ID", "Name");
 // and if you want to set a default
 model.StateID = "NY";
 return View(model);

In the View:

 @Html.DropDownListFor(m => m.StateID, Model.StateList)

Best regards,
Yijing Sun


If the answer is helpful, please click "Accept Answer" and upvote it.

Note: Please follow the steps in our  documentation  to enable e-mail notifications if you want to receive the related email notification for this thread.

· 2
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I changed the Range property in the WordSearch model to:
public IEnumerable<string> Range { get; set; }

I added a new DbSet to IdentityModels:
public DbSet<WordSearchViewModel> Range { get; set; }

I put this into the WordSearchController:
wordSearch.Range = (IEnumerable<string>)(from RangeVariable in db.Range
select RangeVariable);
I added this viewmodel:
public class WordSearchViewModel
{
[Key]
public IEnumerable<string> Range { get; set; }
}//class WordSearchViewModel
But when I run it I get:
JQJ.Models.WordSearchViewModel: : EntityType 'WordSearchViewModel' has no key defined.
But it Does have a key defined.

What is happening?

0 Votes 0 ·

Hi @JonJacobs-9073 ,
As far as I think,complex types can not be key. IEnumerable can't be the key.
You could refer to below this article:
https://stackoverflow.com/questions/32575446/entitytype-has-no-key-defined-error-despite-defining-key
Best regards,
Yijing Sun

0 Votes 0 ·
JonJacobs-9073 avatar image
0 Votes"
JonJacobs-9073 answered

Thank you, @YijingSun-MSFT, that looks like the right direction. The main thing I see is that I need some supporting code in the WordSearchController. It will be a SQL query from the BibleBooks table, something like Select Name From BibleBooks. I want all 69 rows from that table, but only the Name column. I will code from your answer and let you know if I have need more help.

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

DuaneArnold-0443 avatar image
0 Votes"
DuaneArnold-0443 answered

You should understand the models used in MVC, particularly the different purposes between the viewmodel and the EF persistence model.

https://deviq.com/terms/kinds-of-models

https://www.dotnettricks.com/learn/mvc/understanding-viewmodel-in-aspnet-mvc

You should understand SoC in MVC.

https://en.wikipedia.org/wiki/Separation_of_concerns
https://www.c-sharpcorner.com/UploadFile/56fb14/understanding-separation-of-concern-and-Asp-Net-mvc/

You should understand the 'Understanding Models' topic in the link.

https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions-1/overview/understanding-models-views-and-controllers-cs

VM = viewmodel and DM = domain model the DM should be where EF logic is used to populate a viewmodel, and in turn EF model is populated from the VM for data persistence or whatnot, keeping the controller thin and void of such logic.

You can look into the PayrollVM looking a AuthorTypes that is used in
@Html.DropDownListFor(m => m.AuthorTypeId, Model.AuthorTypes, "Select....") in Create.cshtml using Payrollcontroller, the DM used by the controller, the VM used my the view and how the VM is returned to the controller's action method in Github example solution.

You should look into using an IoC and using dependency inject.

https://github.com/darnold924/PublishingCompany

HTH

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.