英文:
passing parameters through all pages using TempData in asp.net core6 mvc
问题
我有一个学校数据库,其中有诸如“Year”、“Grade”、“Major”等实体...
我试图在“_Layout.cshtml”中创建一个年份列表,当用户从列表中选择一年时,所有视图必须基于所选年份检索数据。
因此,我首先需要创建列表,然后将所选年份传递给所有视图。
我尝试使用一个viewModel
,但它不起作用。现在我试图以一种方式使用TempData来保存年份列表和所选年份,但我一直收到以下错误消息。
> System.NullReferenceException: 对象引用未设置为对象的实例。
这是我的AdminController:
public async Task<IActionResult> Index()
{
var allYears = await _context.Years.ToListAsync();
List<SelectListItem> yearList = new List<SelectListItem>();
foreach (var item in allYears)
{
yearList.Add(new SelectListItem { Text = item.Name, Value = item.Id.ToString() });
}
TempData["YearList"] = yearList;
TempData["CurrentYear"] = allYears.FirstOrDefault().Id.ToString();
return View(TempData);
}
这是在_Layout.cshtml
中的局部视图中的列表。这是我得到错误的地方。TempData为null。:
<select class="form-control" asp-for="@TempData["CurrentYear"]">
@foreach (var item in (List<SelectListItem>)TempData["YearList"])
{
<option>@item.Text</option>
}
</select>
我还将这个添加到_viewStart.cshtml
中。
TempData["CurrentYear"] = 1;
TempData["YearList"] = null;
我还尝试了这个,但问题仍然存在。
有没有办法可以使用TempData实现这一点?
还是有更好的方法?
Edit1: 我从viewStart.cshtml
中删除了初始化。但当导航到另一个视图时,我仍然收到null异常错误。
Edit2: 我使用了Session
而不是TempData
。另外,我将下拉列表移到了一个单独的视图,因为我在将列表添加到会话中时遇到了问题。但后来RahulSharma
在评论部分发送了一个教程,非常有帮助。
谢谢大家。
英文:
I have a school database, where there are entities such as Year
, Grade
, Major
, ...
I'm trying to create a list of years in the _Layout.cshtml
and when the user chooses a year from the list, all views must retrieve data based on the selected year.
So I need to first create the list and then pass the selected year to all views.
I tried using a viewModel
but it didn't work. Now I'm trying to make use of TempData in a way to keep the list of years and the selected year, but I keep receiving the following error.
> System.NullReferenceException: Object reference not set to an instance of an object.
Here is my AdminController:
public async Task<IActionResult> Index()
{
var allYears = await _context.Years.ToListAsync();
List<SelectListItem> yearList = new List<SelectListItem>();
foreach (var item in allYears)
{
yearList.Add(new SelectListItem { Text = item.Name, Value = item.Id.ToString() });
}
TempData["YearList"] = yearList;
TempData["CurrentYear"] = allYears.FirstOrDefault().Id.ToString();
return View(TempData);
}
This is the list in the partial view in _Layout.cshtml
. This is where I get the error. TempData is null.:
<select class="form-control" asp-for="@TempData["CurrentYear"]">
@foreach (var item in (List<SelectListItem>)TempData["YearList"])
{
<option>@item.Text</option>
}
</select>
I have also added this to _viewStart.cshtml
.
TempData["CurrentYear"] = 1;
TempData["YearList"] = null;
I have also tried this, but the issue still remains.
Is there any way I can achieve this using TempData?
Or Is there a better way?
Edit1: I removed the initialization in viewStart.cshtml
. But still I get the null exception error when navigating to another view.
Edit2: I used Session
instead of TempData
. Also I moved the dropdownlist to a separate view because I had a problem with adding a list to the session. But then RahulSharma
sent a tutorial in the comment section which is very helpful.
Thank you everyone.
答案1
得分: 2
以下是您情境的原型代码翻译:
Controller
:
[HttpGet]
public async Task<IActionResult> Index()
{
TempData["YearList"] = new List<SelectListItem> { new SelectListItem("2021", "2021"), new SelectListItem("2022", "2022"), new SelectListItem("2023", "2023") };
return View();
}
[HttpPost]
public async Task<IActionResult> Index(int year)
{
TempData["CurrentYear"] = year;
return RedirectToAction(nameof(Index));
}
View
:
<form method="post">
<select name="year">
@foreach (var year in (List<SelectListItem>)TempData["YearList"])
{
<option value="@year.Value">@year.Text</option>
}
</select>
<input type="submit" value="Send"/>
</form>
<h3>Selected year: @TempData["CurrentYear"]</h3>
解释:
[HttpGet]Index
动作方法呈现年份,此步骤中没有选定的年份。- 视图从
TempData
中检索值并显示select
控件。 - 用户选择年份,然后点击按钮(提交表单)。
[HttpPost]Index
接受年份参数(名称与选择控件的name
属性匹配)。将选择放入TempData
。- 重定向到
[HttpGet]Index
。 - 渲染列表和选定的值。这里的关键点是,如果只是刷新页面,它不会再次恢复选定的值。从
TempData
中提取是一次性操作(阅读答案https://stackoverflow.com/a/32571656/2091519)。
要考虑的要点:
- 通过重定向和查询字符串参数传递选定的年份,而不是提交表单(https://stackoverflow.com/a/10175571/2091519)。
- 使用 Ajax(异步)方法在用户选择后获取其他数据(https://stackoverflow.com/a/29122117/2091519)。
- 使用 ViewBag/ModelViews 或任何其他容器来从控制器传递数据到视图。
- 使用 Cookies/Session 在页面重新加载之间保持数据持久性。
等等。
英文:
Here is the prototype for your scenario
Controller
:
[HttpGet]
public async Task<IActionResult> Index()
{
TempData["YearList"] = new List<SelectListItem> { new ("2021", "2021"), new ("2022", "2022"), new ("2023", "2023") };
return View();
}
[HttpPost]
public async Task<IActionResult> Index(int year)
{
TempData["CurrentYear"] = year;
return RedirectToAction(nameof(Index));
}
View
:
<form method="post">
<select name="year">
@foreach (var year in (List<SelectListItem>)TempData["YearList"])
{
<option value="@year.Value">@year.Text</option>
}
</select>
<input type="submit" value="Send"/>
</form>
<h3>Selected year: @TempData["CurrentYear"]</h3>
Explanation:
[HttpGet]Index
action method renders years, no selected year on this step- View retrieves the values from
TempData
and displayselect
control - User choose the year, and click button (submit form)
[HttpPost]Index
accept year argument (name matchesname
attribute of select control). Put the selection intoTempData
- Redirect to
[HttpGet]Index
- Renders both list and selected value. The key point here is that if you just refresh the page it won't recover selected value again. Extraction from TempData is one-time operation (read answer https://stackoverflow.com/a/32571656/2091519)
Points to consider:
- pass the selected year via redirect & query string parameters rather than submitting the form (https://stackoverflow.com/a/10175571/2091519)
- Use Ajax (async) approach to fetch additional data after user selection (https://stackoverflow.com/a/29122117/2091519)
- Use ViewBag/ModelViews or any other container for passing data from contoller to view
- Use Cookies/Session to persist data between page reloads
etc
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论