I have a model which holds some details about an account (Name, Id etc) and then it has a type called Transaction, which holds information about the currently selected account transaction. A transaction can then have many transaction lines. So I have a List<TransactionsLine> property.
I am trying to set the value of a Drop down list, using the model, the value being in the List<> property. At the moment, there can, and must, only be one item in the list.
#Html.DropDownListFor(x=>x.Transaction.TransactionLines[0].CategoryId, Model.TransactionReferences.Categories, new {#onchange="populateSubCategory()"})
However, when I run this, the list defaults to the first item in the list.
In debug mode, when I hover the mouse over x.Transaction.TransactionLines[0].CategoryId, it doesn't show me a value. But when hover over the collection, Model.TransactionReferences.Categories, I see it has a valid list. It just won't set the selected value.
Am I doing this wrong?
It works in other drop downs I use, BUT the select value is in the top most level of my model:
#Html.DropDownListFor(x => x.Transaction.ThirdPartyId, Model.TransactionReferences.ThirdParties, new { #class = "cmbThirdParty form-control", #onchange = "populateDefaults()" })
That one works fine.
Note, doing it manually, works:
<select class="form-control" id="cmbCategory" onchange="populateSubCategory()">
<option value="0">Select a One</option>
#foreach (var cat in Model.TransactionReferences.Categories)
{
//var selected = cat.Value == Model.Transaction.TransactionLines[0].CategoryId.ToString() ? "selected" : "";
<option value="#cat.Value">#cat.Text</option>
}
</select>
But doesn't feel like the best way to do it.
Model:
The main model passed to the view:
public class TransactionModel
{
public int BankAccountId { get; set; }
public string BankAccountName { get; set; }
public TransactionContainer Transaction { get; set; }
public TransactionReferenceModel TransactionReferences { get; set; }
public DateTime DefaultDate { get; set; }
}
The TransactionReferenceModel holds all my 'reference' data used to populate drop down lists:
public class TransactionReferenceModel
{
public List<SelectListItem> TransactionTypes { get; set; }
public List<SelectListItem> EntryTypes { get; set; }
public List<SelectListItem> SubCategories { get; set; }
public List<SelectListItem> Categories { get; set; }
public List<SelectListItem> ThirdParties { get; set; }
public List<SelectListItem> CostCentres { get; set; }
}
The TransactionContainer model holds allthe main details about the selected transaction:
public class TransactionContainer
{
public int Id { get; set; }
public int AccountId { get; set; }
public int TransactionTypeId { get; set; }
public string TransactionType { get; set; }
public int EntryTypeId { get; set; }
public string EntryType { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/dd/yyyy}")]
public DateTime TransactionDate { get; set; }
public string ThirdParty { get; set; }
public int ThirdPartyId { get; set; }
public string Account { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "C2")]
public decimal Amount { get; set; }
public string Notes { get; set; }
public string CategoryDisplay { get; set; }
public string CostCentreDisplay { get; set; }
public decimal RunningBalance { get; set; }
public List<TransactionLine> TransactionLines { get; set; }
}
That then holds a list of transaction lines that make up the transaction. The transaction line holds the property I am trying to set the drop down to, which is CategoryId:
public class TransactionLine
{
public int Id { get; set; }
public int TransactionId { get; set; }
public int? CostCentreId { get; set; }
public string CostCentre { get; set; }
public int SubCategoryId { get; set; }
public string SubCategory { get; set; }
public int CategoryId { get; set; }
public string Category { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "C2")]
public decimal Amount { get; set; }
public string Notes { get; set; }
}
And here is how I am populating my model and sending it to the view:
public ActionResult EditTransaction(int? transactionId, int? bankAccountId)
{
// Create the main view object
var model = new TransactionModel
{
Transaction = new TransactionContainer
{
TransactionLines = new List<TransactionLine>()
}
};
if (transactionId != null) // This is an Edit, as opposed to an Add
{
var item = new TransactionService(currentUserId).GetTransaction(transactionId.Value);
// Populate the Reference object used to populate drop downs.
model.TransactionReferences = PopulateReferenceDate(model.TransactionReferences, item.TransactionLines[0].SubCategoryId);
model.BankAccountId = item.AccountId;
model.BankAccountName = item.Account.FullName;
model.DefaultDate = Session["DefaultDate"] != null
? DateTime.Parse(Session["DefaultDate"].ToString())
: DateTime.UtcNow;
model.Transaction.AccountId = item.AccountId;
model.Transaction.Amount = item.Amount;
model.Transaction.TransactionLines.Add(new TransactionLine
{
Id = item.TransactionLines[0].Id,
CategoryId = item.TransactionLines[0].SubCategory.CategoryId,
CostCentreId = item.TransactionLines[0].CostCentreId,
Notes = item.TransactionLines[0].Notes,
Amount = item.TransactionLines[0].Amount,
SubCategoryId = item.TransactionLines[0].SubCategoryId,
TransactionId = model.Transaction.Id
});
model.Transaction.EntryTypeId = item.EntryTypeId;
model.Transaction.Id = transactionId.Value;
model.Transaction.Notes = item.Notes;
model.Transaction.ThirdPartyId = item.ThirdPartyId;
model.Transaction.TransactionDate = item.TransactionDate;
model.Transaction.TransactionTypeId = item.TransactionTypeId;
}
else
{
// Populate the bank account details
var bank = new BankAccountService(currentUserId).GetBankAccountById(bankAccountId.Value);
model.TransactionReferences = PopulateReferenceDate(model.TransactionReferences, null);
model.BankAccountId = bank.Id;
model.BankAccountName = bank.FullName;
model.Transaction.TransactionLines.Add(new TransactionLine
{
TransactionId = model.Transaction.Id // Link the transaction line to the transaction.
});
var transactionDate = Session["DefaultDate"] != null
? DateTime.Parse(Session["DefaultDate"].ToString())
: DateTime.UtcNow;
// Populate the object to hold the Transaction data, so that we can use it and return it in the view.
model.Transaction.TransactionDate = transactionDate;
}
return View(model);
}
I think you should use the SelectList Constructor in your view, in order to indicate the default value, like this:
#Html.DropDownListFor(
x => x.Transaction.TransactionsLines[0].CategoryId,
new SelectList(Model.TransactionReferences.Categories, "Value", "Text", Model.Transaction.TransactionsLines[0].CategoryId)
)
You are not restricted to use List< SelectListItem > for the collections. You can use a List of a specific class also.
This is the Controller Action Method code:
public class HomeController : Controller
{
public ActionResult Index()
{
var m = new AccountModel();
m.Transaction = new Transaction();
m.Transaction.TransactionsLines = new List<TransactionsLine>();
m.Transaction.TransactionsLines.Add(new TransactionsLine() { CategoryId = 2 });
m.TransactionReferences = new TransactionReferences();
m.TransactionReferences.Categories = new List<SelectListItem>()
{ new SelectListItem() { Text = "Cat1", Value = "1" },
new SelectListItem() { Text = "Cat2", Value = "2" },
new SelectListItem() { Text = "Cat3", Value = "3" }
};
return View(m);
}
}
Related
I have the following view model
public class PlanDetail
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
[DisplayFormat(DataFormatString = "{0:$#.##}")]
public decimal Price { get; set; }
public string FrequencyAbbreviatedName { get; set; }
[Display(Name = "Frequency")]
public string FrequencyName { get; set; }
[Display(Name = "Events")]
public int EventLimit { get; set; }
[Display(Name = "Help Center Access")]
public bool HelpCenterAccess { get; set; }
[Display(Name = "Email Support")]
public bool EmailSupport { get; set; }
[Display(Name = "Priority Email Support")]
public bool PriorityEmailSupport { get; set; }
[Display(Name = "Phone Support")]
public bool PhoneSupport { get; set; }
public bool Active { get; set; }
public string PictureUrl { get; set; }
public bool BestValue { get; set; }
}
I am using stripe.com products and prices.
In my mapping profile class, I am able to map to the basic properties (eg Id, Name, Description, Active).
Mapper.Map<Product,PlanDetail>();
I am not sure how to map the Metadata property (Dictionary<string,string>) or the Images property (List <string>) in the stripe product object to some of the PlanDetail properties.
I created the stripe products in my seed class, and added values to the Metadata and Image properties.
public static async Task SeedStripeAsync(string stripeKey)
{
StripeConfiguration.ApiKey = stripeKey;
var productService = new ProductService();
var priceService = new PriceService();
var products = await productService.ListAsync();
var productsData = System.IO.File.ReadAllText("../Infrastructure/Data/SeedData/stripe_products.json");
var productPlans = JsonSerializer.Deserialize<List<StripeProductSeed>>(productsData);
foreach (var item in productPlans)
{
if (!products.Any(x=> x.Name.Equals(item.Name, StringComparison.InvariantCultureIgnoreCase)))
{
var productOptions = new ProductCreateOptions
{
Name = item.Name,
Description = item.Description,
Active = item.Active,
Images = new List<string>(),
Metadata = new Dictionary<string, string>()
};
productOptions.Images.Add(item.PictureUrl);
productOptions.Metadata.Add("EventLimit", item.EventLimit.ToString());
productOptions.Metadata.Add("HelpCenterAccess", item.HelpCenterAccess.ToString());
productOptions.Metadata.Add("EmailSupport", item.EmailSupport.ToString());
productOptions.Metadata.Add("PriorityEmailSupport", item.PriorityEmailSupport.ToString());
productOptions.Metadata.Add("PhoneSupport", item.PhoneSupport.ToString());
productOptions.Metadata.Add("BestValue", item.BestValue.ToString());
var newProduct = await productService.CreateAsync(productOptions);
var priceOptions = new PriceCreateOptions
{
UnitAmountDecimal = item.Price,
Currency = "usd",
Recurring = new PriceRecurringOptions()
{
Interval = item.Interval,
IntervalCount = (long)item.IntervalCount
},
Product = newProduct.Id
};
await priceService.CreateAsync(priceOptions);
}
}
}
I would like to map the stripe Product Metadata properties such as EventLimit, HelpCenterAccess, EmailSupport, PriorityEmailSupport, PhoneSupport, and BestValue to their respective counterparts in the PlanDetail view model.
In addition, I would like to map the stripe Product Image property to the PictureUrl property in the PlanDetail view model.
Any ideas or suggestions how to use automapper for theses properties would be much appreciated.
Here's what I assume
// Just demo class
public class StripeProductSeed
{
public string PictureUrl { get; set; }
public int EventLimit { get; set; }
public bool HelpCenterAccess { get; set; }
public bool EmailSupport { get; set; }
public bool PriorityEmailSupport { get; set; }
public bool PhoneSupport { get; set; }
public bool BestValue { get; set; }
public List<string> ExtractImages() => new() { PictureUrl };
public Dictionary<string, string> ExtractMetaData() => new()
{
{nameof(EventLimit), EventLimit.ToString()},
{nameof(HelpCenterAccess), HelpCenterAccess.ToString()},
{nameof(EmailSupport), EmailSupport.ToString()},
{nameof(PriorityEmailSupport), PriorityEmailSupport.ToString()},
{nameof(PhoneSupport), PhoneSupport.ToString()},
{nameof(BestValue), BestValue.ToString()}
};
}
The map should be:
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<StripeProductSeed, PlanDetail>()
.ForMember(dst => dst.Images, x => x.MapFrom(src => src.ExtractImages()))
.ForMember(dst => dst.Metadata, x => x.MapFrom(src => src.ExtractMetaData()));
}
}
I have a LINQ query in my controller that has a join which selects all records. I'm then passing the ReportCompletionStatus.AsEnumerable() model to my view. But I keep getting the fowlling exceptions..
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery`1
but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1
I'm setting the model AsEnumerable() and my view is expecting #model IEnumerable so i'm still not sure why it's complaning...
Controller
var ReportCompletionStatus = from r in db.Report_Completion_Status
join rc in db.Report_Category
on r.Report_Category equals rc.ReportCategoryID
select new
{
r.Report_Num,
rc.ReportCategory,
r.Report_Sub_Category,
r.Report_Name,
r.Report_Owner,
r.Report_Link,
r.Report_Description,
r.Last_Published,
r.Previous_Published,
r.Published_By,
r.Previous_Published_By,
r.Last_Edited,
r.Edited_By
};
return View(ReportCompletionStatus.AsEnumerable());
Model
#model IEnumerable<WebReportingTool.Report_Completion_Status>
With your select new, you project to an anonymous type, not to an IEnumerable<WebReportingTool.Report_Completion_Status>
You need to create a ViewModel class (as your projection has data from both Report_Completion_Status and Report_Category) and use it for projection and for your View's model.
class
public class SomeViewModel {
public int ReportNum {get;set;}
public string ReportCategory {get;set;
//etc.
}
projection
select new SomeViewModel
{
ReportNum = r.Report_Num,
ReportCategory = rc.ReportCategory,
//etc.
};
view
#model IEnumerable<SomeViewModel>
By the way, the AsEnumerable is not necessary.
Here's how I got it to work.
Model
public class ReportCategoryListModel
{
public int Report_Num { get; set; }
public string ReportCategory { get; set; }
public string Report_Sub_Category { get; set; }
public string Report_Name { get; set; }
public string Report_Owner { get; set; }
public string Report_Link { get; set; }
public string Report_Description { get; set; }
public Nullable<System.DateTime> Last_Published { get; set; }
public Nullable<System.DateTime> Previous_Published { get; set; }
public Nullable<int> Published_By { get; set; }
public Nullable<int> Previous_Published_By { get; set; }
public Nullable<System.DateTime> Last_Edited { get; set; }
public Nullable<int> Edited_By { get; set; }
}
Controller
var ReportCompletionStatus = from r in db.Report_Completion_Status
join rc in db.Report_Category
on r.Report_Category equals rc.ReportCategoryID
select new ReportCategoryListModel
{
Report_Num = r.Report_Num,
ReportCategory = rc.ReportCategory,
Report_Sub_Category = r.Report_Sub_Category,
Report_Name = r.Report_Name,
Report_Owner = r.Report_Owner,
Report_Link = r.Report_Link,
Report_Description = r.Report_Description,
Last_Published = r.Last_Published,
Previous_Published= r.Previous_Published,
Published_By = r.Published_By,
Previous_Published_By = r.Previous_Published_By,
Last_Edited = r.Last_Edited,
Edited_By = r.Edited_By
};
return View(ReportCompletionStatus);
View
#model IEnumerable<WebReportingTool.Models.ReportCategoryListModel>
Model:
public class PublishedSongViewModel
{
public int Id { get; set; }
[Required(AllowEmptyStrings = false)]
public string SongName { get; set; }
//...
[Required]
public IEnumerable<string> Category { get; set; }
}
public class CategoryViewModel
{
public short Id { get; set; }
public string Title { get; set; }
public virtual ICollection<SongCategoryViewModel> SongCategory { get; set; }
}
public class SongCategoryViewModel
{
public int Id { get; set; }
[Required]
public int PublishedSongId { get; set; }
[Required]
public short CategoryId { get; set; }
}
View:
#model IList<PublishedSongViewModel>
#using (Html.BeginForm("PublishMusic", "Publish", FormMethod.Post, new { #enctype = "multipart/form-data", #id = "form-upload" }))
{
#Html.DropDownListFor(x => Model[i].Category, new SelectList(//Categories list here), new { #class = "form-control dl_Categories ", Multiple = "Multiple" })
}
Controller:
[HttpPost]
public ActionResult PublishMusic(IEnumerable<PublishedSongViewModel> songDetails)
{
if (songDetails != null)
{
IEnumerable<PublishedSongViewModel> savedSongs = (IEnumerable<PublishedSongViewModel>)(Session["UserSongs"]);
var lookupDetails = songDetails.ToDictionary(song => song.Id, song => song);
if (savedSongs != null)
{
foreach (var publishedSong in savedSongs)
{
var key = publishedSong.Id;
if (lookupDetails.ContainsKey(key))
{
var details = lookupDetails[key];
publishedSong.SongName = details.SongName;
}
db.SongCategories.Add(new SongCategoryViewModel { PublishedSongId = key, CategoryId = //categories id that user typed in on editorFor});
db.PublishedSongs.Add(publishedSong);
db.SaveChanges();
}
}
}
return View("Index");
}
I'v filled CategoryViewModel table up with data in my SQL.
1) How do I get the titles of CategoryViewModel and pass them in the SelectList(//Here) parameter in my viewmodel?
2) In the PublishMusic Action, how do I get the CategoryId for the SongCategoryViewModel from the one or more categories that the user selected from songDetails.Category?
I am not sure if I am on the right track with this. basically the categories are like tags, the user can select more than one. I'v also cut out unessential code to make easier to read.
I am trying to insert a product into my database with an associated category. One product can belong to several categories and obviously one category can have several products. When I insert, I am sure I am missing something in my controller method but I'm not sure what it is. I have a bridge table called ProductCategory that just has a ProductID and a CategoryID in it. That table is not getting populated when I do the insert.
Here is my controller method that is doing the insert:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditProduct([Bind(Include = "ID,itemNumber,product,description,active,PDFName,imageName,SelectedCategories")] ProductModel model)
{
if (ModelState.IsValid)
{
using (var context = new ProductContext())
{
context.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
if (model.ID == 0)
{
// Since it didn't have a ProductID, we assume this
// is a new Product
if (model.description == null || model.description.Trim() == "")
{
model.description = "Our Famous " + model.product;
}
if (model.imageName == null || model.imageName.Trim() == "")
{
model.imageName = model.itemNumber + ".jpg";
}
if (model.PDFName == null || model.PDFName.Trim() == "")
{
model.PDFName = model.itemNumber + ".pdf";
}
Session["dropdownID"] = model.ID;
// I think I probably need some additional code here...
context.Products.Add(model);
}
else
{
// Since EF doesn't know about this product (it was instantiated by
// the ModelBinder and not EF itself, we need to tell EF that the
// object exists and that it is a modified copy of an existing row
context.Entry(model).State = EntityState.Modified;
}
context.SaveChanges();
return RedirectToAction("ControlPanel");
}
}
return View(model);
}
And my Product model:
public class ProductModel
{
public int ID { get; set; }
[Required(ErrorMessage = "Required")]
[Index("ItemNumber", 1, IsUnique = true)]
[Display(Name = "Item #")]
public int itemNumber { get; set; }
[Required(ErrorMessage = "Required")]
[Display(Name = "Product")]
[MaxLength(50)]
public String product { get; set; }
[Display(Name = "Description")]
[MaxLength(500)]
public String description { get; set; }
[DefaultValue(true)]
[Display(Name = "Active?")]
public bool active { get; set; }
[Display(Name = "Image Name")]
public String imageName { get; set; }
[Display(Name = "PDF Name")]
public String PDFName { get; set; }
[Display(Name = "Category(s)")]
public virtual ICollection<CategoryModel> ProductCategories { get; set; }
public int[] SelectedCategories { get; set; }
public IEnumerable<SelectListItem> CategorySelectList { get; set; }
//public ICollection<CategoryModel> CategoryList { get; set; }
public virtual BrochureModel Brochure { get; set; }
public IEnumerable<SelectListItem> BrochureList { get; set; }
[Display(Name = "Category(s)")]
public String CategoryList { get; set; }
public static IEnumerable<SelectListItem> getCategories(int id = 0)
{
using (var db = new ProductContext())
{
List<SelectListItem> list = new List<SelectListItem>();
var categories = db.Categories.ToList();
foreach (var cat in categories)
{
SelectListItem sli = new SelectListItem { Value = cat.ID.ToString(), Text = cat.categoryName };
//if (id > 0 && cat.ID == id)
//{
// sli.Selected = true;
//}
list.Add(sli);
}
return list;
}
}
public ProductModel()
{
active = true;
}
}
And my Category model:
public class CategoryModel
{
public int ID { get; set; }
[Required(ErrorMessage = "Required")]
[Display(Name = "Category Name")]
[MaxLength(50)]
public String categoryName { get; set; }
[MaxLength(50)]
public String categoryDBName { get; set; }
[DefaultValue(true)]
[Display(Name = "Active?")]
public bool isActive { get; set; }
//public virtual ICollection<ProductCategory> ProductCategories { get; set; }
public virtual ICollection<ProductModel> Products { get; set; }
}
Here is my Product context:
public class ProductContext : DbContext
{
public ProductContext()
: base("DefaultConnection")
{
Database.SetInitializer<ProductContext>(new CreateDatabaseIfNotExists<ProductContext>());
}
public DbSet<CategoryModel> Categories { get; set; }
public DbSet<ProductModel> Products { get; set; }
public DbSet<BrochureModel> Brochures { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
//modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
//modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
modelBuilder.Entity<CategoryModel>().ToTable("Categories");
modelBuilder.Entity<ProductModel>().ToTable("Products");
modelBuilder.Entity<BrochureModel>().ToTable("Brochures");
modelBuilder.Entity<ProductModel>()
.HasMany(p => p.ProductCategories)
.WithMany(p => p.Products)
.Map(m =>
{
m.ToTable("ProductCategory");
m.MapLeftKey("ProductID");
m.MapRightKey("CategoryID");
});
//modelBuilder.Entity<CategoryModel>()
//.HasMany(c => c.ProductCategories)
//.WithRequired()
//.HasForeignKey(c => c.CategoryID);
}
public System.Data.Entity.DbSet<newBestPlay.Models.RegisterViewModel> RegisterViewModels { get; set; }
}
Let me know if other code or more info is needed.
You're never doing anything with your SelectedCategories array. You need to use this to pull CategoryModel instance from the database and then associate those with the product.
context.Categories.Where(c => model.SelectedCategories.Contains(c.ID)).ToList()
.ForEach(c => model.ProductCategories.Add(c));
...
context.SaveChanges();
UPDATE
Can I ask how to list out the categories for each product in my view?
That's kind of a loaded question, as it's highly dependent on what type of experience you're trying to achieve. Generally speaking, with any collection, you'll need to iterate over the items in that collection and then render some bit of HTML for each item. You can do this in a number of different ways, which is why there's not really one "right" answer I can give you. However, just to give you an idea and not leave you with no code at all, here's a very basic way to just list out the name of every category:
#string.Join(", ", Model.ProductCategories.Select(c => c.categoryName))
Select doesn't work for me with DropDownListFor. Can anyone help me?
I have musiccategories and artists that belong to one musiccategory. On my page I want to show artist details, and I want the dropdownlist to load all musiccategories with the specified artists music category selected. But I can't make one specified option in the drop down list selected, the first option is always selected at first.
My controller:
public ActionResult Index()
{
ClassLibrary.Artist a = GetArtist();
System.Collections.Generic.List<System.Web.Mvc.SelectListItem> items = getGenres();
string genre = a.MusicCategory;
foreach (SelectListItem sli in items)
{
if (sli.Text == genre)
{
sli.Selected = true;
}
}
ViewBag.MusicCategory = items;
return View(a);
}
My first model:
public class MusicCategory
{
public int MusicCategoryID { get; set; }
public string MusicCategoryName { get; set; }
}
My secound model:
public class Artist
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string Description { get; set; }
public string MusicCategory { get; set; }
public int MusicCategoryID { get; set; }
public int Contact { get; set; }
public string InformationToCrew { get; set; }
public string Agreement { get; set; }
public string WantedStage { get; set; }
public string AgreementAccepted { get; set; }
public string PublishingStatus { get; set; }
public string ApplicationStatus { get; set; }
public int? ActiveFestival { get; set; }
public string ImageURL { get; set; }
public string URL { get; set; }
public string FacebookEvent { get; set; }
public int Score { get; set; }
public List<GroupMember> GroupMembers { get; set; }
}
My view:
#Html.DropDownListFor(model => model.MusicCategory, (System.Collections.Generic.List<System.Web.Mvc.SelectListItem>)ViewBag.MusicCategory)
DropDownListFor, selected = true doesn't work
Yup.
But I can't make one specified option in the drop down list selected, the first option is always selected at first.
When you use
// I don't recommend using the variable `model` for the lambda
Html.DropDownListFor(m => m.<MyId>, <IEnumerable<SelectListItem>> ...
MVC Ignores .selected and instead verifies the m.<MyId> value against the values in <IEnumerable<SelectListItem>>.
public class DropDownModel
{
public int ID3 { get; set; }
public int ID4 { get; set; }
public int ID5 { get; set; }
public IEnumerable<SelectListItem> Items { get; set; }
}
public ActionResult Index()
{
var model = new DropDownModel
{
ID3 = 3, // Third
ID4 = 4, // Second
ID5 = 5, // There is no "5" so defaults to "First"
Items = new List<SelectListItem>
{
new SelectListItem { Text = "First (Default)", Value = "1" },
new SelectListItem { Text = "Second (Selected)", Value = "2", Selected = true },
new SelectListItem { Text = "Third", Value = "3" },
new SelectListItem { Text = "Forth", Value = "4" },
}
};
return View(model);
}
<div>#Html.DropDownListFor(m => m.ID3, Model.Items)</div>
<div>#Html.DropDownListFor(m => m.ID4, Model.Items)</div>
<div>#Html.DropDownListFor(m => m.ID5, Model.Items)</div>
Result:
dotnetfiddle.net Example
Maybe it has something to do with the way you populate your selec list items or your model.
You can take a look at this post :
How can I reuse a DropDownList in several views with .NET MVC