[英]Call controller method multiple times based on input in multiselect from view on submitting form [ASP.NET Core]
問題摘要:
我有一個現有的asp.net核心應用程序,該應用程序從下拉列表中獲取3個輸入(每個輸入中允許單個輸入),並基於這些值首先對其進行驗證,然后在表Table_Abc中的數據庫中添加新記錄。 例如: 。
我正在嘗試對此進行修改,以便可以從第二個下拉列表中選擇多個輸入,但是在后端,它添加到Table_Abc =我選擇的輸入數量的記錄數使得所有記錄值都保持不變,唯一的區別是是第二個下拉列表中的不同輸入。
前端(VIEW):
View中的現有代碼(例如:demoview.cshtml):
<div id="newAccess">
<div>
<br />
<form method="post" id="form-submission-id" asp-action="RequestAccessSubmit">
<div class="form-horizontal">
<div class="form-group">
<label class="col-md-3 text-left">User Type:</label>
<select asp-items="ViewBag.GroupTypes" id="UserTypeID" class="form-control" name="GroupTypeID">
<option value="null">--Select User Types--</option>
</select>
</div>
<div class="form-group">
<label class="col-md-3 text-left">Application/Business Group:</label>
<select class="form-control" asp-items="ViewBag.ContainerSelect" id="BusinessGroup" name="ContainerID" disabled>
<option value="null">--Select Business Group--</option>
</select>
</div>
<div class="form-group">
<label class="col-md-3 text-left">Requested Permissions:</label>
<select asp-items="ViewBag.APSelect" id="RequestedPermission" class="form-control fa-align-left" name="AppPermissionID" disabled>
<option value="null">--Select Requested Permission--</option>
</select>
</div>
<div class="form-group">
<label class="col-md-3 text-left">Business Justification:</label>
<textarea id="Description" name="BusinessJustification" style="width: 40%" rows="4" cols="20" resize="none" class="form-control" placeholder="Provide business justification." required="required" disabled></textarea>
</div>
</div>
<div class="form-group">
<div class="col-md-5">
<br />
<button id="btn-submit-user" type="submit" class="btn btn-success" asp-action="RequestAccessSubmit" disabled>Submit</button>
<button id="btn-cancel-request" type="button" class=" btn btn-danger" onclick="redirecttoHome(this); ">Cancel</button>
</div>
</div>
</div>
<br />
</form>
</div>
</div>
在上面,通過更改代碼, 成功更改了視圖以在第二個下拉菜單中接受多個輸入
<select class="form-control" asp-items="ViewBag.ContainerSelect" id="BusinessGroup" name="ContainerID" disabled>
至
<select class="form-control custom-select" multiple asp-items="ViewBag.ContainerSelect" id="BusinessGroup" name="ContainerID" disabled>
目標(需要幫助):
為應用程序/業務組下拉列表中選擇的每個值調用方法RequestAccessSubmit,而其他下拉列表中的值保持不變。
電流:
Javascript:
<script type="text/javascript">
$(function () {
$('#UserTypeID').on('change', null, null, function (e) {
getGroupsandApplications(e);
});
$('#RequestedPermission').on('change', null, null, function (e) {
ValidatePermissions(e);
});
$('#BusinessGroup').on('change', null, null, function (e) {
ValidatePermissions(e);
});
});
在這里,getGroupsandApplications()僅用於基於第一個下拉列表中的輸入來填充第二個和第三個下拉列表,因此可以放心地忽略它。 至於ValidatePermissions()javascript函數,它使用第二和第三下拉列表的當前值在控制器中調用ValidatePermissions()來驗證它們(請注意,此代碼在這兩個下拉列表中僅考慮一個值,因此需要進行修改 )-
function ValidatePermissions(e)
{
var businessGroupID = $('#BusinessGroup').val();
var requestedPermission = $('#RequestedPermission').val();
if (businessGroupID!='null') {
$.ajax({
url: '@Url.Action("ValidatePermissions")',
method: 'GET',
cache: false,
data: { containerID: businessGroupID, appPermissionID: requestedPermission },
success: handleSuccess
});
}
}
控制器:
ValidatePermissions()方法-
public JsonResult ValidatePermissions(int containerID, int appPermissionID)
{
//code to validate containerID and appPermissionID
var sampleRecord = new sampleModel();
sampleRecord = _context.Table_Abc
.FirstOrDefault(x => x.UserId.Equals(user.UserID) && x.ContainerId.Equals(containerID) && x.AppPermissionId.Equals(appPermissionID));
return Json(new
{
success = true
});
}
請注意,sampleModel控制在數據庫的Table_Abc中插入記錄所需的值。
RequestAccessSubmit()方法-
[HttpPost]
[Authorize]
public async Task<IActionResult> RequestAccessSubmit(sampleModel xyz)
{
//some code for variable user
var sampleRecord = new sampleModel();
sampleRecord = _context.Table_Abc.FirstOrDefault(x => x.UserId.Equals(user.UserID)
&& x.ContainerId.Equals(xyz.ContainerId)
&& x.AppPermissionId.Equals(xyz.AppPermissionId)
if (sampleRecord == null)
{
xyz.BusinessJustification = xyz.BusinessJustification;
//fills other needed information in the record
_context.Table_Abc.Add(xyz);
await _context.SaveChangesAsync();
}
return RedirectToAction("Index");
}
模型:
public class UserAccess
{
public string BusinessJustification { get; set; }
public int RequestAccessId { get; set; }
public int AppPermissionId { get; set; }
public int ContainerId { get; set; }
public GroupType GroupType { get; set; }
//rest of the columns in Table_Abc
}
方法:
若要修改上述代碼,以便調用控制器中的上述兩種方法,以便可以為containerId的不同值插入多個記錄
我終於找到了一個成功的解決方案。 最歡迎對此進行優化。
控制器:不變
型號:不變
視圖:表單更改-
<form method="post" asp-action="RequestAccessSubmit" id="form-submission-id">
至:
<form method="post" id="form-submission-id">
<select asp-items="ViewBag.ContainerSelect" id="BusinessGroup" class="form-control custom-select" multiple name="ContainerID" disabled>
至:
<select asp-items="ViewBag.ContainerSelect" id="BusinessGroup" class="form-control custom-select" multiple disabled>
<button id="btn-submit-user" type="submit" class="btn btn-success" asp-action="RequestAccessSubmit" disabled>Submit</button>
至
<button id="btn-submit-user" type="submit" class="btn btn-success" disabled>Submit</button>
簡而言之,我刪除了提交按鈕與控制器的RequestAccessSubmit方法的直接連接,並刪除了ContainerID列的第二個下拉菜單的值。
JavaScript更改:
添加了一個新功能來處理Submit按鈕的執行:
$("#btn-submit-user").click(function (event) {
event.preventDefault();
var businessGroupID = $('#BusinessGroup').val();
for (var i = 0; i < businessGroupID.length; i++) {
if (businessGroupID[i] != 'null') {
var requestObj = {
BusinessJustification : $('#Description').val(),
GroupTypeId : $('#UserTypeID').val(),
AppPermissionId : $('#RequestedPermission').val(),
ContainerId : businessGroupID[i]
};
$.ajax({
url: '@Url.Action("RequestAccessSubmit")',
type: 'POST',
data: { 'requestAccess': requestObj },
success: handleSuccess
});
}
}
});
將ValidatePermissions()腳本方法修改為:
function ValidatePermissions(e)
{
var businessGroupID = $('#BusinessGroup').val();
var requestedPermission = $('#RequestedPermission').val();
//validating each selected container id with the selected permission id
for (var i = 0; i < businessGroupID.length; i++)
{
if (businessGroupID[i] != 'null') {
$.ajax({
url: '@Url.Action("ValidatePermissions")',
method: 'GET',
cache: false,
data: { containerID: businessGroupID[i], appPermissionID: requestedPermission },
success: handleSuccess
});
}
}
}
我針對此要求的方法是強類型Model
綁定View
。 如果要保持數據庫上下文模型的原樣,則可以在Model類中使用繼承。 在此示例中,我的下拉列表和列表框具有硬編碼的值。 您可以根據自己的實現量身定制該要求。 所以我在這里:
該Model
如下所示:
using Microsoft.AspNetCore.Mvc.Rendering;
using System.Collections.Generic;
namespace SampleMultiSelectListExample.Models
{
//No touchy as per requirement
public class UserAccess
{
//Assumption: This is your textarea
public string BusinessJustification { get; set; }
//This is user type id
public int RequestAccessId { get; set; }
//This is requested permission id
public int AppPermissionId { get; set; }
//This is application/business group which is a multi select
public int ContainerId { get; set; }
//public GroupType GroupType { get; set; }
//rest of the columns in Table_Abc
}
//Make our class for our purpose. More of a viewmodel
public partial class UserAccessData : UserAccess
{
//These two variables are to hold only one value as per requirement
public string requestAccessId { get; set; }
public string appPermissionId { get; set; }
public MultiSelectList RequestAccessIdList { get; set; }
public MultiSelectList AppPermissionIdList { get; set; }
public MultiSelectList ContainerIdList { get; set; }
//Define multiselect list to capture multiple application/business role
public List<string> containerIds { get; set; }
//Define our constructor to get these values
public UserAccessData()
{
this.RequestAccessIdList = GetRequestAccessIdList(null);
this.AppPermissionIdList = GetAppPermissionIdList(null);
this.ContainerIdList = GetContainerIdList(null);
}
public MultiSelectList GetRequestAccessIdList(string[] selectedValues)
{
List<Common> getRequestAccessList = new List<Common>()
{
new Common() { ID = 1, Name= "User 1" },
new Common() { ID = 2, Name= "User 2" },
new Common() { ID = 3, Name= "User 3" },
new Common() { ID = 4, Name= "User 4" },
new Common() { ID = 5, Name= "User 5" },
new Common() { ID = 6, Name= "User 6" },
new Common() { ID = 7, Name= "User 7" }
};
return new MultiSelectList(getRequestAccessList, "ID", "Name", selectedValues);
}
public MultiSelectList GetAppPermissionIdList(string[] selectedValues)
{
List<Common> getAppPermissionList = new List<Common>()
{
new Common() { ID = 1, Name= "User 1" },
new Common() { ID = 2, Name= "User 2" },
new Common() { ID = 3, Name= "User 3" },
new Common() { ID = 4, Name= "User 4" },
new Common() { ID = 5, Name= "User 5" }
};
return new MultiSelectList(getAppPermissionList, "ID", "Name", selectedValues);
}
//This will multi selectable as per our view
public MultiSelectList GetContainerIdList(string[] selectedValues)
{
List<Common> getContainerList = new List<Common>()
{
new Common() { ID = 1, Name= "User 1" },
new Common() { ID = 2, Name= "User 2" },
new Common() { ID = 3, Name= "User 3" }
};
return new MultiSelectList(getContainerList, "ID", "Name", selectedValues);
}
}
//Generic class to match what a select list or dropdown list or combobox or radio box requires
public class Common
{
public int ID { get; set; }
public string Name { get; set; }
}
}
Controller
看起來像:
using System;
using Microsoft.AspNetCore.Mvc;
using SampleMultiSelectListExample.Models;
namespace SampleMultiSelectListExample.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
//Here we get our items as required
//UserAccessData useraccessdata = new UserAccessData();
//If you are getting your data from a db, you can do something like this
//useraccessdata.ContainerIdList = GetAllContainerId(null);
//useraccessdata.RequestAccessIdList = GetAllRequestAccessId(null);
//useraccessdata.AppPermissionIdList= GetAllAppPermissionIdList(null);
//Now since I am hardcoding these values, I can directly send my model to the view to render
return View(new UserAccessData());
}
//Just an example implementation of how this would look via a webservice:
//private MultiSelectList GetAllContainerId(string[] selectedValues)
//{
// //Just an example using HttpClient to call a webservice to get this data.
// var client = clientFactory.CreateClient(baseAPIUrl);
// var containerIdDTO = httpClient.GetAsync<UserDtoList>(new Uri(new Uri(baseAPIUrl), $"Master/getUserDto").AbsoluteUri).Result;
// //return containerIdDTO.data;
// List<Common> allContainerIds = new List<Common>();
// foreach (var item in containerIdDTO)
// {
// Common common = new Common();
// common.ID = item.id;
// common.Name = item.fullName;
// allContainerIds.Add(common);
// }
// return new MultiSelectList(allContainerIds, "ID", "Name", selectedValues);
//}
//Now process your selected data as required
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult ProcessInformation(UserAccessData useraccessdata)
{
//Our main model which is untouched
UserAccess user = new UserAccess();
user.AppPermissionId = Convert.ToInt32(useraccessdata.appPermissionId);
user.RequestAccessId = Convert.ToInt32(useraccessdata.requestAccessId);
user.BusinessJustification = useraccessdata.BusinessJustification;
//Now for every container list, do your processing
foreach(var containerid in useraccessdata.containerIds)
{
//Insert in your DB here
//var insert = CallDBInsert(user);
}
return View();
}
}
}
並且View
如下所示:
@using SampleMultiSelectListExample.Models
@model UserAccessData
@{
ViewData["Title"] = "Home Page";
}
<div class="panel-heading">
<h2>Sample MultiSelectList Example</h2>
</div>
<div class="row">
<br />
<div id="newAccess">
<div>
<br />
@using (Html.BeginForm("ProcessInformation", "Home", FormMethod.Post, new { @id = "form-submission-id", @class = "" }))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<div class="form-group">
<label class="col-md-3 text-left">User Type:</label>
@Html.DropDownListFor(m => m.requestAccessId, Model.RequestAccessIdList, new { @id= "UserTypeID", @class = "form-control", placeholder = "Select User Type", @required = "required", @autocomplete = "off" })
</div>
<div class="form-group">
<label class="col-md-3 text-left">Application/Business Group:</label>
@Html.ListBoxFor(m => m.containerIds, Model.ContainerIdList, new { @id = "ContainerID", @name = "choices-multiple-remove-button", @class = "form-control", placeholder = "Select Application/Business Group", @required = "required", @autocomplete = "off", @multiple = "multiple" })
</div>
<div class="form-group">
<label class="col-md-3 text-left">Requested Permissions:</label>
@Html.DropDownListFor(m => m.appPermissionId, Model.AppPermissionIdList, new { @id = "AppPermissionID", @class = "form-control", placeholder = "Select Requested Permission", @required = "required", @autocomplete = "off" })
</div>
<div class="form-group">
<label class="col-md-3 text-left">Business Justification:</label>
@Html.TextAreaFor(m => m.BusinessJustification, new { @id = "Description", @class = "form-control", placeholder = "Provide business justification", @cols="20",@rows="4",@resize="none", @required = "required", @autocomplete = "off" })
</div>
</div>
<div class="form-group">
<div class="col-md-5">
<br />
<button id="btn-submit-user" type="submit" class="btn btn-success">Submit</button>
<button id="btn-cancel-request" type="button" class=" btn btn-danger" onclick="location.href='@Url.Action("Index", "Home")'">Cancel</button>
</div>
</div>
}
</div>
<br />
</div>
</div>
您可以在我的GitHub 存儲庫中找到該項目。
希望這對有類似要求的人有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.