get value in input text box and send it to controller - asp.net-mvc-3

What are the ways to render the input value filename and send it to a controller :
<div id="fileuploaddiv" class="fileuploaddivclass">
<form action="#Model.FormAction" method="#Model.FormMethod"
enctype="#Model.FormEnclosureType">
<input type="hidden" name="key" value="uploads/${filename}" id="filename" />
<input type="hidden" name="AWSAccessKeyId" value="#Model.AWSAccessKey" />
<input type="hidden" name="Content-Type" value="image/jpeg">
<div>
Please specify a file, or a set of files:
<input type="file" name="file" />
</div>
<input type="submit" value="Upload" />
</form>
</div>

You need to look up some MVC3 conventions (I'd recommend NerdDinner as a good starting tutorial), but here is a somewhat similar approach to what you want to do:
#Model YourViewModel
<div id="fileuploaddiv" class="fileuploaddivclass">
#using(Html.BeginForm(Model.FormAction, Model.FormController, FormMethod.Post)
#Html.HiddenFor(model.key => ${fileName})
#Html.HiddenFor(model.AWSAccessKeyID)
#Html.HiddenFor(model.Content-Type)
#<input type="submit" value="Submit My Form" />
#Html.EndForm()
</div>
Your model would look like (And I'm confused here because you seem to be dynamically setting the controller and action, which is unusual):
public class YourViewModel
{
public string FormAction { get; set; }
public string FormController { get; set; }
public int AWSAccessKeyID { get; set; }
public string Content-Type { get; set; }
}
Now on to controllers:
[HttpGet]
public ActionResult WhateverControllerName()
{
YourViewModel yvm = new YourViewModel();
//Initalize viewmodel here
Return view(yvm);
}
[HttpPost]
public ActionResult WhateverControllerName(YourViewModel yvm)
{
if (ModelState.IsValid) {
//Do whatever you want here. Perhaps a redirect?
}
return View(yvm);
}
Note: I am garbage at syntax, so you'll have to check this, but Visual Studio should tell you what works.

Related

How to get multiple answers from radio buttons when clicking submit ASP.NET CORE MVC

This is a quiz with around 40 questions and each question with multiple answers.
Everything looks fine until I try to catch the answers from the view to the controller because everything returns 0 or null, Please help!
This is what I have
The Database looks like this:
Model Evaluacion:
namespace ENCB_Placement_Test_Official.Models
{
public class Evaluacion
{
public int ExamenId { get; set; }
public int RegistroId { get; set; }
public int ReactivoId { get; set; }
public string RespuestaAlumno { get; set; }
public string Pregunta { get; set; }
public string Respuesta1 { get; set; }
public string Respuesta2 { get; set; }
public string Respuesta3 { get; set; }
public string Respuesta4 { get; set; }
}
}
Services folder with a class called RepositorioExaluaciones
namespace ENCB_Placement_Test_Official.Servicios
{
public interface IRepositorioEvaluaciones
{
Task EnviarRespuesta(Evaluacion evaluacion);
Task<IEnumerable<Evaluacion>> ObtenerEvaluaciones();
}
public class RepositorioEvaluaciones: IRepositorioEvaluaciones
{
private readonly string connectionString;
public RepositorioEvaluaciones(IConfiguration configuration)
{
connectionString = configuration.GetConnectionString("DefaultConnection");
}
public async Task<IEnumerable<Evaluacion>> ObtenerEvaluaciones()
{
using var connection = new SqlConnection(connectionString);
return await connection.QueryAsync<Evaluacion>(#"SELECT Examenes.Id AS ExamenId,
RegistroId,
ReactivoId,
RespuestaAlumno,
Pregunta,
Respuesta1,
Respuesta2,
Respuesta3,
Respuesta4
FROM Examenes
INNER JOIN Reactivos
ON Examenes.ReactivoId = Reactivos.Id
WHERE Examenes.RegistroId = 1");
}
public async Task EnviarRespuesta(Evaluacion evaluacion)
{
using var connection = new SqlConnection(connectionString);
connection.Execute(#"UPDATE Examenes
SET RespuestaAlumno = #RespuestaAlumno
WHERE RegistroId = #RegistroId", evaluacion);
}
}
}
Controller Evaluaciones
namespace ENCB_Placement_Test_Official.Controllers
{
public class EvaluacionesController:Controller
{
private readonly IRepositorioEvaluaciones repositorioEvaluaciones;
public EvaluacionesController(IRepositorioEvaluaciones repositorioEvaluaciones)
{
this.repositorioEvaluaciones = repositorioEvaluaciones;
}
public async Task<IActionResult> Evaluar()
{
if (!ModelState.IsValid)
{
return View();
}
var obtenerExamen = await repositorioEvaluaciones.ObtenerEvaluaciones();
return View(obtenerExamen);
}
[HttpPost]
public async Task<IActionResult> Evaluar(Evaluacion evaluacion)
{
if (!ModelState.IsValid)
{
return View(evaluacion);
}
await repositorioEvaluaciones.EnviarRespuesta(evaluacion);
return View();
}
}
}
View Evaluar, this is where I think I have the problem because when I debug the app and click the submit button I just get nulls and zeros
#model IEnumerable<Evaluacion>
#{
ViewData["Title"] = "Start Assesment";
var contador = 1;
}
<h1>Start Assesment</h1>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<form asp-action="Evaluar" method="post">
#foreach (var reactivo in Model)
{
<div class="mb-3">
<label class="form-label">#contador . #reactivo.Pregunta</label>
<div class="form-check">
<input class="form-check-input" type="radio" id="#reactivo.ExamenId" name="#reactivo.ExamenId" value="Respuesta1" checked />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta1</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="#reactivo.ExamenId" name="#reactivo.ExamenId" value="Respuesta2" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta2</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="#reactivo.ExamenId" name="#reactivo.ExamenId" value="Respuesta3" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta3</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" id="#reactivo.ExamenId" name="#reactivo.ExamenId" value="Respuesta4" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta4</label>
</div>
</div>
contador++;
}
<button type="submit" class="btn btn-primary">Send Response</button>
</form>
It is supposed to return an answer like "Respuesta1" and it should be stored in the Model.RespuestaAlumno and I just don't have any idea on how can I do it. please help.
In your Model Design, You need a property to receive the value of the selected answer(maybe you already have that property in your model,I don't understand spanish), So I create that property:
public class Evaluacion
{
public int ExamenId { get; set; }
public int RegistroId { get; set; }
public int ReactivoId { get; set; }
public string RespuestaAlumno { get; set; }
public string Pregunta { get; set; }
public string Respuesta1 { get; set; }
public string Respuesta2 { get; set; }
public string Respuesta3 { get; set; }
public string Respuesta4 { get; set; }
public string Answer { get; set; }
}
Then in your View, name uses property names for binding and it asked to start at index 0. I write a simple demo here, you can refer to it:
#model IEnumerable<Evaluacion>
#{
ViewData["Title"] = "Start Assesment";
var contador = 1;
}
<h1>Start Assesment</h1>
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<form asp-action="Evaluar" method="post">
#foreach (var reactivo in Model)
{
int i = contador - 1;
<div class="mb-3">
<label class="form-label">#contador . #reactivo.Pregunta</label>
<div class="form-check ">
<input class="form-check-input" type="radio" name="[#i].Answer" value="#reactivo.Respuesta1" checked />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta1</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="[#i].Answer" value="#reactivo.Respuesta2" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta2</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="[#i].Answer" value="#reactivo.Respuesta3" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta3</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="[#i].Answer" value="#reactivo.Respuesta4" />
<label class="form-check-label" for="#reactivo.ExamenId">#reactivo.Respuesta4</label>
</div>
</div>
contador++;
}
<button type="submit" class="btn btn-primary">Send Response</button>
</form>
Finally, The type of the model passed into the controller from the page is IEnumerable, You can't just use Evaluacion to receive, You need to change like this:
[HttpPost]
public async Task<IActionResult> Evaluar(List<Evaluacion> evaluacion)
{
//.......
return View(evaluacion);
}
Demo:
You can see the project can receive the answer successfully.

How to set radio button to be checked by default

I'm implementing asp.net core 3.1. I have three radio buttons in my razor view and with the following code, I want to send the selected radio button value to Index action in controller in order to show its related data. My problem is, I can't set one of those radio buttons to be checked by default.
#model CSD.ChartObjects
<form method="post">
#foreach (var year in Model.Years)
{
<input type="radio" asp-for="Year" value="#year" />#year<br />
}
<input type="submit" asp-action="Index" />
</form>
Here is my model object that is read in razor
public class ChartObjects
{
public List<ChartModel> Percent { get; set; }
public List<ChartModel> Time { get; set; }
public List<ChartModel> Avg { get; set; }
public List<ChartModel> Total { get; set; }
public string Year { get; set; }
public string[] Years = new[] { "1398", "1399", "1400" };
}
And here is the body of my HomeController:
[HttpGet]
public IActionResult Index()
{
return (BuildIndexModel("1399"));
}
[HttpPost]
public IActionResult Index([FromForm] string currentYear)
{
return (BuildIndexModel(currentYear));
}
public IActionResult BuildIndexModel(string currentYear)
{
...
}
I think this will work:
#foreach (var year in Model.Years)
{
var fi = (year == Model.Years[0]) ? true : false ;
<input type="radio" asp-for="Year" value="#year" checked="#fi" />#year<br />
}
My problem is, I can't set one of those radio buttons to be checked by default.
To set a default checked radio button, you can try following code snippet.
<form method="post">
#foreach (var year in Model.Years)
{
<input type="radio" asp-for="Year" value="#year" checked="#(year == Model.Years.FirstOrDefault() ? "checked" : null)"/>#year<br />
}
<input type="submit" asp-action="Index" />
</form>
Update:
my data by default is for 1399
You can pass default year through ViewData, like below.
In controller action
ViewData["defaultyear"] = "1399";
In view page
<input type="radio" asp-for="Year" value="#year" checked="#(year == ViewData["defaultyear"].ToString() ? "checked" : null)"/>#year<br />
I don't know how to use asp.net, but In JS, I just simply have to access the attributes of the HTML Input tag so you can then assign the attribute "checked" to true.
I guess is something like this:
HtmlElement Input1 = webBrowser1.Document.GetElementById("ID"); // consider adding an ID
Input1.Attributes.Add("checked", "true");
Check this two links:
How to: Set HTML Attributes for Controls in ASP.NET Web Pages
HtmlDocument.GetElementById(String) Method

mvc3 checkbox value after submit

I have a form with 2 fields a dropdownlist and a checkbox. I have everything working correctly but i can not for some reason obtain the value of a checkbox if it is checked this is my code..
[HttpPost]
public ActionResult view(string pick)
{
switch (pick)
{
case "Deny":
// capture checkbox value here
break;
case "Accept":
// capture checkbox value here
break;
}
return View();
}
This is my view
#using (Html.BeginForm("view", "grouprequest", FormMethod.Post, new {}))
{
#Html.DropDownList("pick", new SelectList(new List<Object>{
new{ Text ="Accept", Value= "Accept"},new{ Text ="Deny", Value= "Deny"}}, "Value", "Text"), new {})
<input type="submit" name="work" id="work" value="Update" style="font-size:16px" />
foreach (var item in Model)
{
<input type="checkbox" id="#item.grouprequestID" name="#item.grouprequestID" value="#item.grouprequestID" />
}
}
Basically the dropdownlist has 2 options which are Accept and Deny I can capture which one the user chooses via the SWITCH-case in the controller now how can I capture the value of the checkboxes? If you notice the Checkboxes have a variable to them named #groupRequestID so every checkbox has a different unique value like 1,2,3 etc.. any help would be greatly appreciated !!
The Model
public class grouprequest
{
[Key]
public int grouprequestID { get; set; }
public int? profileID { get; set; }
public int? registrationID { get; set; }
public DateTime expires { get; set; }
public int? Grouplink { get; set; }
}
Check boxes when posted to the server act a little strange.
If a box is checked the browser will send name=value as in
<input type="checkbox" name="name" value="value" />
But if the checkbox is not checked the server doesn't send anything.
<input type="checkbox" name="Check1" id="Checks1" value="Hello" checked="checked"/>
<input type="checkbox" name="Check1" id="Checks1" value="Hello1" />
<input type="checkbox" name="Check1" id="Checks1" value="Hello2" />
Will result in Check1 = Hello
What this means is if all your check boxes are related, naming them the same will populate the same attribute of your ActionMethod. If that attribute is an enumeration it will contain only the ones that are checked.
If you have this in your view:
<input type="checkbox" name="MyValues" value="1" checked="checked"/>
<input type="checkbox" name="MyValues" value="2" />
<input type="checkbox" name="MyValues" value="3" />
and this as your controller action method:
public ActionMethod MyAction(IEumerable<int> myValues)
The myValues variable will look like this:
myValues[0] == 1
You should also note that if you are using the Html helper extension:
#Html.CheckBoxFor(m => m.MyValue)
Where MyValue is a bool the extension will create a checkbox input tag and also a hidden input tag with the same name, meaning a value will always be passed into the controller method.
Hope this helps.

KeyPairValue in ASP.NET MVC3 Razor

I have a weird problem.
I'm making dynamic form in Razor. I'm using dictionary to store dynamically added inputs.
I generate code like that:
<input type="hidden" value="96" name="Inputs[0].Key">
<input type="text" name="Inputs[0].Value">
I receive in my controller this dictionary. It always has as many elements that I added, but all of them are empty.
This is part of my model:
public class MetriceModelTaskSchedule
{
public IEnumerable<KeyValuePair<long, string>> Inputs { get; set; }
}
What can be wrong here?
What can be wrong here?
The fact that the KeyValuePair<TKey, TValue> class has the Key and Value properties which are readonly. They do not have a setter meaning that the model binder simply cannot set their value.
So as always start by defining a view model:
public class InputViewModel
{
public long Key { get; set; }
public string Value { get; set; }
}
and then:
public class MetriceModelTaskSchedule
{
public IEnumerable<InputViewModel> Inputs { get; set; }
}
Alternatively you could use a Dictionary:
public class MetriceModelTaskSchedule
{
public IDictionary<long, string> Inputs { get; set; }
}
Also make sure that you have respected the standard naming convention for your input fields in the view so that the model binder can successfully bind them to your model:
<div>
<input type="text" name="Inputs[0].Key" value="1" />
<input type="text" name="Inputs[0].Value" value="value 1" />
</div>
<div>
    <input type="text" name="Inputs[1].Key" value="2" />
    <input type="text" name="Inputs[1].Value" value="value 2" />
</div>
...

MVC3: Portions of Model Not Reconstituted on Postback

Portions of my models are not being correctly reconstructed on postback.
Models
public class DemographicsModel
{
public List<QuestionModel> Questions { get; set; }
}
public abstract class QuestionModel
{
[HiddenInput(DisplayValue = false)]
public int ID { get; set; }
[HiddenInput(DisplayValue = false)]
public string Title { get; set; }
}
public abstract class ChooseQuestionModel : QuestionModel
{
public abstract List<SelectListItem> Items { get; set; }
}
public class ChooseManyQuestionModel : ChooseQuestionModel
{
[Required]
[DataType("CheckBoxList")]
public override List<SelectListItem> Items { get; set; }
}
Views
ChooseManyQuestionModel.cshtml
#model X.Y.Z.ChooseManyQuestionModel
<div class="Form Wide NoLabel">
<div class="Title">#this.Model.Title</div>
#Html.TypeStamp()
#Html.EditorFor(m => m.ID)
#Html.EditorFor(m => m.Title)
#Html.EditorFor(m => m.Items)
</div>
CheckBoxList.cshtml
#model IEnumerable<SelectListItem>
#if (!this.Model.IsNullOrEmpty())
{
foreach (var item in this.Model)
{
<div>
#Html.HiddenFor(m => item.Value)
#Html.HiddenFor(m => item.Text)
#Html.CheckBoxFor(m => item.Selected)
#Html.LabelFor(m => item.Selected, item.Text)
</div>
}
}
I believe the issue lies within CheckBoxList.cshtml since these items are not being re-constituted on postback.
HTML Output
<div class="Form Wide NoLabel">
<div class="Title">Question title displays here?</div>
<input id="Questions_1___xTypeStampx_" name="Questions[1]._xTypeStampx_" type="hidden" value="Hrxh2HjDRorBAZWo18hsC0OvbJwyswpDkfTBfNF2NC8=" />
<input data-val="true" data-val-number="The field ID must be a number." data-val-required="The ID field is required." id="Questions_1__ID" name="Questions[1].ID" type="hidden" value="76" />
<input id="Questions_1__Title" name="Questions[1].Title" type="hidden" value="Question title displays here?" />
<div>
<input id="Questions_1__Items_item_Value" name="Questions[1].Items.item.Value" type="hidden" value="148" />
<input id="Questions_1__Items_item_Text" name="Questions[1].Items.item.Text" type="hidden" value="Organization Type 1" />
<input data-val="true" data-val-required="The Selected field is required." id="Questions_1__Items_item_Selected" name="Questions[1].Items.item.Selected" type="checkbox" value="true" /><input name="Questions[1].Items.item.Selected" type="hidden" value="false" />
<label for="Questions_1__Items_item_Selected">Organization Type 1</label>
</div>
</div>
</div>
Controller
public class AccountController : BaseController
{
public ActionResult Demographics()
{
return this.View(new DemographicsModel());
}
[HttpPost]
public ActionResult Demographics(DemographicsModel model)
{
return this.View(model);
}
}
On postback, the DemographicsModel is populated with the correct types (I'm using MvcContrib to handle abstract type binding). The List<Question> is populated with all of the correct data including the ID and Title of each question from the hidden fields. However, List<SelectListItem> within each question is set to null.
Update 1
The issue is definitely occurring because the fields are not named correctly. For instance, the "item" field names are being generated like this:
Questions_1__Items_item_Value
When they should really look like this (addition of item index and removal of erroneous "item"):
Questions_1__Items_1__Value
Similarly, the field IDs are being generated like this (addition of item index and removal of erroneous "item"):
Questions[1].Items.item.Value
Instead of:
Questions[1].Items[0].Value
Using Fiddler with the correct IDs being posted back, the model is constructed correctly with all radio buttons and checkboxes in place.
Try the following.
In ChooseManyQuestionModel.cshtml, change #Html.EditorFor(m => m.Items) to:
#Html.EditorForModel(m => m.Items)
Then, in CheckBoxList.cshtml, change #model IEnumerable<SelectListItem> to:
#model SelectListItem
Finally, in each item, modify each lambda expression, and change item to m, then remove the foreeach loop. This will allow the Editor to iterate through the collection, and should give you correct id generation for each element.
When foreach loop is used the ids generated in HTML are all same.
When for look is used the ids generated with the for loops index so binding is happening correctly and all the data is available after post back.
In this scenario, it seems the Helper class is not doing what you want it to do. I would suggest writing your own helper class to name your inputs exactly as you require them to be.

Resources