У меня есть страница Razor в ASP.NET Core, где есть раскрывающийся список (), заполненный именами пользователей. После выбора имени пользователя форма автоматически отправляется с использованием JavaScript (onchange="this.form.submit()"). Однако после отправки формы выбранное имя пользователя удаляется из раскрывающегося списка, что не является предполагаемым поведением.
Страница Razor (.cshtml):
<div class = "rollname">
<label class = "required">User Name :</label>
<select id = "selectedUser" name = "selectedUser" class = "form-control-1"
asp-items='@(new SelectList(Model.Users, "Key", "Value",ViewData["SelectedUserId"]))'
onchange = "this.form.submit()">
<option value = "">--Select--</option>
</select>
</div>
Страница Razor (cshtml.cs)
public class PageNameModel : PageModel
{
public Dictionary<long, string> Users { get; set; } // Replace with actual data type
public void OnGet()
{
// Load users data and set default selected user ID
ViewData["SelectedUserId"] = "123"; // Replace with your logic to get default selected user ID
}
public IActionResult OnPost(long selectedUser)
{
// Process form submission
HttpContext.Session.SetString("selectedUserId", selectedUser.ToString());
ViewData["SelectedUserId"] = selectedUser.ToString();
return RedirectToPage();
}
}
Выше показано изображение для демонстрации имени пользователя, которое не выбрано предварительно после отправки. Примечание. Существует раскрывающийся список, который не виден в видео по неизвестной причине.
Как мне убедиться, что после выбора значения раскрывающегося списка имени пользователя оно не должно очищаться после перенаправления на ту же страницу. Есть ли лучший подход к этому?
Просто отправьте параметр запроса на перенаправление и прочитайте его из GET. Итак, верните RedirectToPage("/your/relative/pathorURL", new { selectedUserId = selectedUser.ToString() }); Затем вы можете привязать «selectedUserId» к GET и использовать тег «asp-for» в элементе Select.
Вместо использования ViewData
(угу!), привяжите значения к общедоступным свойствам вашего PageModel
:
public class PageNameModel : PageModel
{
public Dictionary<int, string> Users { get; set; }
[BindProperty]
public int SelectedUserId { get; set; } = 123;
public void OnGet()
{
if (HttpContext.Session.TryGetValue("selectedUserId", out string result))
{
SelectedUserId = Convert.ToInt32(result);
}
}
public IActionResult OnPost()
{
// Process form submission
HttpContext.Session.SetString("selectedUserId", SelectedUserId.ToString());
return RedirectToPage();
}
}
Затем назначьте свойство SelectedUserId
атрибуту asp-for
вспомогательного тега select
:
<div class = "rollname">
<label class = "required">User Name :</label>
<select asp-for = "SelectedUserId" class = "form-control-1"
asp-items='@(new SelectList(Model.Users, "Key", "Value"))'
onchange = "this.form.submit()">
<option value = "">--Select--</option>
</select>
</div>
Подробнее о привязке модели можно узнать здесь: https://www.learnrazorpages.com/razor-pages/model-binding
Это не работает . После выбора конкретного пользователя страница перезагружается и выполняются другие операции, после которых выбранное имя пользователя удаляется.
В приведенном мной примере в сеансе сохраняется выбранный UserID, а не имя. Если вы хотите сохранить имя, вам нужно получить его из словаря. Если вам нужна помощь с этим, возможно, вам следует задать еще один вопрос.
Выбранный идентификатор пользователя, который хранится в сеансе. Я хочу, чтобы этот идентификатор выбирался при повторной загрузке страницы. Когда этот идентификатор пользователя выбран, он автоматически отображает соответствующее имя пользователя, поскольку оно хранится в парах KEY, VALUE в словаре.
@YuvrajJadhav Обновлен ответ, чтобы установить значение в OnGet
из сеанса, если оно существует.
Вот пример кода, который вы можете попробовать:
Индекс.cshtml:
@page
@model IndexModel
@{
var selectedUserId = ViewData["SelectedUserId"]?.ToString();
}
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8" />
<title>Assign Circle To User</title>
<link rel = "stylesheet" href = "~/css/site.css" />
<style>
body {
font-family: Arial, sans-serif;
}
.form-control-1 {
width: 200px;
padding: 5px;
margin-bottom: 10px;
}
.rollname {
margin-bottom: 20px;
}
.circles {
display: flex;
align-items: flex-start;
}
.circle-container {
display: flex;
flex-direction: column;
align-items: center;
}
.circles select {
width: 200px;
height: 150px;
margin-bottom: 10px;
}
.buttons {
display: flex;
flex-direction: column;
align-items: center;
margin: 0 20px;
}
.buttons button {
width: 120px;
padding: 5px;
margin: 5px 0;
background-color: #4CAF50;
color: white;
border: none;
cursor: pointer;
font-size: 14px;
}
.buttons button:hover {
background-color: #45a049;
}
.submit-button {
margin-top: 20px;
padding: 10px;
background-color: #008CBA;
color: white;
border: none;
cursor: pointer;
font-size: 14px;
}
.submit-button:hover {
background-color: #007BB5;
}
</style>
</head>
<body>
<div class = "rollname">
<label class = "required">User Name :</label>
<form method = "post" id = "userForm">
<select id = "selectedUser" name = "selectedUser" class = "form-control-1"
asp-items='@(new SelectList(Model.Users, "Key", "Value", selectedUserId))'
onchange = "document.getElementById('userForm').submit()">
<option value = "">--Select--</option>
</select>
</form>
</div>
<form method = "post" id = "circleForm">
<div class = "circles">
<div class = "circle-container">
<label>Available Circle:</label>
<select id = "availableCircles" name = "availableCircles" multiple>
@foreach (var circle in Model.AvailableCircles)
{
<option value = "@circle">@circle</option>
}
</select>
</div>
<div class = "buttons">
<button type = "button" onclick = "assignCircle()">Add</button>
<button type = "button" onclick = "assignAllCircles()">Add All</button>
<button type = "button" onclick = "removeCircle()">Remove</button>
<button type = "button" onclick = "removeAllCircles()">Remove All</button>
</div>
<div class = "circle-container">
<label>Assigned Circle:</label>
<select id = "assignedCircles" name = "assignedCircles" multiple>
@foreach (var circle in Model.AssignedCircles)
{
<option value = "@circle">@circle</option>
}
</select>
</div>
</div>
<input type = "hidden" id = "selectedUserId" name = "selectedUserId" value = "@selectedUserId" />
<button type = "submit" class = "submit-button">Submit</button>
</form>
<script>
function assignCircle() {
var available = document.getElementById("availableCircles");
var assigned = document.getElementById("assignedCircles");
moveSelectedOptions(available, assigned);
}
function assignAllCircles() {
var available = document.getElementById("availableCircles");
var assigned = document.getElementById("assignedCircles");
moveAllOptions(available, assigned);
}
function removeCircle() {
var available = document.getElementById("availableCircles");
var assigned = document.getElementById("assignedCircles");
moveSelectedOptions(assigned, available);
}
function removeAllCircles() {
var available = document.getElementById("availableCircles");
var assigned = document.getElementById("assignedCircles");
moveAllOptions(assigned, available);
}
function moveSelectedOptions(from, to) {
var selectedOptions = Array.from(from.selectedOptions);
selectedOptions.forEach(option => {
to.appendChild(option);
});
}
function moveAllOptions(from, to) {
var options = Array.from(from.options);
options.forEach(option => {
to.appendChild(option);
});
}
</script>
</body>
</html>
Индекс.cshtml.cs:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Http;
using System.Collections.Generic;
using System.Linq;
namespace AssignCircleProject.Pages
{
public class IndexModel : PageModel
{
public Dictionary<long, string> Users { get; set; }
public List<string> AvailableCircles { get; set; } = new List<string> { "Maharashtra", "Karnataka", "Andhra Pradesh" };
public List<string> AssignedCircles { get; set; } = new List<string>();
public void OnGet()
{
Users = GetUsers();
ViewData["SelectedUserId"] = HttpContext.Session.GetString("selectedUserId") ?? "123";
if (ViewData["AssignedCircles"] != null)
{
AssignedCircles = ((string)ViewData["AssignedCircles"]).Split(',').ToList();
}
}
public IActionResult OnPost(long selectedUser, string[] assignedCircles)
{
HttpContext.Session.SetString("selectedUserId", selectedUser.ToString());
ViewData["SelectedUserId"] = selectedUser.ToString();
Users = GetUsers();
AssignedCircles = assignedCircles.ToList();
ViewData["AssignedCircles"] = string.Join(",", AssignedCircles);
return Page();
}
private Dictionary<long, string> GetUsers()
{
return new Dictionary<long, string>
{
{ 1, "User1" },
{ 2, "User2" },
{ 3, "User3" }
// Add more users as needed
};
}
}
}
Фронтенд.cshtml
<select id = "selectedCircleUser" name = "selectedCircleUser" class = "form-control-1"
asp-items='@(new SelectList(Model.Users, "Key", "Value",ViewData["selectedCircleUser"]))'
onchange = "this.form.submit()">
<option value=0>--Select--</option>
</select>
Здесь используется ViewData, чтобы получить значение и выбрать его, если оно существует.
Файл Backend.cshtml.cs
public void OnGet(long? selectedUserId = 0)
{
if (selectedUserId != null && selectedUserId != 0)
{
//string selectedUserId = HttpContext.Session.GetString("selectedCircleUserId");
ViewData["selectedCircleUser"] = selectedUserId; // I
//Code to get the available circle and assigned circle to that user
}
public IActionResult OnPost()
{
HttpContext.Session.SetString("selectedCircleUserId", selectedCircleUser.ToString());
return RedirectToPage(new { selectedUserId = selectedCircleUser });
}
Поэтому всякий раз, когда страница повторно посещается, значение равно 0, и на странице ничего не отображается. Если пользователь выбрал какое-либо конкретное имя пользователя, то в сообщении мы передаем параметр, с помощью которого будут выбраны назначенный круг и доступный круг, а также этот идентификатор имени пользователя будет сохранен в данных просмотра, с помощью которых он предварительно выбирается во внешнем интерфейсе.
Вы использовали вспомогательный тег
asp-items
, но неasp-for
, который будет использоваться для автоматического выбора предыдущего значения из модели.