i try to access a associative array in c#. The Array is send per post to my c# mvc web application.
e. g. html form
<Input Name="myArray[hashKey1]" value="123">
<Input Name="myArray[hashKey2]" value="456">
and in c# i need the keys and values - perhaps with data dictionary?!
[HttpPost]
public ActionResult Index(FormCollection collection)
{
Dictionary<string, string> = KEY, VALUE
...
}
i hope you can follow me :-/
Yes you can; but you need to specify the method of POST.
This doesn't work:
<form id="frmThing" action="#Url.Action("Gah", "Home")">
<input id="input_a" name="myArray[hashKey1]" value="123" />
<input id="input_b" name="myArray[hashKey2]" value="456" />
<input type="submit" value="Submit!"/>
</form>
This does:
<form id="frmThing" action="#Url.Action("Gah", "Home")" method="POST">
<input id="input_a" name="myArray[hashKey1]" value="123" />
<input id="input_b" name="myArray[hashKey2]" value="456" />
<input type="submit" value="Submit!"/>
</form>
Edit: To actually access the details in C#, in your example you'd do one of the following:
String first = collection[0];
String secnd = collection[1];
or
String first = collection["myArray[hashKey1]"];
String secnd = collection["myArray[hashKey2]"];
or even:
foreach (var item in collection) {
string test = (string)item;
}
Edit two:
Here's a trick you can use to get the behavior you want to see.
Firstly, define an extension method:
public static class ExtensionMethods
{
public static IEnumerable<KeyValuePair<string, string>> Each(this FormCollection collection)
{
foreach (string key in collection.AllKeys)
{
yield return new KeyValuePair<string, string>(key, collection[key]);
}
}
}
Then in your action result you can do this:
public ActionResult Gah(FormCollection vals)
{
foreach (var pair in vals.Each())
{
string key = pair.Key;
string val = pair.Value;
}
return View("Index");
}
Related
Form returns url format: localhost2343/index?Colors=red&Colors=blue&Colors=pink
asp-route return url format: localhost2343/index?Colors=red,blue,pink
If I use form submit button than everything seems good. But If i click on sort hyperlink than it will pass URL Colors=System.String%5B%5D
How can I pass value of Colors inside asp-route?
<form asp-page="./index" method="get">
<select asp-for="Colors" asp-items="#Model.Colors_SELECT" class="MultiSelect" multiple>
<option value="">All</option>
</select>
...
</form>
<Table>
...
<a asp-page="./Index" method="get"
asp-route-SortOrder="#Model.Colors_Sort"
asp-route-SearchString="#Model.SearchString"
asp-route-Colors="#Model.Colors">
#Html.DisplayNameFor(model =>
model.MyList[0].Colors)
</a>
...
</table>
[BindProperty(SupportsGet = true)]
public string[]? Colors { get; set; }
public SelectList? Colors_SELECT { get; set; }
public async Task OnGetAsync()
{
// Form - URL Format
// get values from URL & set inside selectlist
var result = Request.Query["Colors"];
var i = 0;
foreach (string? item in result) {
Colors[i] = item;
i++;
}
}
Update - I tried this but on sort link, it removes Sort variable & it picks only 1 Colors (not multi)
<a asp-page="./Index" method="get"
asp-route-SortOrder="#Model.Colors_Sort"
asp-all-route-data="#Model.routeData">
[BindProperty(SupportsGet = true)]
public Dictionary<string, string> routeData { get; set; }
....
var routeData = new Dictionary<string, string>();
routeData.Add("SortOrder", CurrentSort);
routeData.Add("SearchString", SearchString);
for (int i = 0; i < result.Count; i++)
{
var myParam = result[i];
routeData.Add($"Colors{i}", myParam.ToString());
}
This may help:
To get the selected values from a select element in a Razor page, you can use the Request.Form["selectName"] collection.
For example, consider the following select element:
#page "{Colors}"
<form method="post">
<select multiple name="colors">
<option value="red">Red</option>
<option value="blue">Blue</option>
<option value="pink">Pink</option>
</select>
<button type="submit" asp-page-handler="GetColors">Submit</button>
</form>
To get the selected values in the form submission handler and modify the query string in the URL and include the selected values (red, blue, pink), you can try the following code:
public IActionResult OnGet(string? Colors)
{
if (string.IsNullOrWhiteSpace(Colors))
{
// do something
return Page();
}
if (!string.IsNullOrWhiteSpace(Colors))
{
// Do something
return Page();
}
return Page();
}
public IActionResult OnPostGetColors()
{
IDictionary<string, string> params = new Dictionary<string, string>();
var selectedColors = string.Join(",", Request.Form["colors"]);
params.Add("Colors", selectedColors);
string query = "";
foreach (var p in params)
query += $"{p.Key}={p.Value}";
var url = $"{HttpContext.Request.Path}?{query}";
return Redirect(url); // url : https://localhost:7272/index?Colors=red,blue,pink
}
This code will help you submit the selected values through the URL as a query string, and then will redirect the user to a new URL with the selected values added to the query string as multiple values for the colors parameter.
var dictionary = [];
dictionary.push({
key:"Res01" ,
value: "Loss of internet connection at location"
});
when adding this dictionary object to an input field
$('#hdnNotesDict').val('');
$('#hdnNotesDict').val(dictionary);
i am not getting the dictionary value in that input field.
getting result as: [object,object]
Thanks in advance and any suggestion will be appreciated
Let's say you have this form in your view:
<form method="post">
<input id="kvps" name="kvps" />
<input id="submit" type="submit" value="Submit" />
</form>
and you put some values like that:
(function () {
$('#submit').mousedown(function () {
let input = $('#kvps');
let dict = [];
for (var i = 0; i < 10; i++) {
dict.push({ key: `Res${i}`, val: `Val${i}` });
}
input.val(JSON.stringify(dict));
});
})();
in this case you convert the array in a string and you should take it as string into your controller
BUT - you cannot convert it to dictionary immediately, first you should map it to array of model with the same property names then you can call ToDictionary over it.
Array example:
[HttpPost]
public IActionResult JInput(string kvps)
{
var arr = JsonSerializer.Deserialize<object[]>(kvps);
return this.View();
}
If you need it as Dictionary<string, string> you schould use in your jquery object instead:
(function () {
$('#submit').mousedown(function () {
let input = $('#kvps');
let dict = {};
for (var i = 0; i < 10; i++) {
// watch out for the keys here to not overwrite the values
dict[`Res${i}`] = `Val${i}`;
}
input.val(JSON.stringify(dict));
});
})();
And in your controller like that:
[HttpPost]
public IActionResult JInput(string kvps)
{
var arr = JsonSerializer.Deserialize<Dictionary<string, string>>(kvps);
return this.View();
}
I am using a method that generate my questions and answers i mean every questions appear in view and the answers of this question are put to the DDL as you can see here :
public string GenerateHtmlCode()
{
string result = string.Empty;
List<ExecutiveOfficer> executiveOfficers = executiveOfficerRepository.GetAll().ToList();
List<Indicator> indicators = indicatorRepository.GetAll().ToList();
foreach (ExecutiveOfficer executiveOfficer in executiveOfficers)
{
result += "<div style='width:100%;float:right;'><span>" + executiveOfficer.ExecutiveOfficerText +
"</span><span style='float:left'>" +
GenerateAnswer(indicatorRepository.FindBy(i => i.ExecutiveOfficerId == executiveOfficer.Id
).ToList(), executiveOfficer.Id) + "</span></div>";
}
return result;
}
In my create method in controller i pass the string to viewbag as you can see here :
[HttpGet]
public ActionResult Create(int preliminaryId)
{
ViewBag.preliminaryId = preliminaryId;
ViewBag.pageGenarator = objScoreRepository.GenerateHtmlCode();
// List<ExecutiveOfficer> executiveOfficer = objScoreRepository.GetAll().ToList();
//ViewBag.executiveOfficerName = new SelectList(executiveOfficer, "Id", "ExecutiveOfficerText");
return View("Create");
}
My html code :
</span><span style='float:left'><select id='1' name ='1'><option value='value1'>displaytext</option><option value='value2'>displaytext2</option></select></span>
As you can see here i have 1 DDL that has 2 values i need to get the value that is selected by the user i use the form collection to get the name of DDl as you can see here :
[HttpPost]
//[Authorize(Roles = "Expert")]
public ActionResult Create(FormCollection formCollection)
{
//objScoreRepository.Add(Score);
//objScoreRepository.Save();
foreach (var VARIABLE in formCollection.AllKeys)
{
}
return RedirectToAction("Create", "Score");
}
The formcollection just returns one record and the record is 1 the name of DDL .But i need to get the value of DDL.How can i do that?
My view:
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_LayoutIdeaOtherPage.cshtml";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
#Html.Raw(ViewBag.pageGenarator)
<div class="buttonPossion">
<input type="submit" Class="buttonSave" />
</div>
}
best regards .
You can use
foreach(string item in form.AllKeys)
{
var value = Request[item];
}
I have the folloiwng code inside my asp.net mvc action method:-
var CustomerData = customerlist.Select(m => new SelectListItem()
{
Text = m.SDOrganization.NAME,
Value = m.SDOrganization.ORG_ID.ToString(),
});
currently if i remove the ToString() from the ORG_ID , i will get an error that "can not explicitly convert long to string". so it seems that i have to define both the value and the text for the SelectListItem as strings. but since the SelectListItem should hold long , so is there a way to pass the values of the SelectListItem as long instead of strings?
...so is there a way to pass the values of the SelectListItem as long instead of strings?
No. And it doesn't make any sense to do so as when it is rendered, it's just HTML which has no concept of long.
If we have the action
public ActionResult Test()
{
var dictionary = new Dictionary<int, string>
{
{ 1, "One" },
{ 2, "Two" },
{ 3, "Three" }
};
ViewBag.SelectList = new SelectList(dictionary, "Key", "Value");
return this.View();
}
and the following view "Test.cshtml":
#using (Html.BeginForm())
{
#Html.DropDownList("id", ((SelectList)ViewBag.SelectList), "All")
<input type="submit" value="Go" />
}
The generated HTML is
<form action="/home/test" method="post">
<select id="id" name="id">
<option value="">All</option>
<option value="1">One</option>
<option value="2">Two</option>
<option value="3">Three</option>
</select>
<input type="submit" value="Go">
</form>
and when we post to this action, text of your number is effectively parsed back into your desired type by the Model Binder
[HttpPost]
public ActionResult Test(int? id)
{
var selectedValue = id.HasValue ? id.ToString() : "All";
return Content(String.Format("You selected '{0}'", selectedValue));
}
And the above works as you might expect.
I am trying to make 2 cascading drop down lists.
First one works fine, you pick an item but when you go to the second drop down list, you can actually see correct number of spaces generating according to the items in the database but not the items themselves!
Its like they are invisible!
Can you please advise?
My View :
#using (Html.BeginForm("Browse", "Bookings", new { id = "TypeItemFormID", data_itemsListAction = #Url.Action("ItemsList") }))
{
<fieldset>
<legend> Type/Item</legend>
#Html.DropDownList("department", ViewBag.ItemTypesList as SelectList, "Select a Type", new {id="ItemTypeID"})
<div id="ItemsDivId">
<label for="Items">Items </label>
<select id="ItemsID" name="Items"></select>
</div>
<p>
<input type ="submit" value="Submit" id="SubmitID" />
</p>
</fieldset>
}
<script type="text/javascript">
$('#ItemTypeID').on('change', function () {
$.ajax({
type: 'POST',
url: '#Url.Action("GetItemTypeForm")',
data: { itemTypeId: $('#ItemTypeID').val() },
success: function (results) {
var options = $('#ItemsID');
options.empty();
options.append($('<option />').val(null).text("- Select an Item -"));
$.each(results, function () {
options.append($('<option />').val(this.ItemsID).text(this.Value));
});
}
});
});
</script>
My Controller :
[HttpPost]
public JsonResult GetItemTypeForm(string itemTypeId)
{
//pseudo code
var data = from s in db.Items
where s.ItemType.ItemTypeName == itemTypeId
select s.ItemName;
return Json(data);
}
You have the initial problem I mentioned in my comment, but it appears from your comments that your member names probably do not match either.
This may not be exact, as we do not know all your data/member names, but you may want something like this (using an anonymous type to return the shape of data you expect):
[HttpPost]
public JsonResult GetItemTypeForm(string itemTypeId)
{
//pseudo code
var data = from s in db.Items
where s.ItemType.ItemTypeName == itemTypeId
select new { Value = s.ItemName, ItemsID = s.ItemId };
return Json(data);
}