I am inserting Full Name in table using Entity Framework.
Before inserting I want to check if the record is already inserted.
Here is my View model,model and
Your [Remote]
attribute does not work because your generating an input with
<input type="text" name="InsertUser.FullName" .... >
but posting it to method with has a parameter string FullName
. One way to solve this is to use the [Bind]
attribute to strip the prefix
public JsonResult CheckUserName([Bind(Prefix="InsertUser")]string FullName)
so the value is correctly bound. However a better method is to use a view model with just the properties you need in the view, which from the view you have shown appears to be only FullName
and LastName
, and avoid using the [Bind]
attribute.
Your POST method also includes a call to CheckUserName(vmModel.InsertUser.FullName);
which returns a JsonResult
which makes no sense. Assuming you want to have both the client side remote validation, and a repeat check when you submit then you should refactor your code into 2 methods
private bool IsNameValid(string FullName)
{
return Json(!db.Users.Any(x => x.FullName == FullName), JsonRequestBehavior.AllowGet);
}
public JsonResult CheckUserName(string FullName)
{
return Json(IsNameValid(FullName), JsonRequestBehavior.AllowGet);
}
and then in the POST method
[HttpPost]
public ActionResult Create(VMUsers vmModel)
{
if (!IsNameValid(vmModel.InsertUser.FullName)
{
ModelState.AddModelError("InsertUser.FullName", "Fullname exists");
}
if (!ModelState.IsValid)
{
return View(vmModel);
}
// save and redirect
}
You can add a new error to ModelStateDictionary if the user exist in the db.
Also, Looks like your view is only sending FullName and LastName. In that case, why not keep your view model to have only those properties so that your view specific-view model will not have any tight coupling with your entity models.
public class CreateUserVM
{
[Required]
public string FullName { set;get;}
public string LastName { set;get;}
}
And in your GET action make sure you are sending an object of this
public ActionResult Create()
{
return View(new CreateUserVM());
}
and your view will be strongly typed to our flat view model
@model CreateUserVM
@using(Html.BeginForm())
{
@Html.ValidationSummary(false)
<label>Full Name</label>
@Html.TextBoxFor(s=>s.FullName)
<label>Last Name</label>
@Html.TextBoxFor(s=>s.LastName)
<input type="submit" />
}
and your HttpPost action method will be
public ActionResult Create(CreateUserVM model)
{
if (ModelState.IsValid)
{
var exist= db.Users.Any(x => x.FullName == model.FullName)
if(exist)
{
ModelState.AddModelError(string.Empty, "Username exists");
return View(vmModel);
}
var user = new Users()
{
FullName = model.FullName,
LastName = model.LastName
};
//Inserting in Parent table to get the Id that we will used in Child table.
db.Users.Add(user);
db.SaveChanges();
return ReidrectToAction("Index"); //PRG pattern
}
return View(vmModel);
}