How to populate a class with a C# String List - c#

In the system I'm developing I send a select with multiple options to a string type list in my controller, I now need to link this list that I get from the view to the list with the login class I have in my model. The goal is that each position in the string list becomes a position in the new list.
For example I get the following list with the values that were sent from the view select:
[0] = "147"
[1] = "33"
I need to link this array to my other login list, something like this
Login[0] = "147
Login[1] = "33"
I'll put my codes with comments to explain it better:
View:
<select class="selectpicker" multiple data-live-search="true" asp-for="ListResponsibles">
<option value="147">John</option>
<option value="212">Maria</option>
<option value="33">Luiza</option>
</select>
Model:
//Here I get the options marked in the select
public List<string>ListResponsibles { get; set; }
//I want to pass the list I received from the view to this list
public List<Responsibles> ListResponsiblesData { get; set; }
public class Responsibles
{
public string Login { get; set; }
}
Controller:
public async Task<IActionResult> RegisterTask([FromForm] WebdeskTasks webdeskTasks)
{
//I created this variable to receive data from the other list
var LoginList = webdeskTasks.ListResponsiblesData;
//Here I tried to link each possibility of the view's list array to my list, but it doesn't show value in webdeskTarefas.ListResponsibles [i]
for (int i = 0; i < webdeskTasks.ListResponsibles.Count; i++)
{
LoginList[i].Login = webdeskTasks.ListResponsibles[i];
}

Or the LINQish way:
public async Task<IActionResult> RegisterTask([FromForm] WebdeskTasks webdeskTasks)
{
webdeskTasks.ListResponsiblesData = webdeskTasks.ListResponsibles
.Select(entry => new Responsible { Login = entry })
.ToList();
//....
}

You can try following code:
public async Task<IActionResult> RegisterTask([FromForm] WebdeskTasks webdeskTasks)
{
var LoginList = new List<Responsibles>();
foreach (string i in webdeskTasks.ListResponsibles)
{
Responsibles re = new Responsibles();
re.Login = i;
LoginList.Add(re);
}
webdeskTasks.ListResponsiblesData = LoginList;
//....
}

Related

How to select values inside list?

How to select values inside MultiSelect? I just want to select some items inside a dropdownlist from URL Variables
Issue: following line is not selecting items Colors.add(TempArray[i]);
debug: If I remove this line than it works ok and selects values. if (!string.IsNullOrEmpty(result)) ... foreach (var item2 in TempArray) but I need this line to check for null values. Code will get error otherwise
Also If I remove Post Method and it goes to Get directly than it works fine (items get selected). how can I make it work by using post method
Form
<form asp-page="./Index" method="post">
<select asp-for="Colors" asp-items="#Model.Colors_SELECT " class="MultiSelect" multiple>
....
</select>
...
back-end variables
[BindProperty(SupportsGet = true)]
public List<string>? Colors { get; set; }
public SelectList? Colors_SELECT { get; set; }
OnPost() Method - here I am change the URL format. for ex: localhost/index?Colors=red&Colors=Black to localhost/index?Colors=red,Black
public async Task<IActionResult> OnPostAsync()
{
var CurrentFilters = new Dictionary<string, string>();
var ColorsTemp = string.Join(",", Colors);
CurrentFilters.Add("Colors", ColorsTemp);
string query = "";
foreach (var p in CurrentFilters)
{
query += $"{p.Key}={p.Value}&";
}
query = query.TrimEnd(query[query.Length - 1]); //remove last '&'
var url = $"{HttpContext.Request.Path}?{query}"; // create URL
return Redirect(url); // Send new url - call get Method()
}
on OnGet() method
public async Task OnGetAsync()
{
// here i want to get URL values and select those items
string result = Request.Query["Colors"];
if (!string.IsNullOrEmpty(result))
{
string[] TempArray = result.Split(",");
foreach (var item2 in TempArray)
{
Colors.add(TempArray[i]);
}
}
}

ViewData returns null instead of a tuple of lists

Hellow,
I'm using ASP.NET CORE with Razor Pages and I'm trying to go through the final step of making my ViewData return a tuple of lists.
I made things work the way I wanted, where I made 2 different ViewDatas return 2 lists, but the order of it wasn't the way I wanted, so I put them both in a tuple to return the 2 lists one after another, subject, text, subject, text, etc.
Creating and adding data to the tuple in my Services Class:
public Tuple<List<string>, List<JToken>> get_data_om_mig_info_data()
{
StreamReader reader = File.OpenText(json_file_name);
JToken data = JToken.Parse(reader.ReadToEnd());
JObject om_mig_info = data["om_mig_info"].Value<JObject>();
List<string> subjects = om_mig_info.Properties().Select(property => property.Name).ToList();
List<JToken> text = om_mig_info.Properties().Select(property => property.Value).ToList();
Tuple<List<string>, List<JToken>> om_mig_data = new Tuple<List<string>, List<JToken>>(subjects, text);
return om_mig_data;
}
Index.cs:
Here Tuuple gets all the items as intended. Item1 Count = 3, and Item2 Count = 3.
But the ViewData remains null.
public class IndexModel : PageModel
{
private readonly ILogger<IndexModel> _logger;
public string Index_title { get; private set; }
public Data_Info_Service Om_mig_service_text { get; set; }
public Tuple<List<string>, List<JToken>> Tuuple { get; set; }
public object aaa;
public IndexModel(ILogger<IndexModel> logger, Data_Info_Service Om_mig_service_text)
{
_logger = logger;
this.Om_mig_service_text = Om_mig_service_text;
}
public void OnGet()
{
Tuuple = Om_mig_service_text.get_data_om_mig_info_data(); // Tuple works
ViewData["data_text"] = Tuuple;
aaa = ViewData["data_text"]; // aaa seems to work as well, has all items
Index_title = "Om mig";
}
}
View:
<div class="data_position">
#foreach (var data in ViewData["data_text"] as IEnumerable<Tuple<List<string>, List<Newtonsoft.Json.Linq.JToken>>>) // Exception here
{
<h5>#data</h5>
}
</div>
Exception:
System.NullReferenceException: 'Object reference not set to an instance of an object.'
(... as System.Collections.Generic.IEnumerable<System.Tuple<System.Collections.Generic.List<string>,
System.Collections.Generic.List<Newtonsoft.Json.Linq.JToken>>>) returned null.
Any help would be very appreciated, thanks.
I think this should be working :
public void OnGet()
{
Var datas = ViewData["data_text"] as Om_mig_service_text.get_data_om_mig_info_data();}
The cast in your View is not valid.
You cannot cast a Tuple containing 2 lists into a single list.
<div class="data_position">
#{
var data = ViewBag.data_text;
var list1 = data.Item1 as List<string>;
var list2 = data.Item2 as List<string>;
}
#foreach (var item in list1)
{
<h5>#item</h5>
}
</div>

DropDownListFor has unique value for all items

I am using a razor helper DropDownListFor in order to have a dropdown list of Organizational Units from Active Directory (replicated in Database, it doesn't matter so much). The idea is you have a first list with all parent elements, and when clicking, I search my database to find the children elements, and so on until you reach a leaf (so to speak, last element). My problem is that when inspecting element in my browser I find that all value from the <option> markup are equal to the first id that I pass when clicking.
So here is my ViewModel:
public class SiteDirectionModel
{
public int id { get; set; }
public List<SelectListItem> Names { get; set; }
}
Then my first controller method (for parent elements) is the following :
public ActionResult CreateADUser()
{
List<SelectListItem> items = new List<SelectListItem>();
SiteDirectionModel sdM = new SiteDirectionModel();
//The below method gets all parent nodes from database
//_nonGenService is an instance of a service that can access my Repository
direction = _nonGenService.GetAllSiteDirection();
if (direction != null && direction.Count!=0)
{
items.Add(new SelectListItem
{
Text = dir.Name,
Value = dir.IDDirection.ToString()
});
}
sdM.Names = items;
return View(sdM);
}
else
return View("AccessError"); //A page in case of error
}
Then the second controller method to treat child elements:
public ActionResult GetSiteRF(SiteDirectionModel model)
{
SiteDirectionModel sdM = new SiteDirectionModel();
List<SelectListItem> items = new List<SelectListItem>();
//This method gets children elements from a specified id
//The table that looks has IDDirection as FK from first table
radioFrance = _nonGenService.GetSiteRFFromDirection(model.id);
direction = _nonGenService.GetAllSiteDirection();
int id;
string nameConcat = string.Empty;
//For loop to concatenate names
foreach(var dir in direction)
{
if (dir.IDDirection == model.id)
{
nameConcat = dir.Name + "-" + nameConcat;
break;
}
}
if (radioFrance.Count==1)
{//This condition would be to see if the name is equal to the current node so
//that we can exit the condition and access a form to create the user
Site_RadioFrance single = radioFrance.SingleOrDefault();
if (single.Name.Equals(nameConcat))
{
return View("CreateADForm", model);
}
}
else
{
foreach (var radio in radioFrance)
{
items.Add(new SelectListItem
{
Text = nameConcat+radio.Name,
Value = radio.IDDirection.ToString()
});
}
sdM.Names = items;
return View("CreateADUser",sdM);
}
return View("AccessError"); //Error treatement
}
My view loks like this :
#model MyProject.Models.SiteDirectionModel
<h2>Create an account in Active Directory</h2>
#using (Html.BeginForm("GetSiteRF", "Create", FormMethod.Post))
{
#Html.DropDownListFor(x => x.id, Model.Names);
<input type="submit" value="Selectionner" class="btn btn-primary"/>
}
Now say you have the item clicked with IDDirection=10 then all my child elements have
<option value=10>parent1-child1</option>
<option value=10>parent1-child2</option>
<option value=10>parent1-child3</option>
<option value=10>parent1-child4</option>
I don't know how to fix this, any ideas? because then my model id has this value, and I somehow thought that it would apply a value for each different option, I don't understand why it doesn't?
Thanks!

Set selected value in dropdown list

How do I set the selected value on a drop down list? Here is what I have so far:
#model Web.Models.PostGraduateModels.PlannedSpecialty
#Html.DropDownList("PlannedSpecialtyID")
//controller
[HttpGet]
public PartialViewResult PlannedSpecialty()
{
// Get Planned Specialty ID
var pgtservice = new PgtService();
PostGraduateModels.PlannedSpecialty plannedSpecialty = pgtservice.GetPlannedSpecialtyId();
// Get Data for Planned Specialty DropDown List from SpecialtyLookup
var pgtServ = new PgtService();
var items = pgtServ.GetPlannedSpecialtyDropDownItems();
ViewBag.PlannedSpecialtyId = items;
return PartialView(plannedSpecialty);
}
// service
public IEnumerable<SelectListItem> GetPlannedSpecialtyDropDownItems ()
{
using (var db = Step3Provider.CreateInstance())
{
var specialtyList = db.GetPlannedSpecialtyDdlItems();
return specialtyList;
}
}
// data access
public IEnumerable<SelectListItem> GetPlannedSpecialtyDdlItems()
{
IEnumerable<Specialty> specialties = this._context.Specialties().GetAll();
var selList = new List<SelectListItem>();
foreach (var item in specialties)
{
var tempps = new SelectListItem()
{
Text = item.Description,
Value = item.Id.ToString()
};
selList.Add(tempps);
}
return selList;
}
I would recommend you to avoid using ViewBag/ViewData/ Weekly typed code. Use strongly typed code and it makes it more readable. Do not use the Magic strings/ Magic variables. I would add a collection property to your ViewModel to hold the SelectList items and another property to hold the selected item value.
public class PlannedSpecialty
{
public IEnumerable<SelectListItem> SpecialtyItems { set;get;}
public int SelectedSpeciality { set;get;}
//Other Properties
}
and in your Get action, If you want to set some Item as selected,
public PartialViewResult PlannedSpecialty()
{
var pgtServ = new PgtService();
var vm=new PlannedSpecialty();
vm.SpecialtyItems = pgtServ.GetPlannedSpecialtyDropDownItems();
//just hard coding for demo. you may get the value from some source.
vm.SelectedSpeciality=25;// here you are setting the selected value.
return View(vm);
}
Now in the View, use the Html.DropDownListFor helper method
#Html.DropDownListFor(x=>x.SelectedSpeciality,Model.SpecialtyItems,"select one ")
Use the selected property of the SelectListItem class:
selList.Selected = true;

Trying to pass a parameter but getting a "context" error

I am trying to pass this from my controller into my view (#ViewBag.Chapter7Total):
ViewBag.Chapter7Total = calc.CalculatePrice(quoteData, Chapter7);
But am getting a "doesn't exist in the current context error" in VS.
Basically, I am trying to pass in a second parameter which determines which pricing structure to use between 2. Chapter7 or Chapter13, with the selection determining the second parameter to perform calculations with.
Here are my methods:
class Chapter
{
public decimal PaymentPlan { get; set; }
public decimal Price { get; set; }
}
public decimal decPaymentPlan(QuoteData quoteData, Chapter chapter)
{
if (quoteData.StepFilingInformation.PaymentPlanRadioButton
== StepFilingInformation.PaymentPlan.No)
return PriceQuote.priceNoPaymentPlan;
else
return chapter.PaymentPlan;
}
public decimal Calculate(QuoteData quoteData, Chapter chapter)
{
decimal total = chapter.Price;
total += this.decPaymentPlan(quoteData, chapter);
return total;
}
static Chapter Chapter7 = new Chapter() { Price = 799.00m, PaymentPlan = 100.00m };
Finally, this is my controller:
public ActionResult EMailQuote()
{
Calculations calc = new Calculations();
Chapter chap = new Chapter();
QuoteData quoteData = new QuoteData
{
StepFilingInformation = new Models.StepFilingInformation
{
//just moking user input here temporarily to test out the UI
PaymentPlanRadioButton = Models.StepFilingInformation.PaymentPlan.Yes,
}
};
var total = calc.CalculatePrice(quoteData);
ViewBag.Chapter7Total = calc.CalculatePrice(quoteData, Chapter7);
return View(quoteData);
}
I'm not sure what to do to pass Chapter7. Any thoughts?
UPDATE 1:
This is my ViewModel (QuoteData):
public class QuoteData
{
public PriceQuote priceQuote;
public Calculations calculations;
public StepFilingInformation stepFilingInformation { get; set; }
public QuoteData()
{
PriceQuote = new PriceQuote();
Calculations = new Calculations();
}
}
I'm trying to figure out what you are doing here but I see that most importantly, you are sending quoteData to your View. I'm making a guess here but I figure QuoteData is a custom entity type of yours and not a ViewModel.
To start, I would create a QuoteDataViewModel in your models with all the properties of QuoteData that you need, including
public class QuoteDataViewModel {
... all of your quoteData properties here
public Chapter Chapter7 { get; set; }
}
In your EMailQuote action, something similar to this
public ActionResult EMailQuote() {
...
var model = new QuoteDataViewModel();
var quoteData = new QuoteData();
... // map your quoteData to your model with Automapper or manually like
... // model.SomeProperty = quoteData.SomeProperty;
... // repeat for all properties
model.Chapter7 = Chapter7;
return View(model);
}
If you are posting this data back you would need your Post action to accept the new QuoteDataViewModel
public ActionResult EmailQuote(QuoteDataViewModel model) {
if(ModelState.IsValid) {
....//save data that was entered?
}
return View(model);
}
Your view would then take a QuoteDateViewModel
#model QuoteDataViewModel
This is all just how I would do it personally, I don't quite understand what you have going on, for example, this line:
var total = calc.CalculatePrice(quoteData);
I don't see total ever being used after you create it.
Anyway, that's just a sample of how I'd do it, create a model specific to the view, include any and all properties I need, populate the model in the controller and send it to the view
Update
Based on the OP comment that quoteData is a ViewModel, then just as above, adding the new property to hold the extra data is simple, by adding ...
public decimal QuoteTotal { get; set; }
public Chapter Chapter7 { get; set; }
...to the ViewModel
the controller populates
var total = calc.CalculatePrice(quoteData);
model.QuoteTotal = total;
model.Chapter7 = new Chapter();
model.Chapter7 = Chapter7;
In the View the values can be accessed like:
#Html.DisplayFor(model => model.QuoteTotal)
#Html.DisplayFor(model => model.Chapter7.PaymentPlan)
#Html.DisplayFor(model => model.Chapter7.Price)

Categories