我正在使用vs 2017和chrome。
我有一个ASP.Net核心MVC应用程序。它有一个下拉列表,没有正确显示项目。显示的项目应为:喜剧,西方和浪漫。
这是调试图像。这些项目显示了数组和文本{MvcMovie.Modesl.Genre},当我点击每个项目时,项目文本显示为我想要的。
我从数据库中选择类型并将它们作为List返回并将其转换为SelectList,因为它将HTML呈现为具有SelectListItem对象集合的元素。
但是,当我查看原始视图时,我只看到文本{MvcMovie.Modesl.Genre},这是下拉列表中显示的内容。
我填充movieGenreVM并将其作为Index操作方法中的视图返回。
public IActionResult Index(string movieGenre, string searchStringEntered)
{
// A list of genre objects.
SelectList genresList;
// A list of movie objects.
List<Movie> moviesList;
// Instantiate the View model.
var movieGenreVM = new MovieGenreViewModel();
// Get a list of genres from the database.
genresList = new SelectList(GetGenres(movieGenre));
// Get a list of movies from the database.
moviesList = GetMovies(searchStringEntered);
// Sets the models property which is then used in the dropdown of Genres.
movieGenreVM.genres = genresList;
// Creates a List object.
// Movie is populated from the database and used to generate an HTML table of loaded movies.
movieGenreVM.movies = moviesList;
// Passing the MovieGenreViewModel.
// Return the IActionResult - the Index.cshtml. A view template to generate an HTML response to the browser.
return View(movieGenreVM);
}
namespace MvcMovie.Models
{
public class MovieGenreViewModel
{
// A list of movies.
public List<Movie> movies;
// A SelectList containing the list of genres.
public SelectList genres;
// Contains the selected genre.
public string movieGenre { get; set; }
}
}
类型模型是:
public class Genre
{
public string MovieGenre { get; set; }
// Constructor.
public Genre()
{
}
public Genre(string a_MovieGenre)
{
MovieGenre = a_MovieGenre;
}
}
这里是流派列表代码的总体:
// Create a list of genres.
private List<Genre> _genre = new List<Genre>();
public List<Genre> Genre
{
get
{
return _genre;
}
}
public List<Genre> GetGenres(string movieGenre)
{
Boolean errorSw = false;
// Declare the reader and initialize.
SqlDataReader GenresDataReader = null;
try
{
// Open the connection.
dbFunc.OpenDB();
// Get the list of distinct Genres by executing a stored procedure.
SqlCommand GenresCmd = new SqlCommand("dbo.SelectGenres", dbFunc.objConn);
GenresCmd.Parameters.Clear();
GenresCmd.CommandType = CommandType.StoredProcedure;
GenresCmd.Parameters.Add("@SearchText", SqlDbType.VarChar).Value = movieGenre;
// Set the reader.
GenresDataReader = GenresCmd.ExecuteReader();
// Loop thru the results returned.
while (GenresDataReader.Read())
{
// Add to the list of genres - creates a new row for the collection.
Genre.Add(new Genre(GenresDataReader["Genre"].ToString()));
}
}
catch (Exception ex)
{
errorSw = true;
}
finally
{
if (GenresDataReader != null)
{
GenresDataReader.Close();
}
dbFunc.CloseDB();
}
// Return the list of genre objects.
return Genre;
}
以下是观点:
@model MvcMovie.Models.MovieGenreViewModel
@{
ViewData["Title"] = "Index";
}
<h2>List of Movies</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<form asp-controller="Movies" asp-action="Index" method="get">
<p>
@* A dropdown. *@
<select asp-for="movieGenre" asp-items="Model.genres">
<option value="">All</option>
</select>
Title: <input type="text" name="searchStringEntered">
<input type="submit" value="Filter" />
</p>
</form>
@* Shows the list of movies. *@
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.movies[0].Title)
</th>
<th>
@Html.DisplayNameFor(model => model.movies[0].ReleaseDate)
</th>
<th>
@Html.DisplayNameFor(model => model.movies[0].Genre)
</th>
<th>
@Html.DisplayNameFor(model => model.movies[0].Price)
</th>
<th>
@Html.DisplayNameFor(model => model.movies[0].Rating)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.movies) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Title)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Genre)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.Rating)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
&#13;
本教程使用的是Entity Framework,但我将其转换为使用ADO.net和存储过程。下拉列表的EF版本工作正常。
这是EF版本的索引操作方法。该类型只是文本 - 没有与之相关的Id。
public async Task<IActionResult> Index(string movieGenre, string searchStringEntered)
{
IQueryable<string> genreQuery = from m in _context.Movie
orderby m.Genre
select m.Genre;
var movies = from m in _context.Movie
select m;
if (!String.IsNullOrEmpty(searchStringEntered))
{
movies = movies.Where(s => s.Title.Contains(searchStringEntered));
}
if (!String.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}
// Instantiate the model.
var movieGenreVM = new MovieGenreViewModel();
// The SelectList of genres is created by projecting the distinct genres.
// Sets the models property which is then used in the dropdown of Genres.
movieGenreVM.genres = new SelectList(await genreQuery.Distinct().ToListAsync());
// Creates a List object.
// Movie is populated from the database and used to generate an HTML table of loaded movies.
movieGenreVM.movies = await movies.ToListAsync();
return View(movieGenreVM);
}
答案 0 :(得分:0)
从屏幕截图中可以清楚地看出,SelectList
和DataTextField
错过了DataValueField
。所以SELECT标记帮助器不知道哪个属性应该用于文本,哪个属性应该用于Value。
解决方案是在创建SelectList对象时指定它。由于Genre
实体类只有一个属性MovieGenre
,您可以将它用于Text和Value
var generesList = new SelectList(GetGenres(movieGenre),"MovieGenre","MovieGenre");
var vm=new MovieGenreViewModel { genres= generesList};
return View(vm);
现在,在您的视图中,您可以将Select tag helper与此genres
属性
@model MovieGenreViewModel
<select asp-for="movieGenre" asp-items="@Model.genres"></select>
select标签助手将使用DataValueField
属性值作为选项值属性,使用DataTextField
属性值作为选项文本。
或由于您的enter code here
Genre类中只有一个属性,因此您可以将字符串列表传递给SelectList
构造函数。以下也可以。
var gList=GetGenres(movieGenre);
var generesList = new SelectList(gList.Select(a=>a.MovieGenre));
var vm=new MovieGenreViewModel { genres= generesList};
return View(vm);
这篇文章解释了使用SELECT标记助手的不同选项,供您参考
答案 1 :(得分:0)
这是我如何做的一个例子:
var items = GetItemsFromDB();
var vals = new List<SelectListItem> {new SelectListItem {Selected = true, Text = "--Select an Item--", Value = "0"}};
vals.AddRange(items.Select(item => new SelectListItem
{
Selected = false, Text = item.Type, Value = item.Id.ToString()
}));
var result = new SelectList(vals, "Value", "Text");
正如您所看到的,当我将其转换为SelectList时,我将Value和Text指定为dataValueField和dataTextField。
在您的情况下,您需要这些值的属性,并在您“投射”时指定它们。使用SelectList构造函数。
在我看来,我这样做:
<select asp-for="Model.ItemId" asp-items="Model.MyItemSelectList"></select>
其中Model.MyItemSelectList可以是SelectListItem的列表
将它绑定到集合的另一种方法是这样的:
<select asp-for="Model.MyItemId">
<option value="">-- Select Item --</option>
@{
foreach (var item in Model.MyItems)
{
<option value="@item.Key">@item.Value</option>
}
}
</select>
其中item具有Key和Value属性。属性可以是您想要的名称。在这种情况下&#34; item&#34;有这些属性。