Reading the value of Radio Button in asp.net mvc - c#

Can anyone tell me how to read the value of checked radio button from my View and save this value in database attribute type_of_user. the following is part of the view:
<div class="form-group">
<div class="control-label col-md-2">
Account Type: </div>
<div class="col-md-10">
#Html.RadioButton("AccountType", "Individual", true) Individual
#Html.RadioButton("AccountType", "Organization", false) Organization
#Html.ValidationMessageFor(model => model.Type_of_user)
</div>
</div>
and in The controller I placed this code:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include="Username,Password,Status,Email,Type_of_user,admin_id")] Account account)
{
if (ModelState.IsValid)
{
db.Accounts.Add(account);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.admin_id = new SelectList(db.Adminstrators, "Admin_ID", "Phone", account.admin_id);
return View(account);
}

Related

ResetPassword feature doesn't use code from link

I have an old MVC website I'm looking at. I don't understand the following code in my Account controller. (I believe this was code generated by ASP.NET.)
Controller
//
// GET: /Account/ResetPassword
[AllowAnonymous]
public ActionResult ResetPassword(string code)
{
return code == null ? View("Error") : View();
}
//
// POST: /Account/ResetPassword
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model)
{
if (!ModelState.IsValid)
{
return View(model);
}
var user = await UserManager.FindByNameAsync(model.Email);
if (user == null)
{
// Don't reveal that the user does not exist
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password);
if (result.Succeeded)
{
return RedirectToAction("ResetPasswordConfirmation", "Account");
}
AddErrors(result);
return View();
}
View
#model OnBoard101.Models.ResetPasswordViewModel
#{
ViewBag.Title = "Reset password";
}
<h2>#ViewBag.Title</h2>
#using (Html.BeginForm("ResetPassword", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Reset your password</h4>
<hr />
#Html.ValidationSummary("", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Code)
<div class="form-group">
#Html.LabelFor(m => m.Email, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Email, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Password, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.Password, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.ConfirmPassword, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.PasswordFor(m => m.ConfirmPassword, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" class="btn btn-success" value="Reset" />
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
These methods are called when the user uses the Forgot Password feature and then clicks the link that is sent to them in an email.
As best I can tell, the POST handler correctly detects an invalid code in the link (it produces an Invalid Token error when the code is not value). But I don't understand how. The GET handler seems to simply discard the code argument.
I don't get how this code works. How does model.Code ever get populated?
The ResetPassword feature does use code from the link.
Model binding retrieves data from various sources such as route data, form fields, and query strings.
It inspects the query string parameters for matching properties on the model used by the view
While it may appear like the code is being discarded by the Controller GET action, the code is still a part of the request and used by the view.
And since the view explicitly binds to a model
#model OnBoard101.Models.ResetPasswordViewModel
which has a matching public Code property (case-insensitive)
public string Code { get; set; }
it will bind it to the model in the view during the GET and then use it (the model) to populate a hidden form field (as shown in your View markup)
#Html.HiddenFor(model => model.Code)
So now when the form is submitted, the POST action will bind that field to the model posted back to the action and perform the validation
The same could have been achieved with
// GET: /Account/ResetPassword
[AllowAnonymous]
public ActionResult ResetPassword(string code) {
if (code == null) return View("Error");
var model = new ResetPasswordViewModel {
Code = code
};
return View(model);
}
But since the built-in model binding functionality would initialize a model if one was not provided, the above code really does not add anything additional to what the framework does out-of-the-box.

Return Partial View Via Controller Method

I have a Search Partial View that I want to return but I want to return it by running it through an exisiting Partial View Result in the Controller instead of loading the view directly.
So, in the controller I have:
public ActionResult Index()
{
return View();
}
public PartialViewResult _GetSearch(List<Search> model)
{
return PartialView("_Search", model);
}
[ValidateAntiForgeryToken()]
public PartialViewResult _BeginSearch(string search)
{
var results = SearchModels(search).ToList();
return PartialView("_GetSearch", results);
}
And in the search view itself I have:
<div class="col-md-4">
<div id="modelSearch" class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><i class="fa fa-search"></i> Search by Model / Manufacturer</h3>
</div>
<div class="panel-body">
#using (Ajax.BeginForm("_BeginSearch", "Home", new AjaxOptions() { UpdateTargetId = "modelSearch" }))
{
#Html.AntiForgeryToken()
<div class="input-group">
#Html.TextBox("search", null, new {id = "name", #class = "form-control", placeholder = "Please enter a manufacturer or model"})
<span class="input-group-btn">
<button id="search" class="btn btn-default" type="submit"><i class="fa fa-search"></i></button>
</span>
</div>
if (Model != null)
{
<div class="searchResults fade">
#foreach (var s in Model)
{
<div class="result">
#switch (s.ResultType)
{
case "Man":
#s.Manufacturer
break;
case "Mod":
#s.Manufacturer #s.Model
<img src="~/Images/General/(#s.TierId).png" alt="Tier #s.TierId"/>
break;
}
</div>
}
</div>
}
}
</div>
</div>
</div>
When I try and run the code it tell me that it cannot find the _GetSearch view, which yes technically is right, but I'm not looking for a view I'm looking for a method in the controller.

Fill value by default form in .NET

I have a IdentityUser Model
I have a Manage View with 3 partials (each one have one viewmodel and controller) I want to enter on this view and see the forms with data filled of the model.
ApplicationUser : IdentityUser (Model of my user)
using Microsoft.AspNet.Identity.EntityFramework;
using System;
namespace MTGWeb.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser
{
public String Pais;
public String Email;
public DateTime UltimoLogin;
public DateTime FechaRegistro;
public String Tipo;
public Boolean Activado;
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
}
Manage (Main View)
#using MTGWeb.Models;
#using Microsoft.AspNet.Identity;
#{
ViewBag.Title = "Administrar cuenta";
}
<h2>#ViewBag.Title.</h2>
<p class="text-success">#ViewBag.StatusMessage</p>
<div class="row">
<div class="col-md-12">
<p>Ha iniciado sesión como <strong>#User.Identity.GetUserName()</strong>.</p>
#Html.Partial("_ChangePasswordPartial")
#Html.Partial("_ChangeEmailPartial")
#Html.Partial("_OtherFieldsPartial")
</div>
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
_ChangeEmailPartial
#using Microsoft.AspNet.Identity
#model MTGWeb.Models.ManageUserViewModelEmailChange
#using (Html.BeginForm("ManageEmail", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h4>Formulario para cambiar email</h4>
<hr />
#Html.ValidationSummary()
<div class="form-group">
#Html.LabelFor(m => m.OldEmail, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.OldEmail, new { #class = "form-control", Value = Model.OldEmail})
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.NewEmail, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.NewEmail, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.ConfirmEmail, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.ConfirmEmail, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Cambiar email" class="btn btn-default" />
</div>
</div>
}
Controller - ManageEmail
// Cambia el email
// POST: /Account/ManageEmail
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ManageEmail(ManageUserViewModelEmailChange model)
{
ViewBag.ReturnUrl = Url.Action("Manage");
var user = await UserManager.FindByNameAsync(User.Identity.Name);
if (ModelState.IsValid)//Si no hay errores en la validación que hace la clase (Datatype, length, required, etc..)
{
if (model.OldEmail.Equals(model.NewEmail) && model.OldEmail.Equals(user.Email))
{
user.Email = model.NewEmail;
IdentityResult success = await UserManager.UpdateAsync(user);
if (success.Succeeded)
{
return RedirectToAction("Manage", new { Message = ManageMessageId.ChangeEmailSuccess });
}
}
}
//Si el modelo no es válido o no el cambio no ha tenido exito
return View(model);
}
I have 2 more controllers for others partials, but this is usefull for the example. These Model.OldEmail is null and causes a Nullreference error, Where I have to fill it? I guess that this have to be filled in AccountController/Manage, but.. How can I send it to the partials?
I am new on MVC and .NET, I used to work with Java, and I am stucked in this (Is a testing project purposes)
pass the model you want the partials to show into the partials as an argument
you will need to add a viewmodel containing the models you want to show to the host view.
eg
#Html.Partial("_ChangePasswordPartial",Model.ChangePAsswordViewModel)
Model is a property on Controller (which your manage controller will inherit from)
You pass the viewmodel into the manage view from the controller in return View(YourViewModelInstance) from your Manage controller method.
you also need to add a reference to that model in your manage form like you have in your partials
Eg
#model MTGWeb.Models.ManageViewModel
your manage viewmodel might look something like
public class ManageViewModel
{
public ChangePasswordViewModel ChangePasswordViewModel{get;set;}
public NextViewModel NextViewModel{get;set;}
public AnotherViewModel NextViewModel{get;set;}
}

MVC Create returns null object

I'm having a problem in my MVC project. When trying to create an object to add it to the db, it always returns null.
public class ListsModel
{
public EntitiesList EntityList { get; set; }
public List<string> AllGroups { get; set; }
}
public ActionResult Create()
{
ListsModel model = new ListsModel();
model.EntityList = new EntitiesList();
model.AllGroups = managerLists.GetAllListsKeys(); //For droplist
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ListsModel model)
{
if (ModelState.IsValid)
{
model.EntityList.List_CreatedTime = DateTime.Now;
managerLists.AddNewObject(model.EntityList);
return RedirectToAction("Index");
}
return View(model);
}
And a simple cshtml:
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>EntitiesList</legend>
<div class="form-group">
#Html.LabelFor(model => model.EntityList.List_EntitityName)
#Html.DropDownListFor(model => model.AllGroups, new SelectList(Model.AllGroups),
new { #class = "form-control" })
<p class="help-block">#Html.ValidationMessageFor(model => model.EntityList.List_EntitityName)</p>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EntityList.List_EntityValue)
<input class="form-control" value="#Model.EntityList.List_EntityValue"/>
<p class="help-block">#Html.ValidationMessageFor(model => model.EntityList.List_EntityValue)</p>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EntityList.List_OrderByNumber)
<input class="form-control" value="#Model.EntityList.List_OrderByNumber"/>
<p class="help-block">#Html.ValidationMessageFor(model => model.EntityList.List_OrderByNumber)</p>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EntityList.List_Comments)
<textarea class="form-control" rows="3">#Model.EntityList.List_Comments</textarea>
<p class="help-block">#Html.ValidationMessageFor(model => model.EntityList.List_Comments)</p>
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
When it's getting to the "model.EntityList.List_CreatedTime = DateTime.Now;" a null reference exception is thrown.
I tried to change the signature to "public ActionResult Create(ListsModel ListsModel)", as suggested here: Create view is posting null objects
But I got the same results.
Hope you can help me.
I think the problem is the way you define inputs like this:
<input class="form-control" value="#Model.EntityList.List_EntityValue"/>
For ASP MVC can collect form data, inputs should have an Name attribute corresponding with model fields.
Try to generate inputs using the standard:
#Html.TextBoxFor(model => model.EntityList.List_EntityValue)
I suggest you inspect the differences in the html generated (to see how is asp mvc generating inputs).

When I press submit button there is no postback

I am new to MVC and I am stuck in creating a submit form.
Model Email.cs:
using System.Web;
namespace MySite.Models
{
public class Email
{
public string From { get; set; }
public string Subject { get; set; }
public string body { get; set; }
}
}
Controller CommunicationController.cs:
namespace MySite.Controllers
{
public class CommunicationController : Controller
{
public ActionResult SendEmail() {
Email email = new Email();
return View(email);
}
[HttpPost]
public ActionResult SendEmail(Email email)
{
if (ModelState.IsValid)
{
}
return View(email);
}
}
}
View SendEmail.cshtml:
#model MySite.Models.Email
#{
ViewBag.Title = "SendEmail";
}
<h2>#Html.Label("Send email")</h2>
#using(Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.Label("From")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.From)
</div> <div class="editor-label">
#Html.Label("Subject")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Subject)
</div> <div class="editor-label">
#Html.Label("Body")
</div>
<div class="editor-field">
#Html.EditorFor(model => model.body)
</div>
<input id="btnSubmit" type="submit" value="SendEmail" />
}
When I press submit, the event never gets fired. In the controller if I press 'go to view' then it goes to SendEmail view. I have no idea whats happenning. I tried to debug but the [HttpPost] controller never gets fired.
Here is what I get from browser, I don't see action
<form method="post" action="/" novalidate="novalidate">
<input type="hidden" value="ZktM_I7fzdlcNme4YVEcNNpnFFmQu1cpAuTXarO_V4w-7bPmpHkaLRfNY3cXGMYy7wkRgSJWW‌​SkS8lp5vdRimFrNCgqk0Jfdr4v7Zc3V2pg1" name="__RequestVerificationToken">
<div class="editor-label">
<div class="editor-field">
<input id="From" class="text-box single-line" type="text" value="" name="From">
</div>
<div class="editor-label">
<div class="editor-field">
<div class="editor-label">
<div class="editor-field">
<input id="btnSubmit" type="submit" value="SendEmail">
</form>
Try this,
#using (Html.BeginForm("ActionName", "ControllerName",
FormMethod.Post))
{
//form UI
<input id="btnSubmit" type="submit" value="SendEmail" />
}
Edit
You can also try this:
<a onclick="$('#formId').submit();">Submit</a>
or
<button type="submit">Submit</button>
I rarely use the basic helper, so I could be wrong, but I believe the default method you get from
Html.BeginForm()
is a GET. So, you probably want to use
Html.BeginForm("SendEmail", "Communication", FormMethod.Post, new { /* html attributes */ })
Then, to test whether you're actually hitting the controller, add this inside the action:
ModelState.AddModelError("", "Action was called!");
That will show up as an error in your ValidationSummary, which is okay, since we're just debugging here.
I'm a little late to the party...
Try replacing:
<input id="btnSubmit" type="submit" value="SendEmail" />
With:
<button id="btnSubmit" type="submit" name="submitButton value="SendEmail" />
Let us know if this works, or if you found another solution! :)

Categories

Resources