Best Programming Practice of Using Dropdownlist in ASP.NET MVC

Best programming practice of using DropDownList in ASP.Net MVC

You want to use option 1, mainly because you want to use Strongly Type as much as possible, and fix the error at compile time.

In contrast, ViewData and ViewBag are dynamic, and compile could not catch error until run-time.

Here is the sample code I used in many applications -

Model

public class SampleModel
{
public string SelectedColorId { get; set; }
public IList<SelectListItem> AvailableColors { get; set; }

public SampleModel()
{
AvailableColors = new List<SelectListItem>();
}
}

View

@model DemoMvc.Models.SampleModel
@using (Html.BeginForm("Index", "Home"))
{
@Html.DropDownListFor(m => m.SelectedColorId, Model.AvailableColors)
<input type="submit" value="Submit"/>

}

Controller

public class HomeController : Controller
{
public ActionResult Index()
{
var model = new SampleModel
{
AvailableColors = GetColorListItems()
};
return View(model);
}

[HttpPost]
public ActionResult Index(SampleModel model)
{
if (ModelState.IsValid)
{
var colorId = model.SelectedColorId;
return View("Success");
}
// If we got this far, something failed, redisplay form
// ** IMPORTANT : Fill AvailableColors again; otherwise, DropDownList will be blank. **
model.AvailableColors = GetColorListItems();
return View(model);
}

private IList<SelectListItem> GetColorListItems()
{
// This could be from database.
return new List<SelectListItem>
{
new SelectListItem {Text = "Orange", Value = "1"},
new SelectListItem {Text = "Red", Value = "2"}
};
}
}

MVC4 best practice for DropDownListFor enum from database or code

I personally think that database-driven is the way to go. Mainly from experience, say you wanted to add a value into your lookup and you'd already deployed your application, you'd have to re-deploy the code after adding the new value to the Enum. With them being database driven you simply can run an insert query against the database and no re-deploy is required.

I wouldn't call your database in your view like that though, I wouldn't say that was best practice, as that's not the view's responsibility, it just needs to display data, not query for additional data.

First off, put your items you want in your dropdown list in your model, like so:

public class YourModel
{
public int WidgetTypeId { get; set; }
public SelectList WidgetTypes { get; set; }
//...rest of your model
}

Then, in your GET method in your controller (before returning your view, populate that list with the code you have in the view:

public ActionResult MyAction()
{
YourModel model = new YourModel();

model.WidgetTypes = Business.MySession.Current.WidgetTypes
.ToSelectList(d => d.TypeName, d => d.WidgetTypeID.ToString(), " - Select - ");

return View(model);
}

Then in your view just do:

@Html.DropDownListFor(model => model.WidgetTypeID, Model.WidgetTypes)

ASP.NET MVC ViewModel with SelectList(s) best practice

Personally I like to keep it simple:-

[HttpGet]
public Edit(int id) {
EditForm form = new EditForm();
// Populate from the db or whatever...
PopulateEditPageSelectLists(form);
return View(form);
}

[HttpPost]
public Edit(EditForm form) {
if (ModelState.IsValid) {
// Do stuff and redirect...
}
PopulateEditPageSelectLists(form);
return View(form);
}

public void PopulateEditPageSelectLists(form) {
// Get lookup data from the db or whatever.
}

If the logic to populate the select lists is all kinds crazy it might be worthwhile moving to a separate class or whatever it but as a first step this is the best place to start.

Populate DropDown List in MVC App that Consumes a Web API

In your Code, I noticed that you used @Html.DropDownList to realzie the selector element, and using form submit to handle the data. So I did a test in my side:

@{
List<SelectListItem> listItems= new List<SelectListItem>();
listItems.Add(new SelectListItem
{
Text = "Exemplo1",
Value = "Exemplo1_v"
});
listItems.Add(new SelectListItem
{
Text = "Exemplo2",
Value = "Exemplo2_v",
Selected = true
});
listItems.Add(new SelectListItem
{
Text = "Exemplo3",
Value = "Exemplo3_v"
});
}

<form asp-action="Create">
<div class="form-group">
AuthorNames
<div class="col-md-10">
@Html.DropDownListFor(model => model.Author, listItems, "-- Select author --")
</div>
</div>

<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>

My model contains a public string? Author { get; set; } property, and when I click the submit button, the select value will be submitted, so when you want to pass the FullName to your controller, you need to set it as the Value of the SelectListItem.

Sample Image

ASP MVC 5 C# Recursive Trees To Group and Indent A DropDownList

You can first select the parent categories (where ParentId is null) and then for each parent category, select its child categories.

public IEnumerable<SelectListItem> GetCategoriesSelectList()
{
var categories = _context.Category.ToList();
// Initialise list and add first "All" item
List<SelectListItem> options = new List<SelectListItem>
{
new SelectListItem(){ Value = "0", Text = "All" }
};
// Get the top level parents
var parents = categories.Where(x => x.ParentId == null);
foreach (var parent in parents)
{
// Add SelectListItem for the parent
options.Add(new SelectListItem()
{
Value = parent.Id.ToString(),
Text = parent.Name
});
// Get the child items associated with the parent
var children = categories.Where(x => x.ParentId == parent.Id);
// Add SelectListItem for each child
foreach (var child in children)
{
options.Add(new SelectListItem()
{
Value = child.Id.ToString(),
Text = string.Format("--{0}",child.Name)
});
}
}
return options;
}

Best Practice for adding Liststring to DropDownList

The only thing DropDownListFor needs is an IEnumerable<SelectListItem> (i.e., that could be a list/collection/queryable/etc.). The problem right now is that you simply have a list string instead of SelectListItem. That's easy remedied with a little LINQ-fu:

@Html.DropDownListFor(x => x.searchCategory, Model.AllCategories.Select(m => new SelectListItem { Value = m, Text = m }))

However, the better approach would be to simply have AllCategories return a list of SelectListItems off-the-bat (assuming it's only being used for populating the dropdown list).

private IEnumerable<SelectListItem> allCategories;
public IEnumerable<SelectListItem> AllCategories
{
get
{
if (allCategories == null)
{
var _engine = new NopEngine();
var categoryService = _engine.Resolve<ICategoryService>();

allCategories = categoryService.GetAllCategories().Select(m =>
new SelectListItem { Value = m.Name, Text = m.Name });
}

return allCategories;
}

// You don't need a setter
}

The first time AllCategories is accessed, the associated private variable, allCategories, will be null, so your service spins up and the list of categories is fetched. Select is used to cast the returned categories into a collection of SelectListItems. If you category has something like an Id property, you should use that for Value instead of Name. Any subsequent accesses of AllCategories will simply return the value stored in the private without hitting the database again.

Bonus Pro Tip

If you actually do need to use a for loop for something like this, you don't need to create a new list, add items to the list in the loop, and then return that list. It's easier to just use yield. For example:

public IEnumerable<int> Numbers
{
for (int i = 0; i < 10; i++)
{
yield return i;
}
}

populate dropdownlistfor mvc

You are passing in a list of PartStructures class objects to the Except method. Except method uses the default equality comparer to compare the values.

If you are passing a custom class (not a simple value type like int) , You should implement IEqualityComparer<T> interface methods such as Equals and GetHashCode.

If you do not prefer to do that, You can get the Ids of your PartStructures collection and use that with the Contains method.

var excludeIdList = db.PartStructures1.Where(p => p.mainPart_id == partID)
.Select(g=>g.Id).ToList();

var parts = db.Parts
.Where(c => !c.PartStructures_comp.Any(g=>excludeIdList.Contains(g.Id)))
.ToList();


Related Topics



Leave a reply



Submit