please help me.
i can not bind the input parameter from textbox in to actionmethod
Controller code:
public ActionResult CheckUser(string empCode) // ActionMethod with parameter
{
try
{
string res = "";
DataSet dataSet = new DataSet();
using (SqlConnection connection = new SqlConnection(ConnectionString))
{
using (SqlCommand command = new SqlCommand("spUserCheck"))
{
command.Parameters.AddWithValue("#UserCode", empCode);
command.CommandType = CommandType.StoredProcedure;
connection.Open();
command.Connection = connection;
SqlDataAdapter dataAdapter = new SqlDataAdapter();
dataAdapter.SelectCommand = command;
dataAdapter.Fill(dataSet);
connection.Close();
}
}
if (dataSet.Tables.Count > 0)
{
res = "Alredy Avilable";
}
else
{
res = "Not Avilable. Please create user";
}
return View(res) ;
}
catch (Exception ex)
{
throw new Exception("Error ", ex);
}
}
ViewCode:-
<div class="form-group">
<label class="control-label col-sm-2">Employee Code <span class="mandatory"></span>:</label>
<div class="col-sm-3">
<input type="text" class="form-control input-md" id="empCode" placeholder="Enter employee code" />
</div>
<div class="col-sm-2">
<input type="button" class="btn btn-info" onclick="location.href='#Url.Action("CheckUser", "User")'" id="btnAvaiaable" value="Check Availability ?" />
</div>
</div>
ModelCode
public class UserParameter
{
public string empCode { get; set; }
public string Role { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailID { get; set; }
public int MobileNo { get; set; }
public string Zone { get; set; }
public string State { get; set; }
public string Branch { get; set; }
public string CompanyType { get; set; }
}
First issue is you need a textbox with attribute name="empCode".
Second, you need to wrap the textbox in a form element.
Third, you need to post to the controller. Just changing the location in a button click (as you are doing) will do a get with no form data attached.
There are plenty of samples online which show this.
Related
In my program the admin has the ability to delete managers that are in a drop down list. I am having trouble getting the actual value to pass through when the button is clicked. Currently it passes a 'null' value. I want the value deleted from the database when the button is clicked.
MY VIEW
<div id="addManagerBox" class="admin-home-container-settings boxlike">
<div class="admin-home-itm-settings thinner">
<h2>Add Project Manager</h2>
#Html.TextBoxFor(m => m.manager, new {#class = "form-control" })
<a id="btnAddManager" class="btn btn-lg btn-primary margintop">Add Manager</a>
</div>
<div class="admin-home-itm-settings thinner">
<h2>Delete Project Manager</h2>
#Html.DropDownListFor(m => Model.selectedManager, Model.AllManagers,"--Select Project Manager--", htmlAttributes: new { #class = "form-control" })
<button id="btnDeleteManager" class="btn btn-lg btn-danger margintop">Delete Manager</button>
</div>
AJAX CODE
$("#btnDeleteManager").click(function () {
$.post("/Settings/DeleteManager",
{
selectedManager: $('#selectedManager').val()
},
function (data) {
if (data == "True") {
} else {
}
});
});
MY MODEL VIEW
public class AppSettingsViewModel
{
public string manager { get; set; }
public string purpose { get; set; }
[Required(ErrorMessage = "Email is required")]
[Display(Name = "RegisterEmail")]
public string registerEmail { get; set; }
[Required(ErrorMessage = "Project Manager is required")]
[Display(Name = "Manager")]
public string selectedManager { get; set; }
public List<Managers> allManagers { get; set; }
public List<SelectListItem> AllManagers { get; set; }
[Required(ErrorMessage = "Purpose is required")]
[Display(Name = "Purpose")]
public string selectedPurpose { get; set; }
public List<Purposes> allPurposes { get; set; }
public List<SelectListItem> AllPurposes { get; set; }
[Required(ErrorMessage = "Image History is required")]
[Display(Name = "ImageHistory")]
public string ImageHistory { get; set; }
public List<Questions> allQuestions { get; set; }
public List<Settings> allSettings { get; set; }
public AppSettingsViewModel()
{
allSettings = new List<Settings>();
allPurposes = new List<Purposes>();
allManagers = new List<Managers>();
allQuestions = new List<Questions>();
}
}
CONTROLER
[HttpPost]
public bool DeleteManager(string manager)
{
var managerRepo = new SiteContentRepository();
return managerRepo.EditManager(manager, "delete");
}
Your parameters are not matching. Your controller needs manager and you are passing selectedManager. Try this.
$.post("/Settings/DeleteManager",
{
manager: $('#selectedManager').val()
},
function (data) {
if (data == "True") {}
else {}
});
Give your drop down an id value that matches what you are using in JQuery:
htmlAttributes: new { #class = "form-control", #id = "selectedManager" })
You're JQuery code:
manager: $('#selectedManager').val() //Changed this to accept the same named parameter as server side
I have a Model which i want to edit (Location).This model has a field called ActivityId.I am sending an array of ActivityId-s via ViewData to the view and transform them to a SelectList.
I want the ActivityId field (long) of the Location to be set with the selected item from the dropdownlist (string) - i need a conversion done somehow from string to long before entering the Post Action of the controller.(EditConfirmed)
Models:
[Table("location")]
public partial class Location
{
public Location()
{
StoryLocation = new HashSet<StoryLocation>();
UserStoryLocation = new HashSet<UserStoryLocation>();
}
[Column("id", TypeName = "bigint(20)")]
public long Id { get; set; }
[Column("description")]
[StringLength(255)]
public string Description { get; set; }
[Column("name")]
[StringLength(255)]
public string Name { get; set; }
[Column("activity_id", TypeName = "bigint(20)")]
public long? ActivityId { get; set; }
[ForeignKey("ActivityId")]
[InverseProperty("Location")]
public Activity Activity { get; set; }
}
}
[Table("activity")]
public partial class Activity
{
public Activity()
{
Location = new HashSet<Location>();
}
[Column("activity_id", TypeName = "bigint(20)")]
public long ActivityId { get; set; }
[Column("description")]
[StringLength(255)]
public string Description { get; set; }
[Column("name")]
[StringLength(255)]
public string Name { get; set; }
[Column("type")]
[StringLength(255)]
public string Type { get; set; }
[InverseProperty("Activity")]
public ICollection<Location> Location { get; set; }
}
Controller:
[HttpGet]
public IActionResult Edit(long id = 0)
{
Location loc = this.context.Locations.Find(id);
if (loc == null)
{
return NotFound();
}
ViewData[Constants.ViewData.TActivities]=this.context.Activities
.Select(elem=>
new SelectListItem
{
Text=elem.Name,
Value=elem.ActivityId.ToString()
}
).ToList();
return View(loc);
}
View
#using AdminMVC.Models
#using AdminMVC.ConfigConstants
#using Newtonsoft.Json
#model AdminMVC.Models.Location
#{
List<SelectListItem> dropActivities=ViewData[Constants.ViewData.TActivities] as List<SelectListItem>;
}
<html>
<head>
</head>
<body>
<div id="form">
</div>
<div id="page">
#using (Html.BeginForm("Edit","Location",FormMethod.Post))
{
<div id="table">
<label>Set Location:</label>
<table border="">
#Html.DisplayFor(x=>x.Id)
<tr>
<td>#Html.DisplayNameFor(x=>x.Name)</td>
<td>#Html.EditorFor(x=>x.Name)</td>
</tr>
<tr>
<td>#Html.DisplayNameFor(x=>x.Description)</td>
<td>#Html.EditorFor(x=>x.Description)</td>
</tr>
<div>
<label >Select Activity:</label>
#Html.DropDownList("Activity",dropActivities) //i need to somehow convert the selected value from the dropdown to long before the form is sent to the controller
</div>
</table>
</div>
<div id="control-panel">
<input type="submit" value="Edit">
</div>
}
</body>
</div>
</html>
Post to Controller
[HttpPost, ActionName("Edit")]
public IActionResult EditConfirmed(Location editLoc)
{
if (ModelState.IsValid)
{
this.context.Entry(editLoc).State = EntityState.Modified;
this.context.SaveChanges();
return RedirectToAction("Index");
}
return View(editLoc);
}
P.S:So far the ActivityId of the Location sent to the Post Action is null.I need it to be long.
I solved this problem using the ViewData component.I would first serialize the SelectList using NewtonSoft then i would add it to the ViewData dictionary.When rendering the view i would use the DropDownList razor Html Helper method.
Model
public class FixedLocation
{
[Column("id", TypeName = "bigint(20)")]
public long Id { get; set; }
[Column("coords")]
[StringLength(255)]
public string Coords { get; set; }
[Column("name")]
[StringLength(255)]
[Required]
public string Name { get; set; }
[Column("google_id")]
[StringLength(255)]
[Required]
public string GoogleId { get; set; }
}
Extension method for getting a List of SelectListItem
public static IEnumerable<SelectListItem> ToSelectList<T,Tkey,Tvalue>(
this IQueryable<T> myenum,
Func<T,(Tkey,Tvalue)>kvpair)
{
return myenum.Select(elem=>kvpair(elem))
.Select(tuple=>new SelectListItem{
Text=tuple.Item1.ToString(),
Value=tuple.Item2.ToString()
});
}
Controller:
public IActionResult Create()
{
Location targetLocation = new Location();
ViewData[Constants.ViewData.TFixedLocations]=
this.context.FixedLocation
.ToSelectList<FixedLocation,string,long>
(elem=>(elem.Name,elem.Id)).ToList();
return View(targetLocation);
}
View:
#using AdminMVC.Models
#model AdminMVC.Models.Location
#using AdminMVC.ConfigConstants
#{
dropFixedLocations=ViewData[Constants.ViewData.TFixedLocations] as List<SelectListItem>;
}
<div>
<label >Select FixedLocation:</label>
#Html.DropDownListFor(x=>Model.Id,dropFixedLocations)
</div>
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
I added the code to show many checkboxes from my table (HairTags) and in my form CreationUpload.cshtml i got the following error :
An exception of type 'System.NullReferenceException' occurred in
App_Web eba142hb.dll but was not handled in user code Additional
information: Object reference not set to an instance of an object.
Object reference not set to an instance of an object.
<div class="col-md-12">
#for (int i = 0; i < Model.CreationHairTags.Count; i++)
{
#Html.CheckBoxFor(m => Model.CreationHairTags[i].IsChecked)
#Model.CreationHairTags[i].Text
#Html.HiddenFor(m => Model.CreationHairTags[i].Value)
#Html.HiddenFor(m => Model.CreationHairTags[i].Text)<br />
}
</div>
this is my model Creation.cs (in bold the added code)
namespace HairCollection3.Models
{
public class Creation
{
public string UserId { get; set; }
[Key]
public int CreationId { get; set; }
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ViewRes.ValidationStrings))]
[Display(Name = "Sex", ResourceType = typeof(ViewRes.Names))]
public string CreationSex { get; set; }
[Required(ErrorMessageResourceName = "Required", ErrorMessageResourceType = typeof(ViewRes.ValidationStrings))]
[Display(Name = "CreationTitle", ResourceType = typeof(ViewRes.NamesCreation))]
[StringLength(2000)]
[AllowHtml]
public string CreationTitle { get; set; }
public string CreationPhotoBis { get; set; }
public string Creationtag { get; set; }
public virtual ICollection<CreationLike> CreationLikes { get; set; }
}
public class CreationLike
{
public int CreationId { get; set; }
public string UserId { get; set; }
public virtual ApplicationUser User { get; set; }
[Key]
public int CreationLikeId { get; set; }
public virtual Creation ParentCreation { get; set; }
}
public class HairTag
{
[Key]
public int HairTagId { get; set; }
[Required]
public string HairTagTitle { get; set; }
[Required]
public string HairTagType { get; set; }
[Required]
public int HairTagOrder { get; set; }
}
***//CHECKBOXES
public class HairTagModel
{
[Key]
public int Value { get; set; }
public string Text { get; set; }
public bool IsChecked { get; set; }
}
public class HairTagList
{
private ApplicationDbContext creationdb = new ApplicationDbContext();
public HairTagList()
{
var HairTagList = creationdb.HairTags.ToList();
List<HairTagModel> obj = new List<HairTagModel>();
foreach (var tags in HairTagList)
{
obj.Add(new HairTagModel
{
Text = tags.HairTagTitle,
Value = tags.HairTagId,
IsChecked = false
});
}
this.CreationHairTags = obj;
}
public List<HairTagModel> CreationHairTags { get; set; }
//public List<HairTagModel> ListHairTags { get; set; }
}
public class CreationHairTagsModel
{
public Creation Creation { get; set; }
public List<HairTagModel> CreationHairTags { get; set; }
}
}***
My controller CreationController.cs
// GET: /Creation/CreationUpload
[Authorize]
public ActionResult CreationUpload()
{
CreationHairTagsModel creation = new CreationHairTagsModel();
return View(creation);
//return View();
}
// POST: /Creation/CreationUpload
// Afin de déjouer les attaques par sur-validation, activez les propriétés spécifiques que vous voulez lier. Pour
// plus de détails, voir http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public ActionResult CreationUpload([Bind(Include = "CreationId,CreationSex,CreationTitle,CreationPhotoBis,CreationHairTags")] CreationHairTagsModel creation, IEnumerable<HttpPostedFileBase> files)
{
if (ModelState.IsValid)
{
// update each field manually
foreach (var file in files)
{
if (file != null)
{
if (file.ContentLength > 0)
{
....CODE UPLOAD HIDDEN....
//Avoid Script
var CreationTitletocheck = Regex.Replace(creation.Creation.CreationTitle, #"<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>", string.Empty);
CreationTitletocheck = Regex.Replace(CreationTitletocheck, #"(?></?\w+)(?>(?:[^>'""]+|'[^']*'|""[^""]*"")*)>", string.Empty);
creation.Creation.CreationTitle = CreationTitletocheck;
//Tags
StringBuilder sb = new StringBuilder();
foreach (var item in creation.CreationHairTags)
{
if (item.IsChecked)
{
sb.Append(item.Text + ",");
}
}
creation.Creation.Creationtag = sb.ToString();
creation.Creation.UserId = User.Identity.GetUserId();
db.Creations.Add(creation.Creation);
db.SaveChanges();
}
}
}
}
//UserId
return RedirectToAction("CreationList", "Creation", new { UserId = User.Identity.GetUserId() });
}
return View(creation);
}
My page of upload CreationUpload.cshtml
#model HairCollection3.Models.CreationHairTagsModel
#using Microsoft.AspNet.Identity
#{
ViewBag.Title = ViewRes.NamesCreation.CreationUploadTitle;
}
<div class="col-sm-12 col-md-12 chpagetop">
<h1>#ViewRes.Shared.PublishAPhoto</h1>
<hr />
#using (Html.BeginForm("CreationUpload", "Creation", FormMethod.Post, new { id = "CreationUpload", enctype = "multipart/form-data", onsubmit = "$('#creationloading').show(); $('#creationform').hide();" }))
{
#Html.AntiForgeryToken()
<div class="col-md-12" id="creationloading" style="display:none">
<div id="progress">
<p>#ViewRes.Shared.UploadPhotoProgress<strong>0%</strong></p>
<progress value="5" min="0" max="100"><span></span></progress>
</div>
</div>
<div class="col-md-12" id="creationform">
<div class="col-md-12">
#Html.ValidationMessageFor(m => m.Creation.CreationSex)
#Html.RadioButtonFor(m => m.Creation.CreationSex, "F", new { #checked = true }) #ViewRes.Shared.WomanHairstyle #Html.RadioButtonFor(m => m.Creation.CreationSex, "M") #ViewRes.Shared.ManHairstyle
</div>
<div class="col-md-12">
#Html.ValidationMessageFor(m => m.Creation.CreationTitle)
#Html.TextBoxFor(m => m.Creation.CreationTitle, new { #class = "inputplaceholderviolet wid100x100", placeholder = HttpUtility.HtmlDecode(Html.DisplayNameFor(m => m.Creation.CreationTitle).ToHtmlString()), onfocus = "this.placeholder = ''", onblur = "this.placeholder = '" + HttpUtility.HtmlDecode(Html.DisplayNameFor(m => m.Creation.CreationTitle).ToHtmlString()) + "'" })
</div>
<div class="col-md-12">
#for (int i = 0; i < Model.CreationHairTags.Count; i++)
{
#Html.CheckBoxFor(m => Model.CreationHairTags[i].IsChecked)
#Model.CreationHairTags[i].Text
#Html.HiddenFor(m => Model.CreationHairTags[i].Value)
#Html.HiddenFor(m => Model.CreationHairTags[i].Text)<br />
}
</div>
<div class="col-md-12" style="text-align: center">
<p style="display: inline-block">
<input type="file" accept="image/*" onchange="loadFile(event)" name="files" id="file1" translate="yes" data-val="true" data-val-required="A File is required." class="wid100x100" /><label for="file1"></label>
<img id="output" style="max-width:200px;"/>
</p>
</div>
<div class="col-sm-12 col-md-12 chpagetopdiv">
<button type="submit" title="#ViewRes.Shared.Publish"><span class="glyphicon glyphicon-share-alt"></span> #ViewRes.Shared.Publish</button>
</div>
</div>
}
</div>
What is wrong in my code please help and explain ?
Important: In C#, every collection must be initialized before being accessed
The error occurs when you are trying to access from the View to the collection CreationHairTags, which is not initialized. Replace your model to initialize collection in the class constructor:
public class CreationHairTagsModel
{
public Creation Creation { get; set; }
public List<HairTagModel> CreationHairTags { get; set; }
public CreationHairTagsModel()
{
CreationHairTags = new List<HairTagModel>();
}
}
My problem is that my ViewModel property doesn't bind into an action parameter.
I think it'll be more clear if i just give you my code.
I have a model as follows:
namespace Sima3.Models
{
using System;
using System.Collections.Generic;
public partial class Usuario
{
public string Login { get; set; }
public string NombreCompleto { get; set; }
public short Organigrama { get; set; }
public int Interno { get; set; }
public string EMail { get; set; }
}
}
And i added DataAnnotations to this partial class in another file (Because this model was generated automatically by EntityFramework), note the remote validation on Login property:
namespace Sima3.Models
{
[MetadataType(typeof(UsuarioMetaData))]
public partial class Usuario
{
}
public class UsuarioMetaData
{
[Display(Name = "Nombre de Usuario")]
[Remote("NoExisteUsuario", "Validation")]
[Required]
public string Login { get; set; }
[Display(Name = "Nombre y Apellido")]
[Required]
public string NombreCompleto { get; set; }
[Display(Name = "Sector")]
[Required]
public short Organigrama { get; set; }
[Required]
public int Interno { get; set; }
[EmailAddress]
[Required]
public string EMail { get; set; }
}
}
Now, i have a ViewModel wich contains a property of type Usuario and some other stuff needed to render my View:
namespace Sima3.ViewModels.PedidoViewModels
{
public class AgregarViewModel
{
public Usuario Usuario { get; set; }
public Pedido Pedido { get; set; }
public SelectList ListaSectores { get; set; }
public SelectList ListaEstados { get; set; }
public SelectList ListaPrioridades { get; set; }
public SelectList ListaTipos { get; set; }
public SelectList ListaDirecciones { get; set; }
}
}
And my view looks as follows (I'll only post part of it, if u need to see more let me know):
#using (Ajax.BeginForm("Crear", "Usuario", null,
new AjaxOptions
{
OnSuccess = "UsuarioCreadoSuccess",
HttpMethod = "Post"
}
, new { #class = "form-horizontal", id = "FormUsuario" }))
{
#Html.AntiForgeryToken()
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title title">Nuevo Usuario</h4>
</div>
<div class="modal-body">
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Usuario.Login, new { #class = "col-lg-4 control-label" })
<div class="col-lg-7">
#Html.TextBoxFor(model => model.Usuario.Login, new { #class = "form-control"})
#Html.ValidationMessageFor(model => model.Usuario.Login)
</div>
</div>
Alright, the important part is the TextBoxFor, it renders me the next HTML:
<input class="form-control valid" data-val="true" data-val-remote="'Nombre de Usuario' is invalid." data-val-remote-additionalfields="*.Login" data-val-remote-url="/Validation/NoExisteUsuario" data-val-required="El campo Nombre de Usuario es obligatorio." id="Usuario_Login" name="Usuario.Login" type="text" value="">
As you see, the textbox name is: name="Usuario.Login"
And my controller action wich gets called by the Remote validation looks like this:
public JsonResult NoExisteUsuario([Bind(Prefix="Usuario")]string Login)
{
Usuario usuario = db.Usuarios.Find(Login);
if (usuario != null)
{
var MensajeDeError = string.Format("El usuario {0} ya existe", Login);
return Json(MensajeDeError, JsonRequestBehavior.AllowGet);
}
else
{
return Json(true, JsonRequestBehavior.AllowGet);
}
}
I set a breakpoint in this Action and it gets hit, but Login comes in null.
I checked with google chrome's debugger the http request header and it shows the form is getting submitted like this: Usuario.Login: asdasdasd.
The question is simple, how can i make it bind?
By the way, i'm using MVC5.
Thanks.
Well, i finally got it working, it seems i was setting the Prefix binding attribute wrongly.
Now my action looks like this:
public JsonResult NoExisteUsuario([Bind(Prefix="Usuario.Login")]string login)
{
Usuario usuario = db.Usuarios.Find(login);
if (usuario != null)
{
var MensajeDeError = string.Format("El usuario {0} ya existe", login);
return Json(MensajeDeError, JsonRequestBehavior.AllowGet);
}
else
{
return Json(true, JsonRequestBehavior.AllowGet);
}
}
If you have the following type.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public List<TheParameters> Parameters { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
}
public class TheParameters
{
public string Parameter { get; set; }
}
You make your page stronglytyped to Person.
"System.Web.Mvc.ViewPage<Person>"
<form action="/Home/Save" method="post">
<b>Your Name</b>
<label for="FirstName">
<span>First Name</span>
<%=Html.TextBox("Person.FirstName", ViewData.Model.FirstName) %>
</label>
<label for="LastName">
<span>Last Name</span>
<%=Html.TextBox("Person.LastName", ViewData.Model.LastName)%>
</label>
<b>Your Address</b>
<label for="Street">
<span>Street</span>
<%=Html.TextBox("Person.Address.Street", ViewData.Model.Address.Street)%>
</label>
<label for="City">
<span>City</span>
<%=Html.TextBox("Person.Address.City", ViewData.Model.Address.City)%>
</label>
<label for="State">
<span>State</span>
<%=Html.TextBox("Person.Address.State", ViewData.Model.Address.State)%>
</label>
<label for="Parameters">
<span>Parameters</span>
<%
int index = 0;
foreach (TheParameters parameter in ViewData.Model.Parameters)
{
Response.Write(Html.TextBox("Person.Parameters.Parameter[" + index + "]", parameter.Parameter));
index++;
}
%>
</label>
<input id="submit" type="submit" value="submit" />
</form>
In the controller the following:
public ActionResult Index()
{
Person p = new Person();
p.FirstName = "Name";
p.LastName = "Last";
p.Address = new Address();
p.Address.City = "city";
p.Address.State = "state";
p.Address.Street = "street";
p.Parameters = new List<TheParameters>();
p.Parameters.Add(new TheParameters(){ Parameter = "P1" });
p.Parameters.Add(new TheParameters(){ Parameter = "p2" });
ViewData.Model = p;
return View();
}
public ActionResult Save(FormCollection form)
{
Person p = new Person();
UpdateModel(p, "Person", form.ToValueProvider());
return RedirectToAction("Index");
}
I call the UpdateModel. All properties are filled in properly except for the Person.Parameters. This is always null after the updateModel.
Is there a solution for this or a workaround?
regards,
Steve
In your view:
"Person.Parameters.Parameter[" + index + "]"
should be
"Person.Parameters[" + index + "].Parameter"