Razor webgrid get selected row data - razor

In my Razor view, I have this webgrid:
#{
var grid = new WebGrid(Model, canPage: false, selectionFieldName: "VendorClassID", canSort:false);
}
#grid.GetHtml(
headerStyle: "header",
htmlAttributes: new{id = "tableGrid"},
tableStyle: "webgrid",
selectedRowStyle: "webgrid-selected-row",
columns: grid.Columns(
grid.Column(header: "Select", format: #<text>#item.GetSelectLink("Select")</text>),
grid.Column("ClassID", "ID"),
grid.Column("ClassNum", "Class Num"),
grid.Column("Description")
)
)
#if (grid.HasSelection)
{
var x = #grid.SelectedRow;
}
It's my understanding that when I click the generated "select" link, the page posts back and the URL gets a parameter "VendorClassID = selectrowindex" added on. However, the value of the parameter seems to be the index of the selected row, which isn't particularly useful to me. Is there anyway to have the parameter value be set to a value from the selected row (ClassID, etc)? The #grid.SelectedRow doesn't seem to know anything about the row's data either, but I am new to MVC so perhaps there is a way to get the row data from there?

I found the solution, I got the data I wanted (VendorClassID), by using
#if (grid.HasSelection)
{
var x = grid.SelectedRow.Value.VendorClassID;
//logic
}
VendorClassID is an attribute of my VendorClass. The page has a list of VendorClasses for its Model

Model:
public class SchemeDetailsModel
{
[Display(Name = "File Name")]
public string FileName { get; set; }
public Int64 FileId { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
[Display(Name = "Scheme Id")]
public int SchemeId { get; set; }
public string Status { get; set; }
[Display(Name="Validation Error Report")]
public string ValidationErrorReport { get; set; }
}
Controller:
[HttpGet]
public ActionResult History()
{
if (ModelState.IsValid)
{
List<SchemeDetailsModel> objSchemeDetails = new List<SchemeDetailsModel>();
string employerId = Session["EmployerId"].ToString();
objSchemeDetails = _repository.getSchemeDetails(employerId);
return View(objSchemeDetails);
}
return View();
}
Repository:
public List<SchemeDetailsModel> getSchemeDetails(string employerId)
{
List<SchemeDetailsModel> objDetails = new List<SchemeDetailsModel>();
var query = (from efd in _context.EmployerFileDatas
//where efd.EmployerId == employerId
orderby efd.FileName
select new
{
efd.FileName,
efd.Timestamp,
//efhd.SchemeId,
efd.ValidationStatus
}).ToList();
//join efhd in _dataContext.EmployerFileHeaderDetails on efd.EmployerId equals efhd.EmployerId
if(query!=null)
{
foreach (var item in query)
{
objDetails.Add(new SchemeDetailsModel { FileName = item.FileName, Date = item.Timestamp, Status = item.ValidationStatus, ValidationErrorReport = "View" });
}
return objDetails;
}
View:
#model IEnumerable<EFITestHarness.Models.SchemeDetailsModel>
#using System.Web.Helpers;
#{
ViewBag.Title = "SchemeDetails";
Layout = "~/Views/Shared/_Layout.cshtml";
var grid = new WebGrid(Model, canPage: true, rowsPerPage: 4, selectionFieldName: "selectedRow"); grid.Pager(WebGridPagerModes.NextPrevious);
}
<table>
<tr>
<td>#Html.ActionLink("Back", "FileUpload", "Home", null, new { #class = "form-control" })
</td>
</tr>
</table>
<div id="gridContent" class="webGridWrapper">
#grid.GetHtml(tableStyle: "webGrid",
footerStyle: "foot",
headerStyle: "webGridHeader",
alternatingRowStyle: "webGridAlt",
selectedRowStyle: "select",
columns: grid.Columns(
grid.Column("FileName"), //the model fields to display
grid.Column("Date"),
grid.Column("SchemeId"),
grid.Column("Status"),
grid.Column("ValidationErrorReport", format: (item => Html.ActionLink((string)(#item.ValidationErrorReport).ToString(), "ValidationResults", new { fileName = #item.FileName })))
))
</div>
Controller:
[HttpGet]
public ActionResult ValidationResults(string fileName)
{
Session["FileName"] = fileName;
if (ModelState.IsValid)
{
List<ValidationResultsModel> objValidationResults = new List<ValidationResultsModel>();
string employerId = Session["EmployerId"].ToString();
objValidationResults = _repository.getValidationResultsDetails(101);
if (objValidationResults.Count() > 0)
{
//var dataGrid = new GridView();
Session["results"] = objValidationResults;
//dataGrid.DataSource = objValidationResults;
//dataGrid.DataBind();
return View(objValidationResults);
}
else
return PartialView("~/Views/Results.cshtml");
}
return View();
}
Model:
public class ValidationResultsModel
{
public string NINO { get; set; }
public DateTime? DOB { get;set;}
public string Transaction { get;set; }
public string Element { get;set; }
public string ErrorMessage { get; set; }
}
View:
#model IEnumerable<EFITestHarness.Models.ValidationResultsModel>
#using System.Web.Helpers;
#{
ViewBag.Title = "ValidationResults";
Layout = "~/Views/Shared/_Layout.cshtml";
var grid = new WebGrid(Model, canPage: true, rowsPerPage:2, selectionFieldName: "selectedRow"); grid.Pager(WebGridPagerModes.NextPrevious);
}
#using (Html.BeginForm("ValidationResults", "Home", new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<table>
<tr>
<td>#Html.ActionLink("Back", "History", "Home", null, new { #class = "form-control" })
</td>
</tr>
</table>
<div class="container-fluid" style="font-size:medium;color:blue;">
Validation Results: </div>
<div style="font-size:medium;color:black;">1.Error Message<br />
</div>
<div id="gridContent" class="webGridWrapper">
#grid.GetHtml(tableStyle: "webGrid",
footerStyle: "foot",
headerStyle: "webGridHeader",
alternatingRowStyle: "webGridAlt",
selectedRowStyle: "select",
columns: grid.Columns(
grid.Column("NINO"), //the model fields to display
grid.Column("DOB"),
grid.Column("Transaction"),
grid.Column("Element"),
grid.Column("ErrorMessage", style: "description")
))
</div>
}
<div style="font-size:medium;color:black;">
Select the Button below to Download the Validation error Report
</div>
<div>
<input type="button" class="btn btn-primary btn-md" value="Download" onclick="#("window.location.href='" + #Url.Action("Download", "Home") + "'");" />
</div>
Controller:
[HttpGet]
public ActionResult Download()
{
var dataGrid = new GridView();
dataGrid.DataSource = Session["results"];
dataGrid.DataBind();
/*Code to eport the detail in excel sheet format*/
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename='" + Session["FileName"] + "'.xls");
Response.ContentType = "application/ms-excel";
Response.Charset = "";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
dataGrid.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
return View();
}
partial view:
#{
ViewBag.Title = "ValidationResults";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<table>
<tr>
<td>
#Html.ActionLink("Back", "History", "Home", null, new { #class = "form-control" })
</td>
</tr>
</table>
<div class="container-fluid" style="font-size:medium;color:blue;">
Validation Results:
</div>
<div style="font-size:medium;color:black;">
1.Successful Message<br />
</div>
}

Related

How to change culture class programmatically (Calling implemented Switch)

I have implemented culture in my system. The change with selected combox works fine.
[
[
Now I want depending on User Language to change the language.
I read other descriptions but I can't get it to work.
======================= My switch class Model ===================
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
namespace WorkCollaboration.Models
{
public class SwitchCultureModel
{
public CultureInfo CurrentUICulture { get; set; }
public List<CultureInfo> SupportedCultures { get; set; }
}
}
I have a general logon service where I check user privileges languages....
In the system I created a page were I want to change User language session and so on.
This is how my page looks like
[
========= This is my razor page ==========
#page
#using Microsoft.AspNetCore.Localization
#using Microsoft.AspNetCore.Mvc.Localization
#model WorkCollaboration.Pages.LogonService.LanguageModel
#{
ViewData["Title"] = "UserLanguage";
}
#inject IViewLocalizer Localizer
<h1>#Localizer["Edit"]</h1>
<h4>#Localizer["LogonService"]</h4>
<p>
<a asp-page="/LogonService/IndexLanguage">#Localizer["Back to Index"]</a>
</p>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="LogonService.WorkColUserMail" />
<input type="hidden" asp-for="LogonService.WorkColUserId" class="form-control" />
<input type="hidden" asp-for="LogonService.WorkColUserPassword" class="form-control" />
<input type="hidden" asp-for="LogonService.WorkColUserPasswordConfirm" class="form-control" />
<input type="hidden" asp-for="LogonService.WorkColUserName" class="form-control" />
<input type="hidden" asp-for="LogonService.WorkColUserVerificationMode" class="form-control" />
<input type="hidden" asp-for="LogonService.WorkColEnteredPassword" class="form-control" />
<input type="hidden" asp-for="LogonService.WorkColLoggedIn" class="form-control" />
<div class="form-group">
#Html.LabelFor(model => model.LogonService.WorkColUserLanguage, htmlAttributes: new { #class = "form-group" })
<div class="form-group">
#Html.DropDownListFor(model => model.LogonService.WorkColUserLanguage, new List<SelectListItem>
{
new SelectListItem {Text = "DE", Value = "DE", Selected = true },
new SelectListItem {Text = "EN", Value = "EN" },
}, new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.LogonService.WorkColUserLanguage, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-page="/LogonService/IndexLanguage">#Localizer["Back to List"]</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
In c# I call the following threds
if (LogonService.WorkColUserLanguage == "DE")
{
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture("de");
Thread.CurrentThread.CurrentUICulture = new
CultureInfo("de");
}
if (LogonService.WorkColUserLanguage == "EN")
{
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture("en");
Thread.CurrentThread.CurrentUICulture = new
CultureInfo("en");
}
However the page language continues on same language
==========Here my c# code ======================
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualBasic;
using WorkCollaboration.Data;
using WorkCollaboration.Models;
using System.Collections;
using System.Web;
namespace WorkCollaboration.Pages.LogonService
{
public class LanguageModel : PageModel
{
private readonly WorkCollaboration.Data.WorkCollaborationContext _context;
public LanguageModel(WorkCollaboration.Data.WorkCollaborationContext context)
{
_context = context;
}
[BindProperty]
public Models.LogonService LogonService { get; set; }
public async Task<IActionResult> OnGetAsync(string id)
{
if (id == null)
{
return NotFound();
}
LogonService = await _context.LogonService.FirstOrDefaultAsync(m => m.WorkColUserMail == id);
if (LogonService == null)
{
return NotFound();
}
return Page();
}
// To protect from overposting attacks, enable the specific properties you want to bind to, for
// more details, see https://aka.ms/RazorPagesCRUD.
public async Task<IActionResult> OnPostAsync()
{
string id = LogonService.WorkColUserMail;
byte[] ep = LogonService.WorkColEnteredPassword;
string ln = LogonService.WorkColUserLanguage;
string SessionKeyName = "_Name";
string SessionKeyId = "_Id";
string SessionKeyDate = "_Date";
string SessionKeyLang = "_Lang";
if (id == null)
{
return NotFound();
}
//====================================
// Load WorColUser Data with Mail Key
//====================================
LogonService = await _context.LogonService.FirstOrDefaultAsync(m => m.WorkColUserMail == id);
//====================================
// Overwrite Data with GUI Data
//====================================
LogonService.WorkColEnteredPassword = ep;
LogonService.WorkColUserLanguage = ln;
LogonService.WorkColLoggedIn = true;
//====================================
// Create SessionID
//====================================
DateTime now = DateTime.Now;
string valueSystemKeyDates = now.ToString("yyyymmddhh:mm:ss");
HttpContext.Session.SetString(SessionKeyDate, valueSystemKeyDates);
HttpContext.Session.SetString(SessionKeyId, Convert.ToString(LogonService.WorkColUserId));
HttpContext.Session.SetString(SessionKeyName, LogonService.WorkColUserMail);
HttpContext.Session.SetString(SessionKeyLang, LogonService.WorkColUserLanguage);
var SessionIdDate = HttpContext.Session.GetString(SessionKeyDate);
var SessionIdId = HttpContext.Session.GetString(SessionKeyId);
var SessionIdName = HttpContext.Session.GetString(SessionKeyName);
var SessionIdLang = HttpContext.Session.GetString(SessionKeyLang);
LogonService.WorkColUserSessionId = Strings.RTrim(SessionIdDate) + " " + Strings.RTrim(SessionIdName) + " " + Strings.RTrim(SessionIdId) + " " + Strings.RTrim(SessionIdLang);
//=========================================
// Change Culture on specific user language
//=========================================
if (LogonService.WorkColUserLanguage == "DE")
{
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture("de");
Thread.CurrentThread.CurrentUICulture = new
CultureInfo("de");
}
if (LogonService.WorkColUserLanguage == "EN")
{
Thread.CurrentThread.CurrentCulture =
CultureInfo.CreateSpecificCulture("en");
Thread.CurrentThread.CurrentUICulture = new
CultureInfo("en");
}
if (!ModelState.IsValid)
{
return Page();
}
_context.Attach(LogonService).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!LogonServiceExists(LogonService.WorkColUserMail))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToPage("/LogonService/IndexLanguage");
}
private bool LogonServiceExists(string id)
{
return _context.LogonService.Any(e => e.WorkColUserMail == id);
}
}
}
Tks for helping
==============================================================================
Update: 25.1.2021: I investigated further why my culture defined values do not work. And I found the reason why. In my SwithCulturViewComponent.cs The culture is on every page load or exited refreshed to the one defined in the languages in the combo (see Pic 1 or 2)
Now I tried to influence the switch class by setting the culture info from the user language from the session.
=================== SwitchCultureViewComponet ===============
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using WorkCollaboration.Models;
namespace WorkCollaboration.ViewComponents
{
public class SwitchCultureViewComponent : ViewComponent
{
private readonly IOptions<RequestLocalizationOptions> localizationOptions;
public SwitchCultureViewComponent(IOptions<RequestLocalizationOptions> localizationOptions)
{
this.localizationOptions = localizationOptions;
}
public IViewComponentResult Invoke()
{
//=============================================
// Get Session Language
//=============================================
string SessionKeyName = "_Name";
string SessionKeyId = "_Id";
string SessionKeyDate = "_Date";
string SessionKeyLang = "_Lang";
var SessionIdDate = HttpContext.Session.GetString(SessionKeyDate);
var SessionIdId = HttpContext.Session.GetString(SessionKeyId);
var SessionIdName = HttpContext.Session.GetString(SessionKeyName);
var SessionIdLang = HttpContext.Session.GetString(SessionKeyLang);
if (SessionIdId == null)
{
SessionIdId = "0";
}
if (SessionIdId == "")
{
SessionIdId = "0";
}
if (SessionIdLang == null)
{
SessionIdLang = "DE";
}
if (SessionIdLang == "")
{
SessionIdLang = "DE";
}
//=========================================
// Change Culture on specific user language
//=========================================
if (SessionIdLang == "DE")
{
CultureInfo myCIintl = new CultureInfo("de-CH", false);
CultureInfo current = CultureInfo.CurrentCulture;
Console.WriteLine("The current culture is {0}", current.Name);
CultureInfo newCulture;
newCulture = new CultureInfo("de-CH");
CultureInfo.CurrentCulture = newCulture;
Console.WriteLine("The current culture is now {0}",
CultureInfo.CurrentCulture.Name);
CultureInfo.CurrentUICulture = new CultureInfo("de-CH", false);
// CultureInfo.CurrentUICulture = CultureInfo.CreateSpecificCulture("de-CH");
Console.WriteLine("CurrentUICulture is now {0}.", CultureInfo.CurrentUICulture.Name);
}
if (SessionIdLang == "DE")
{
CultureInfo myCIintl = new CultureInfo("en-US", false);
CultureInfo current = CultureInfo.CurrentCulture;
Console.WriteLine("The current culture is {0}", current.Name);
CultureInfo newCulture;
newCulture = new CultureInfo("en-US");
CultureInfo.CurrentCulture = newCulture;
Console.WriteLine("The current culture is now {0}",
CultureInfo.CurrentCulture.Name);
CultureInfo.CurrentUICulture = new CultureInfo("en-US", false);
// CultureInfo.CurrentUICulture = CultureInfo.CreateSpecificCulture("de-CH");
Console.WriteLine("CurrentUICulture is now {0}.", CultureInfo.CurrentUICulture.Name);
}
// How can I influence this code below. I only want this to be executed when I change the UI language code in the dropdown
// Otherwise it should use the custure Info from the above user languages
var cultureFeature = HttpContext.Features.Get<IRequestCultureFeature>();
var model = new SwitchCultureModel
{
SupportedCultures = localizationOptions.Value.SupportedUICultures.ToList(),
CurrentUICulture = cultureFeature.RequestCulture.UICulture
};
return View(model);
}
}
}
How can I influence this code below? I only want this to be executed when I change the UI language code in the dropdown
Otherwise it should use the culture Info from the above user languages
Whenever I try to CurrentUICuture within the "var"...
============ Section in the SwitchViewComponent.cs ==============
var model = new SwitchCultureModel
{
SupportedCultures =
localizationOptions.Value.SupportedUICultures.ToList(),
CurrentUICulture = cultureFeature.RequestCulture.UICulture
};
return View(model);
I get errors. Thank you for your support

Get value from selected option and pass it to the function

Hi im making a reservation page in razor pages asp.net. On my page I have two drop downlist. One for the location other for the rooms of that specific location. I want to pass the value of that selected location to the function which shows the rooms (function is named showRoom()), so that the rooms will be shown depending on which location you selected. How do i do that with html? I tried something but didnt really work. Here is the html code
<td>Select location</td>
<div class="form-group">
<select id="locations" name="Location">
#foreach(var reservations in #Model.PopulateReservations())
{
<option>#Html.DisplayFor(m => reservations.LocationName)</option>
}
</select>
</div>
<td>Select Room</td>
<div class="form-group">
<select id="rooms" name="Room">
#foreach(var reservations in #Model.ShowRoom(string LocationName))
{
<option>#Html.DisplayFor(m => reservations.RoomName)</option>
}
</select>
</div>
Here is the function showRoom
public List<WorkspaceModel> ShowRoom(string loc)
{
var cs = Database.Database.Connector();
List<WorkspaceModel> res = new List<WorkspaceModel>();
using var con = new NpgsqlConnection(cs);
{
string query = "Select room FROM workspaces WHERE location = '"+ loc +"'";
using NpgsqlCommand cmd = new NpgsqlCommand(query, con);
{
cmd.Connection = con;
con.Open();
using (NpgsqlDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
res.Add(new WorkspaceModel { RoomName = dr["room"].ToString() });
}
}
con.Close();
}
}
Here is a demo(I use fake data to test):
class:
public class PopulateReservation
{
public string LocationName { get; set; }
}
public class WorkspaceModel
{
public string RoomName { get; set; }
}
TestDropDown.cshtml:
<td>Select location</td>
<div class="form-group">
<select id="locations" name="Location">
#foreach (var reservations in #Model.PopulateReservations)
{
<option>#Html.DisplayFor(m => reservations.LocationName)</option>
}
</select>
</div>
<td>Select Room</td>
<div class="form-group">
<select id="rooms" name="Room">
#foreach (var reservations in #Model.Rooms)
{
<option>#Html.DisplayFor(m => reservations.RoomName)</option>
}
</select>
</div>
<form>
#Html.AntiForgeryToken()
</form>
#section scripts{
<script>
$('#locations').on('change', function () {
var arr = [];
$.ajax({
type: "POST",
url: '?handler=ShowRoom',
headers: {
RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
},
data: { "loc": $("#locations").val() },
dataType:"json"
}).done(function (data) {
$("#rooms").empty();
$.each(data, function (i, item) {
$("#rooms").append('<option> ' + item["roomName"] + ' </option>');
});
});
});
</script>
}
TestDropDown.cshtml.cs:
public class TestDropDownModel : PageModel
{
[BindProperty]
public List<PopulateReservation> PopulateReservations { get; set; }
[BindProperty]
public List<WorkspaceModel> Rooms { get; set; }
public IActionResult OnGet()
{
PopulateReservations = new List<PopulateReservation> {
new PopulateReservation { LocationName = "location1" },
new PopulateReservation { LocationName = "location2" },
new PopulateReservation { LocationName = "location3" }
};
Rooms = new List<WorkspaceModel> {
new WorkspaceModel { RoomName = "Room1" },
new WorkspaceModel { RoomName = "Room2" },
new WorkspaceModel { RoomName = "Room3" },
};
return Page();
}
public IActionResult OnPost()
{
return Page();
}
public IActionResult OnPostShowRoom(string loc)
{
List<WorkspaceModel> l= new List<WorkspaceModel> {
new WorkspaceModel { RoomName = loc + "Room1" },
new WorkspaceModel { RoomName = loc + "Room2" },
new WorkspaceModel { RoomName = loc + "Room3" },
};
return new JsonResult(l);
}
}
result:

How to pass value selected from DropDownList to Controller - MVC

I am having trouble getting the value selected in my dropdownlist in my Homecontroller. I have the DropDownList in a form but I think my format may be wrong. I'm new to MVC and new to HTML so I'm struggling pretty hard. Would appreciate some help.
Here is my controller (I put this in my homecontroller, is that a bad idea?):
public IActionResult Index()
{
_ = new List<MyjsonSettings>();
var obj = new StatusPortController(configuration);
List<MyjsonSettings> PortList = obj.GetPortNum();
List<SelectListItem> AppNameList = PopulateDropDown(PortList);
ViewData["Applications"] = AppNameList;
return View("~/Views/Home/dataview.cshtml");
}
public List<SelectListItem> PopulateDropDown(List<MyjsonSettings> PortList)
{
List<SelectListItem> AppNameList = new List<SelectListItem>();
for (int i = 0; i < PortList.Count(); i++)
{
AppNameList.Add(new SelectListItem {
Text = PortList[i].NAME, Value = (i+1).ToString()
});
}
return AppNameList;
}
Here is the view (dataview.cshtml):
#{
ViewData["Title"] = "Home Page";
}
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.DropDownList("Applications", ViewData["AppNameList"] as List<SelectListItem>)
<input type="submit" value="submit" />
}
Any ideas? No errors when I run, I just don't know how to get the response back.
you can rebuild the structure to a more usable way, and in order to submit form with drop down list or any type of fields you need to first return a view with Model and then submit the form to an action that receive same Model type as parameter
example:
model:
public class ApplicationsAddModel {
public ApplicationsAddModel (){
//constructer to initialize the list
ApplicationsList = new List<SelectListItem>();
}
public string test{ get; set; }
public int selectedApplicationId { get; set; }
public List<SelectListItem> ApplicationsList { get; set; }
}
controller
//this is the first action that return the model
[HttpGet]
public IActionResult Index()
{
ApplicationsAddModel model = new ApplicationsAddModel ();
//fill your drop down list
List<SelectListItem> AppNameList = PopulateDropDown(PortList);
model.ApplicationsList = AppNameList;
return View(model);
}
[HttpPost] //recive the form
public IActionResult Index(ApplicationsAddModel SubmittedModel)
{
var selectedApplication = SubmittedModel.selectedApplicationId; //get the selected value from ddl
//fill your drop down list
List<SelectListItem> AppNameList = PopulateDropDown(PortList);
model.ApplicationsList = AppNameList;
return View(SubmittedModel);
}
view (index.cshtml):
#model projectName.ApplicationsAddModel
#{ ViewData["Title"] = "Home Page"; }
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.LabelFor(m => m.selectedApplicationId)
#Html.DropDownListFor(m => m.selectedApplicationId, Model.ApplicationsList, "---", new { #class = "custom-select form-control" })
<input type="submit" value="submit" />
}
summary:
in MVC when you have to submit data to controller, create your model, go to controller and create your first action (GET) which fill the form with initial data and fill your drop down lists if exist, then create the (POST) action which receive the model of same type of the view and MVC will bind it automatically for you
best regards

MVC view code for bool type input

In one of my first MVC projects I encountered the following part of code in my "Create" view.
<div class="form-group">
#Html.LabelFor(model => model.Attend, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.Attend)
#Html.ValidationMessageFor(model => model.Attend, "", new { #class = "text-danger" })
</div>
</div>
</div>
This was scaffolded based on the following property in my model:
public virtual bool? Attend { get; set; }
What this will show for me on the "Create" view is a dropdown with the following values: Not Set; True; False;
Is there a way I can change these values in the dropdownlist for my bool so that it says something more readable/understandable for a user like: Yes; No;?
I tried to search for a solution and I think it has something to do with the following line:
#Html.EditorFor(model => model.Attend)
As #Stephen Muecke said you can create your own selectlist. You can do it with your own editor template .
Here is how i have done it:
Create EditorTeplates folder in Views/Shared
Create YesNoNotSelected.cshtml in this folder with this code:
#model bool?
#Html.DropDownList("", new SelectListItem[]
{
new SelectListItem()
{
Text = "Not set",
Value = String.Empty,
Selected = !Model.HasValue
},
new SelectListItem()
{
Text = "True",
Value = "true",
Selected = Model.HasValue && Model.Value
},
new SelectListItem()
{
Text = "False",
Value = "false",
Selected = Model.HasValue && !Model.Value
}
})
In your model add UIHintAttribute above Attend property like this:
[UIHint("YesNoNotSelected")]
public virtual bool? Attend { get; set; }
Now EditorFor helper should render your property according to this template.
I like the best of all worlds scenario:
I don't want to always require a UIHint
I don't want to use UIHint at all, it's not descriptive
I want bools to be extensible; yes/no, true/false, etc
Here is how I implemented it:
/Models/BooleanType.cs
public enum BooleanDisplay
{
undefined = 0,
YesNo = 1,
TrueFalse = 2,
GoodEvil = 3
}
/MVC/UIBooleanType.cs
[AttributeUsage(AttributeTargets.Property)]
public class UIBooleanAttribute : UIHintAttribute
:base("boolean", "MVC")
{
public UIBoolean(BooleanType displayAs)
{
DisplayAs = displayAs;
}
public BooleanDisplay DisplayAs { get; set; }
}
/Views/Shared/EditorTemplates/boolean.cshtml
#model boolean?
#{
// default
var displayAs = BooleanDisplay.TrueFalse;
var uiBoolean = ViewData
.ModelMetadata
.ContainerType
.GetProperty(ViewData.ModelMetadata.PropertyName)
.GetCustomAttributes(typeof(UIBooleanAttribute))
.Select(ca => ca as UIBooleanAttribute)
.FirstOrDefault(ca => ca != null);
if (uiBoolean != null)
{
displayAs = uiBoolean.DisplayAs;
}
var values = new List<SelectListItem>()
{
new SelectListItem()
{
Text = "Not set",
Value = String.Empty,
Selected = !Model.HasValue
}
};
switch(displayAs)
{
default:
throw new NotImplementedException(displayAs.ToString()
+ " is not implemented in boolean.cshtml";
YesNo:
values.Add(new SelectListItem()
{
Text = "Yes",
Value = "true",
Selected = Model.HasValue && Model.Value
});
values.Add(new SelectListItem()
{
Text = "No",
Value = "false",
Selected = Model.HasValue && !Model.Value
});
TrueFalse:
// etc
}
}
#Html.DropDownList("", values)
usage:
ViewModel:
public class Person
{
// defaults to True/False
public bool AreYouHappy { get; set; }
[UIBoolean(BooleanDisplay.GoodEvil)]
public bool IsInherently { get; set; }
}
View:
#model Person
#Html.EditorFor(p => p.AreYouHappy)
#Html.EditorFor(p => p.IsInherently)

How can I override the name attribute of a RadioButtonFor?

I'm trying to group together radiobuttons that are creating using a for loop and Razor syntax. Here is the code:
#for (var i = 0; i < Model.Sessions.Count(); i++)
{
#Html.HiddenFor(it => it.Sessions[i].Id)
#Html.RadioButtonFor(it => it.Sessions[i].Checkbox, "0", new {#class = "Sessions", #id = id, #name="Sessions"})
#Html.LabelFor(it => it.Sessions[i].Name, Model.Sessions[i].Name)
<span class="time-span"><em>#Model.Sessions[i].StartTime</em><em>#Model.Sessions[i].EndTime</em></span>
<br />
}
The third line inside the for loop is where the problem is. Basically the name doesn't change and it's always "Sessions[x].Checkbox". The checkbox is a property (bool) of a custom class. I can't seem to get the hang of debugging Razor stuff, so any help would be greatly appreciated, I'm guessing this will be extremely obvious to someone here.
EDIT
Dimitrov's post helped a lot. Below is the final code I used. I use the #class and #id attributes to be able to use Javascript to select the session originally picked (since this is an edit, not create form).
#for (var i = 0; i < Model.Sessions.Count(); i++)
{
#Html.HiddenFor(it => it.Sessions[i].Id)
var SId = #Model.Sessions[i].Id;
#Html.RadioButtonFor(it => it.selectedSession, Model.Sessions[i].Id, new { id = SId, #class = "Sessions" })
#Html.LabelFor(it => it.Sessions[i].Name, Model.Sessions[i].Name)
<span class="time-span"><em>#Model.Sessions[i].StartTime</em><em>#Model.Sessions[i].EndTime</em></span>
<br />
}
If you want to be able to select only a single radio button you need to have a single property on your view model to hold the selected session id, like this:
public class SessionViewModel
{
public int SelectedSessionId { get; set; }
public IList<Session> Sessions { get; set; }
}
public class Session
{
public int Id { get; set; }
public string Name { get; set; }
}
and then have a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new SessionViewModel
{
SelectedSessionId = 2,
Sessions = Enumerable.Range(1, 5).Select(x => new Session
{
Id = x,
Name = "session" + x,
}).ToList()
};
return View(model);
}
[HttpPost]
public ActionResult Index(SessionViewModel model)
{
return Content("Thank you for selecting session id: " + model.SelectedSessionId);
}
}
and finally a view:
#model SessionViewModel
#using (Html.BeginForm())
{
for (var i = 0; i < Model.Sessions.Count(); i++)
{
#Html.HiddenFor(x => x.Sessions[i].Id)
#Html.RadioButtonFor(x => x.SelectedSessionId, Model.Sessions[i].Id, new { id = "session_" + i })
#Html.Label("session_" + i, Model.Sessions[i].Name)
<br/>
}
<button type="submit">OK</button>
}