Asp dot net MVC Pass Radiobutton Value to Model (or int) - c#

I want to pass the value from my radiobutton to a model, or an integer. The value could be 5 for example.
If I add an input type as text and fill it in, it does pass that value but the value of the radio button will not work.
So my problem is that the id from Adresregelmodel is null
I tried it with an int and with a model but both does not work.
So my code from the view is :
#{
ViewData["Title"] = "Order";
}
<div class="container">
Vorige stap
<h2>Verzending en Betaling</h2>
#using (Html.BeginForm("Order", "Winkelwagen", FormMethod.Post))
{
<label for="des">Adres: </label><br />
foreach (var adresregel in ViewBag.adresregelViewbag)
{
<div class="form-group">
<label><input type="radio" name="Id" id="#adresregel.Id"> #adresregel.Adres, #adresregel.Postcode, #adresregel.Woonplaats</label>
</div>
}
<input type="text" name="Adres" />
<input type="submit" class="btn btn-success" value="Bevesting en bestel" />
}
</div>
This is my controller
[HttpPost]
public IActionResult Order(AdresregelModel adresregel, int Id)
{
// Gebruiker email ophalen
string cookie = Request.Cookies["klantemail"];
// id gebruiker ophalen
GebruikerModel gebruikermodel =
gebruiker.GetGebruikerByMail(cookie);
// Weten welke radio button is geselecteerd
// bestellingmodel maken en vullen
return View();
}
This is my Model :
public class AdresregelModel
{
public int Id { get; set; }
public int GebruikerId { get; set; }
public string Adres { get; set; }
public string Postcode { get; set; }
public string Woonplaats { get; set; }
}

You need to set a value="" attribute on your radio button for that value to be passed
Like:
<input type="radio" name="Id" value="#adresregel.Id">
Then the Id property on your model will be populated with whatever #adresregel.Id contains...
You also probably want to take the
, int Id) off your action method:

Related

Form error message not displaying (ASP.NET CORE)

I've tried and played around a lot, but I can't seem to get my form authentication working.
Before I add functionality to actually create a review, I need to get this working.
The site simply submits the form, regardless of what is in the review text element. It should be catching and displaying an error message if it is blank.
Model:
public class CreatedReview
{
public int Id { get; set; }
[StringLength(60, MinimumLength = 3)]
[Required]
public string Review1 { get; set; }
public int? RestaurantId { get; set; }
public int? UserId { get; set; }
[Required]
public int? Stars { get; set; }
public CreatedReview(string review, int stars)
{
this.Review1 = review;
this.Stars = stars;
}
}
Index.cshtml
#model CreatedReview
#{
}
<h1>Leave a review!</h1>
<form method="post" asp-action="LeaveReview">
<p>Restaurant</p>
<input type="text" name="name" />
<p>Zipcode</p>
<input type="number" name="zipcode" />
<p>Review</p>
<input type="text" name="review" />
<span asp-validation-for="Review1" class="text-danger"></span>
<p>Star Rating</p>
<input type="number" name="stars" />
<input type="submit" />
</form>
Controller:
public IActionResult LeaveReview(string name, int zipcode, string review, int stars)
{
if (!ModelState.IsValid)
{
return View("Index");
}
// create review blah blah blah (need to accept all of the parameters later)
var newReview = new CreatedReview(review, stars);
return View("Index");
}

asp dot net BeginForm post method send nothing to controller

I want to have a form on the webpage /create. This form contains : name, description and price. When filled in, it should send the data to the controller.
De controller does not receive the data and I don't know why.
I tried deleting the pages and recreate them, this did not work. I also tried #html.textlabelfor. this also did not work.
Here is my view code :
#using (Html.BeginForm("Create", "Beheer", FormMethod.Post))
{
<div class="form-group">
<label for="name">Name:</label>
<input type="text" class="form-control" placeholder="Fill article name" name="Naam">
</div>
<div class="form-group">
<label for="des">Description:</label>
<input type="text" class="form-control" placeholder="Fill in article description" name="Omschrijving">
</div>
<div class="form-group">
<label for="price">Price:</label>
<input type="number" class="form-control" placeholder="Fill in article price" name="Prijs">
</div>
<input type="submit" class="btn btn-default" value="submit" />
}
Here is my controller code:
[HttpPost]
public IActionResult Create(ArtikelModel artikelModel)
{
return View(artikelModel);
}
[HttpGet]
public IActionResult Create()
{
return View();
}
Here is my model :
public int Id { get; set; }
public string Naam { get; set; }
public string Omschrijving { get; set; }
public decimal Prijs { get; set; }
public byte[] Foto { get; set; }
public decimal Korting { get; set; }
public List<ReviewModel> Reviews { get; set; }
I expected the ArtikelModel to be filled with data the user put it.
Since you indicated that the controller method doesn't get called at all, the likely issue is the name of your controller as #LaljiDhameliya mentioned. So, since your view lists "Beheer" as the controller, due to ASP.NET MVC convention, your controller should be called "BeheerController" (you didn't include this bit of code in your question, so we can't see if that is the case)

Add a dynamic dropdown field to Razor view

I am building a form based on the model with this structure
public class DynamicFormElementsModel
{
//param might be shown in UI , but will not pass while setting params for report . Example select org.
public bool ReportParameter { get; set; }
public string ParamName { get; set; }
public string ParamLabel { get; set; }
public string ParamType { get; set; }
public bool Visible { get; set; }
public string ParamValue { get; set;}
}
And in Razor i am building the control like
#using (Html.BeginForm("Index", "Reports", FormMethod.Post, new { role = "form" }))
{
#Html.HiddenFor(p => Model.ReportId)
for (int i = 0; i < Model.Parameters.Count(); i++)
{
<div class="form-group">
<label class="control-label">#Model.Parameters[i].ParamLabel</label>
#switch (#Model.Parameters[i].ParamType.ToLower())
{
case "textbox":
if (#Model.Parameters[i].Visible)
{
<input type="text" class="form-control" value="#Model.Parameters[i].ParamValue" name="#Model.Parameters[i].ParamName" />
}
else
{
<input type="hidden" value="#Model.Parameters[i].ParamValue" name="#Model.Parameters[i].ParamName" />
}
break;
default:
break;
}
</div>
}
<input type="submit" class="btn btn-default" value="Submit" />
}
Normal textboxes will be rendered correctly with this approach . But how can i make a dropdown and fill the dropdown from a table id , name value pair from the sql table

How to select an item from <select> tag and save it as Foreign Key in ASP .NET Core 2.0

I have these two classes:
State and Station :
public class State
{
public int Id { get; set; }
[Required]
public string Code { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<Station> Stations { get; set; }
}
and
public class Station
{
public int Id { get; set; }
[Required]
public string Code { get; set; }
[Required]
public string Name { get; set; }
[Required]
public virtual State State { get; set; }
}
The design was "Code First" and I used migration to set up the database and it was like:
The station table saves StateId as foreign Key as it should
My StationsController.cs file has a Create Method in which I use ViewBag for listing the state names like this:
// GET: Stations/Create
public IActionResult Create()
{
ViewBag.StatesList = _context.States.ToList();
return View();
}
And finally my HttpPost Create method
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Code,Name,State")] Station station)
{
if (ModelState.IsValid)
{
_context.Add(station);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(station);
}
My create.cshtml file has <select> tag like this:
<div class="form-group">
<label asp-for="State" class="control-label"></label>
<select asp-for="State" asp-items="#(new SelectList(ViewBag.StatesList, "Id", "Name","State"))" ></select>
<span asp-validation-for="State" class="text-danger"></span>
</div>
The Issue I am facing is that after clicking submit, my ModelState.isValid remains false and the State field is null as shown in this image:
The State Field is null
The Controller has been autogenerated and only two things I have changed: 1st is that I have added the ViewBag.StateList in the Create() method and second is that I have added a State field in Create([Bind("Id,Code,Name,State")].
Any help will be greatly appreciated and sorry for the long post..
regards
Ashutosh
I don't know how many times I have said in SO that you shouldn't send your entity model directly from database to the view, and listen to its postback. You should only generate a model (we call it ViewModel) that represents what the view needs.
Here is what I will do (I wrote everything by hand, not tested).
Create a view model for station creation view:
public class CreateStationViewModel
{
// You shouldn't have Station ID here as it's creation
[Required]
public string Code { get; set; }
[Required]
public string Name { get; set; }
[Display(Name = "State")]
public int SelectedStateId { get; set; }
public IDictionary<int, string> AvailableStates { get; set; }
}
Initialize this view model on the get method:
public IActionResult Create()
{
var vm = new CreateStationViewModel
{
// Construct a list of available states.
// We will use it as the dropdown options.
AvailableStates = _context.States
.ToDictionary(x => x.Id, x => $"{ x.Name }({ x.Code })")
};
return View(vm);
}
Build the form on the view:
#model CreateStationViewModel
#{
// You can define a variable here for the dictionary-to-selectListItem
// conversion.
// Or you can write an extension method on IDictionary for that purpose.
var availableStatesSelectListItems = Model.AvailableStates
.Select(x => new SelectListItem
{
Text = x.Value.ToString(),
Value = x.Key.ToString()
});
}
<form asp-area="" asp-controller="station" asp-action="create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Code" class="control-label"></label>
<input type="text" class="form-control" asp-for="Code" />
<span class="form-text" asp-validation-for="Code"></span>
</div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input type="text" class="form-control" asp-for="Name" />
<span class="form-text" asp-validation-for="Name"></span>
</div>
<div class="form-group">
<label asp-for="SelectedStateId" class="control-label"></label>
<select class="form-control" asp-for="SelectedStateId"
asp-items="availableStatesSelectListItems">
<option value="">- select -</option>
</select>
<span class="form-text" asp-validation-for="SelectedStateId"></span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Create</button>
</div>
</form>
Listen to the view model on postback:
[HttpPost]
public IActionResult Create(CreateStationViewModel model)
{
if (ModelState.IsValid)
{
// You build the entity model from the view model
_context.Stations.Add(new Station
{
Code = model.Code,
Name = model.Name,
StateId = model.SelectedStateId
});
_context.SaveChanges();
return RedirectToAction("index");
}
// Rebuild the available states, or
// better, you can use ajax for the whole form (different topic)
model.AvailableStates = _context.States
.ToDictionary(x => x.Id, x => $"{ x.Name }({ x.Code })");
return View(model);
}
AFAIK you can't pass a State object to be used as the value of the <option> elements inside your <select>. Instead, you have to use a simpler datatype. In practice you need to use StateId as the value.
Add the property StateId to your Station class:
public class Station
{
public int Id { get; set; }
[Required]
public string Code { get; set; }
[Required]
public string Name { get; set; }
public virtual State State { get; set; }
[Required]
public int StateId { get; set; }
}
Also, your SelectList constructor is wrong. The fourth argument ("State" in your example) is supposed to define the default selected item. You don't need to define it here, so leave it out:
<select asp-for="StateId" asp-items="#(new SelectList(ViewBag.StatesList, "Id", "Name"))" ></select>
Now your <select> element should be able to select the correct Id and populate your StateId field. Note that in the [HttpPost] method, the Statewill still be null, but your database should be updated with the correct StateId.

MVC 4 Model Binding returns null

I'm having trouble with model binding in MVC. I have a class:
public class UserSurvey
{
public int Id { get; set; }
public virtual Survey Survey { get; set; }
}
Which is the model for a view:
#model SurveyR.Model.UserSurvey
<form id="surveyForm">
<div class="container survey">
#Html.HiddenFor(x=>x.Id)
#Html.EditorFor(x => x.Survey.Steps)
</div>
<input type="button" value="Submit" id="btnSubmit"/>
</form>
And then for the submit the controller takes a class:
public class SurveyResponseViewModel
{
public int Id { get; set; }
public Survey Survey { get; set; }
}
[HttpPost]
public ActionResult Submit(SurveyResponseViewModel surveyResponse)
{
...
}
When I debug the submit the surveyResponse.Survey object is populated as it should be but the surveyResponse.Id value is 0 when it should be 1.
I can see the Id=1 being passed back in the submit but the model binding doesn't seem to hook it up.
Any help would be greatly appreciated!
Kev
EDIT: The rendered html looks like this:
<form id="surveyForm">
<div class="container survey">
<input data-val="true" data-val-number="The field Id must be a number." data-val-required="The Id field is required." id="Id" name="Id" type="hidden" value="1" />
So yes the value appears there and is also passed in the submit if I look using dev tools.
EDIT 2: The Form data in dev tools definitely contains "Id:1".
Your Code seems to be fine.Try passing the id value explicitly as another parameter like below
[HttpPost]
public ActionResult Submit(SurveyResponseViewModel surveyResponse , int Id )
{
surveyResponse.Id = Id
}
I have tested. Its working fine.
public ActionResult test1()
{
var model = new UserSurvey();
model.Id = 10;
return View(model);
}
[HttpPost]
public ActionResult test1(SurveyResponseViewModel surveyResponse)
{
var x = surveyResponse.Id; // returns 10
return View(new UserSurvey());
}
public class SurveyResponseViewModel
{
public int Id { get; set; }
public Survey Survey { get; set; }
}
public class UserSurvey
{
public int Id { get; set; }
public virtual Survey Survey { get; set; }
}
public class Survey
{
public string Steps { get; set; }
}
#model TestWeb.Controllers.UserSurvey
#using (Html.BeginForm())
{
<div class="container survey">
#Html.HiddenFor(x=>x.Id)
#Html.EditorFor(x => x.Survey.Steps)
</div>
<input type="submit" value="Submit" id="btnSubmit"/>
}

Categories