如何在 Razor 页面上提交后保持模型筛选值的持久化

huangapple go评论45阅读模式
英文:

How to persist model filter values on a Razor page after post

问题

我有一个相当基本的.NET Core Razor页面,其中包含一个带有表格的部分视图。主页有一组文本框和下拉菜单,用于过滤表格。表格和过滤功能按预期工作。

我还有一个模态弹出窗口,用于向基本表格添加新记录。模态上有一个提交按钮,用于保存表单值。这也按预期工作,但在提交后,用于过滤的文本框和下拉菜单会重置。

CSHTML过滤

<form>
	<select style="width:150px;" asp-for="Division" asp-items="Model.Divisions">
		<option value="">All</option>
	</select>
	<input type="submit" value="Filter" />
	<a class="link-button">Reset</a>
</form>

CSHTML C#

public class IndexModel : PageModel
	{
		public SelectList? Divisions { get; set; }
		public SelectList? OpCos { get; set; }
		public SelectList? Municipalities { get; set; }
		public SelectList? DesignPhases { get; set; }
		public SelectList? Designers { get; set; }

		[BindProperty(SupportsGet = true)]
		public string? Division { get; set; }

		public async Task OnGetAsync()
		{
			IQueryable<string> filterQuery =
				from m in _context.GasProjects
				where !string.IsNullOrEmpty(m.Division)
				orderby m.Division
				select m.Division;
			Divisions = new SelectList(await filterQuery.Distinct().ToListAsync(), Division);
			GasProjects = await QueryProjects();
		}
	}

模态后台处理程序

public async Task<IActionResult> OnPostCreateNewRecordAsync(GasProject gasProject)
		{
			if (!ModelState.IsValid)
			{
				return Page();
			}
			//save record
			return RedirectToPage("Index");
		}

我尝试过一些ViewState和JavaScript的想法,但还没有找到正确的解决方案。

英文:

I have a pretty basic .NET Core Razor page that contains a partial view with a table. The index page has a collection of text boxes and dropdowns that are used to filter the table. The table and the filtering functionality works as expected.

I also have a modal popup that is used to add a new record to the base table. There is a submit button on the modal for saving the form values. This also works as expected, except that the text boxes and dropdowns for the filtering are reset after postback.

CSHTML filter

<form>
	<select style="width:150px;" asp-for="Division" asp-items="Model.Divisions">
		<option value="">All</option>
	</select>
	<input type="submit" value="Filter" />
	<a class="link-button">Reset</a>
</form>

CSHTML c#

public class IndexModel : PageModel
	{
		public SelectList? Divisions { get; set; }
		public SelectList? OpCos { get; set; }
		public SelectList? Municipalities { get; set; }
		public SelectList? DesignPhases { get; set; }
		public SelectList? Designers { get; set; }

		[BindProperty(SupportsGet = true)]
		public string? Division { get; set; }

		public async Task OnGetAsync()
		{
			IQueryable<string> filterQuery =
				from m in _context.GasProjects
				where !string.IsNullOrEmpty(m.Division)
				orderby m.Division
				select m.Division;
			Divisions = new SelectList(await filterQuery.Distinct().ToListAsync(), Division);
			GasProjects = await QueryProjects();
		}

Modal Post Handler

public async Task<IActionResult> OnPostCreateNewRecordAsync(GasProject gasProject)
		{
			if (!ModelState.IsValid)
			{
				return Page();
			}
			//save record
			return RedirectToPage("Index");
		}

I have tried some ViewState and javascript ideas but I haven't hit on the correct solution yet.

答案1

得分: 0

你应该使用<input type="hidden" ...>来保存Division的值。并使用TempData来实现它。

<form method="get">
    <select style="width:150px;" asp-for="Division" asp-items="Model.Divisions">
        <option value="">All</option>
    </select>
    <input type="submit" value="Filter" />
    <a href="/YourController/Reset" class="link-button">Reset</a>

    @if (!string.IsNullOrEmpty(Model.Division))
    {
        <input type="hidden" asp-for="Division" value="@Model.Division" />
    }
</form>

你可以在OnGetAsync方法中保存SelectedDivision数据,并在OnPostCreateNewRecordAsync方法中检查TempData["SelectedDivision"]的值。

public async Task OnGetAsync()
{
    if (!string.IsNullOrEmpty(Request.Query["Division"]))
    {
        Division = Request.Query["Division"].ToString();
        TempData["SelectedDivision"] = Division;
    }
    else if (TempData.ContainsKey("SelectedDivision"))
    {
        Division = TempData["SelectedDivision"].ToString();
    }

    // ...
    IQueryable<string> filterQuery = ...;
    Divisions = new SelectList(await filterQuery.Distinct().ToListAsync(), Division);
    GasProjects = await QueryProjects();
}

public async Task<IActionResult> OnPostCreateNewRecordAsync(GasProject gasProject)
{
    if (!ModelState.IsValid)
    {
        return Page();
    }

    // 保存记录

    if (TempData.ContainsKey("SelectedDivision"))
    {
        Division = TempData["SelectedDivision"].ToString();
    }

    return RedirectToPage("Index");
}
英文:

You should use &lt;input type=&quot;hidden&quot; ...&gt; to save the value of Division. And use TempData to implement it.

&lt;form method=&quot;get&quot;&gt;
    &lt;select style=&quot;width:150px;&quot; asp-for=&quot;Division&quot; asp-items=&quot;Model.Divisions&quot;&gt;
        &lt;option value=&quot;&quot;&gt;All&lt;/option&gt;
    &lt;/select&gt;
    &lt;input type=&quot;submit&quot; value=&quot;Filter&quot; /&gt;
    &lt;a href=&quot;/YourController/Reset&quot; class=&quot;link-button&quot;&gt;Reset&lt;/a&gt;

    @if (!string.IsNullOrEmpty(Model.Division))
    {
        &lt;input type=&quot;hidden&quot; asp-for=&quot;Division&quot; value=&quot;@Model.Division&quot; /&gt;
    }
&lt;/form&gt;

You can save SelectedDivision data in OnGetAsync method, and check the value of TempData[&quot;SelectedDivision&quot;] in the OnPostCreateNewRecordAsync method or not.

Like below:

public async Task OnGetAsync()
{
    if (!string.IsNullOrEmpty(Request.Query[&quot;Division&quot;]))
    {
        Division = Request.Query[&quot;Division&quot;].ToString();
        TempData[&quot;SelectedDivision&quot;] = Division;
    }
    else if (TempData.ContainsKey(&quot;SelectedDivision&quot;))
    {
        Division = TempData[&quot;SelectedDivision&quot;].ToString();
    }

    // ...
    IQueryable&lt;string&gt; filterQuery = ...;
    Divisions = new SelectList(await filterQuery.Distinct().ToListAsync(), Division);
    GasProjects = await QueryProjects();
}

And

public async Task&lt;IActionResult&gt; OnPostCreateNewRecordAsync(GasProject gasProject)
{
    if (!ModelState.IsValid)
    {
        return Page();
    }
    
    // Save record
    
    if (TempData.ContainsKey(&quot;SelectedDivision&quot;))
    {
        Division = TempData[&quot;SelectedDivision&quot;].ToString();
    }
    
    return RedirectToPage(&quot;Index&quot;);
}

huangapple
  • 本文由 发表于 2023年6月12日 23:20:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76458080.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定