Passing data from view to controller MVC3 - asp.net-mvc-3

I recently came across the MVC tutorial on ASP.Net. I was trying to create a similar project (MVC3 Razor) where you can register the details. However, when I click the submit button the values of all properties in the parameter User is always null. I'm not able to figure out why the data is not getting passed from the view to the controller.
Even in the tutorial in the Create.cshtml they just use the Submit button as
<input type="submit" value="Create" />
and the code in Create Action in MoviesController.cs is as follows
[HttpPost]
public ActionResult Create(Movie movie)
{
if (ModelState.IsValid)
{
db.Movies.Add(movie);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(movie);
}
In this tutorial when I submit, I get the form data in parameter movie. However, In my sample project I get it as null. I'm new to MVC and it would be great if you could help me our with this. Please find my code below.
Register.cshtml - While creating this view I have selected "Create a strongly-typed view" option and the Scaffold template option as "Empty"
#model MvcRegister.Models.User
#using (Html.BeginForm())
{
<div>
<div>Name</div><div>#Html.EditorFor(model => model.Name)</div>
<div>Email</div><div>#Html.EditorFor(model => model.Email)</div>
<div>Phone</div><div>#Html.EditorFor(model => model.Phone)</div>
<div><input type="submit" value="Register" /></div>
</div>
}
RegisterController.cs
public class RegisterController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Register()
{
return View();
}
[HttpPost]
public ActionResult Register(User user)
{
return RedirectToAction("Index");
}
}
User.cs
public class User
{
[Required]
public string Name;
[Required]
public string Email;
[Required]
public string Phone;
}
My project Source code available at http://www.filedropper.com/mvcregister and the Sample Movie project at http : //www.filedropper.com/mvcmovie

Change your User class as below. You have missed getter and setter.
public class User
{
[Required]
public string Name { get; set; }
[Required]
public string Email { get; set; }
[Required]
public string Phone { get; set; }
public string IP { get; set; }
public string Password { get; set; }
}
And also you need to add following java-scripts to get the validation work.
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
Thanks!

Related

How to send selected radiobutton value from view to controller in asp.net core

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 after choosing a radio button and after that select the button. it send null value to the Index method.
Here my radio button code in razor
#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; }
[BindProperty]
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([FromForm] string currentYear)
{
...
}
The problem you're having is because of this:
[HttpPost]
public IActionResult Index([FromForm] string currentYear)
On your form, the value you want to bind is called Year, but in your POST action, you're specifying a parameter called currentYear. MVC doesn't know that you want to bind the value of Year to currentYear. Model binding is all based on the convention of property names on your model being the same as the data being sent from a form.
So all you need to do is change your POST method to this:
[HttpPost]
public IActionResult Index(string year)
Notice how I've also removed the [FromForm] attribute. You don't need to specify that here in order for it to bind properly. I'm guessing you added it while trying to figure out why it wasn't working. For the same reason, you also don't need the [BindProperty] attribute on your viewmodel - it's the name of the property that is important.

why dropdownlist in mvc4 throws error where mvc3 work well

Could you tell me please does MVC4 has different dropdownlist then mvc3?
I made the same test project in mvc4 and mvc 3:
in TransactionController
public ActionResult Create()
{
var listme=db.Transacts.ToList();
ViewBag.TransactId = new SelectList(listme, "TransactId", "TransactionName");
return View();
}
in create view
#model HomeAccounting.Domain.Transaction
...some code
#using (Html.BeginForm())
...some code
#Html.DropDownList("TransactId",String.Empty)
...some code
< input type="submit" value="Create" />
Result
Dropdown list provides mistake in mvc4 when you submit form. But MVC3 works perfectly
What is the reason? If mvc4 and mvc3 helpers are different how to find out there difference? F12? but there are almost the same.. do I have to investigate this differences everytime, it's not comfortable?
*Error
There is no ViewData item of type 'IEnumerable< SelectListItem >' that has the key « TransactId »*
*info
public class Transaction
{
public virtual int Id { get; set; }
public int TransactId { get; set; }
public virtual Transact Transact { get; set; }
}
public class Transact
{
[Key]
public virtual int TransactId { get; set; }
public virtual string TransactionName { get; set; }
}
Try using #Html.DropDownListFor(model => model.Field) and then pass in your model instead of a string id.

Remote validation attribute in MVC3 invalid get format

I trying to use remote validation for the first time, but am encountering problems with the parameters passed inot the remote validation method.
My model is as follows:
public class PerinatalWomanView : IPerinatalWoman
{
[Required(ErrorMessage = "The woman's postcode is required")]
[Display(Name = "Woman's postcode")]
[Remote("PostcodeCheck", "Validation", "Validation")]
[RegularExpression("^[a-zA-Z]{1,2}[0-9][0-9A-Za-z]{0,1} [0-9][A-Za-z]{2}$", ErrorMessage = "A valid postcode is required")]
public string Postcode { get; set; }
The view snippet is:
<div class="editor-label control-label">
#Html.LabelFor(m => m.perinatalWomanView.Postcode)
</div>
div class="editor-field controls">
#Html.EditorFor(m => m.perinatalWomanView.Postcode)
#Html.ValidationMessageFor(m => m.perinatalWomanView.Postcode)
</div>
and the validation controller is:
public class ValidationController : Controller
{
//
// GET: /Validation/Validation/
[HttpGet]
public JsonResult PostcodeCheck(string Postcode)
{
// postcode has already been checked for correct format
// now look it up to see if it exists
string mbrraceCommonCodeEntitiesConnectionString = ConfigurationManager.ConnectionStrings["MbrraceCommonCodeEntities"].ConnectionString;
if (PostcodeChecks.CheckPostcodeExists(mbrraceCommonCodeEntitiesConnectionString, Postcode))
{ return Json(true, JsonRequestBehavior.AllowGet); }
return Json("This postcode was not found in the database", JsonRequestBehavior.AllowGet);
}
When the controller is called the value of Postcode is null. The actual call - from Firebug - is:
http://localhost:57881/Validation/Validation /PostcodeCheck?perinatalWomanView.Postcode=OX4+1SU
How do I read the postcode string parameter correctly becuase it is clearly not null?
HELP!
You could have a view model like this:
public class AddressViewModel
{
public string Postcode { get; set; }
}
and then use specify the Prefix by decorating the parameter with the [Bind] attribute:
[HttpGet]
public ActionResult PostcodeCheck(
[Bind(Prefix = "perinatalWomanView")]AddressViewModel model
)
{
// use model.Postcode here ...
}
or if you don't want to use the Bind attribute have the following models:
public class MyViewModel
{
public AddressViewModel PerinatalWomanView { get; set; }
}
public class AddressViewModel
{
public string Postcode { get; set; }
}
and then have your controller action take the view model:
[HttpGet]
public ActionResult PostcodeCheck(MyViewModel model)
{
// use model.PerinatalWomanView.Postcode here ...
}

Razor proxy type error. System.Data.Entity.DynamicProxies

I have a class User and then another Type UserSpecial with some special user properties.
I pass it in razor to the partial method class to create the UserSpecial form which expects an object of type User Special but i get an error.
#model User
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
#Html.Partial("../UserSpecial/_CreateOrEdit", Model.UserSpecial)
<p class="submit clear">
<input type="submit" value="Register" />
</p>
</fieldset>
}
</div>
Error i get -
The model item passed into the dictionary is of type 'System.Data.Entity.DynamicProxies.User_AC9DED50C9495788046D6BFA3B90DDFC6AD2884157CF23C91FCB3B7A55F70B18', but this dictionary requires a model item of type 'UserSpecial'.
What am i doing wrong here?
From my controller i just pass the current User Object that i have stored in the session state.
Controller -
public ActionResult Register()
{
return View(userRepository.Current);
}
Here Current is of type "User"
Model -
public partial class User
{
public User()
{
}
public int UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Sex { get; set; }
public System.DateTime CreateDate { get; set; }
public string Email { get; set; }
public string HomeTown { get; set; }
public short UserType { get; set; }
public virtual UserSpecial UserSpecial { get; set; }
}
Model Declaration for _CreateOrEdit is
#model UserSpecial
No idea what userRepository.Current is but it seems that it doesn't correctly/eagerly load the UserSpecial property. Why don't you use view models? Why are you passing domain entity models to your views? That's bad practice. You should define view models that contain only the data that's required by your view and then in your controller action map between your domain models and the corresponding view model which will be passed to the view.
The solution for this issue is pretty simple:
You should just use a wrapper class (view model) as Darin suggested.
So for example:
(entity domain model):
public class MyEntityModel
{
public int Id { get; set; }
public String Name { get; set; }
}
=> put it in a ViewModel (just a stupid wrapper) should result in this
public class MyViewModel
{
public MyEntityModel MyEntityModel { get; set; }
}
Now, in the view, u should be able to access the "name" property by doing this
<div>
The entity object's name is "#model.MyEntityModel.Name"
</div>
(notice you should not use #model.Name!)

MVC3 passing base class to partial View - submitting form only has parent class values

I have a number of child ViewModel classes which inherit from an base ViewModel class.
I pass my child ViewModel into my View, which then passes itself into a partial view.
The main view takes the child type, but the partial view takes the Parent type.
Everything displays correctly when I manually populate the properties.
However, when I Submit the form, my controller action only has properties for the Child class - none of the base class properties are completed?
e.g.
public abstract class BaseDetails
{
public string Name { get; set; }
public BaseDetails()
{ }
public BaseDetails(string name)
{
Name = name;
}
}
public class LocalDetails:BaseDetails
{
public int Visits { get; set; }
public LocalDetails()
{ }
public LocalDetails(int visits, string name)
:base(name)
{
Visits = visits;
}
}
With the View as simple as:
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Visits)
<br />
#Html.Partial("Name", Model)
<input id="Submit1" type="submit" value="submit" />
}
The partial view has a single textbox on it.
In IE: ViewSource shows the form tag is around both tetxboxes.
However, when I submit to the controller method:
[HttpPost]
public ActionResult EditLocal (LocalDetails model)
model.Visits is correctly populated, but model.Name is null?
Any ideas?
I added parameterless constructors to the classes because I got an exception upon submission if I didn't.
Unable to reproduce. Works fine for me. Notice that I am not using any constructors with my view models because the model binder wouldn't be able to call them and that all the properties must to have public getters and setters.
Model:
public abstract class BaseDetails
{
public string Name { get; set; }
}
public class LocalDetails : BaseDetails
{
public int Visits { get; set; }
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new LocalDetails());
}
[HttpPost]
public ActionResult Index(LocalDetails model)
{
return View(model);
}
}
View (~/Views/Home/Index.cshtml):
#model LocalDetails
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Visits)
<br />
#Html.Partial("Name", Model)
<input type="submit" value="submit" />
}
Partial (~/Views/Home/Name.cshtml):
#model BaseDetails
#Html.TextBoxFor(x => x.Name)
When I submit the form inside the POST Index action both model properties Name and Visits are correctly bound with values from the form.

Resources