I have the following snippet of asp.net mvc controller code that check if state is invalid, then I will update the value of one field:
[HttpPost]
public ActionResult Create(ContactInfo contactinfo)
{
if (IsModelStateValid(GetIssues(contactinfo)))
{
db.ContactInfoes.Add(contactinfo);
db.SaveChanges();
return RedirectToAction("Index");
}
contactinfo.Name+="why this is not working".
return View(contactinfo);
}
Through debugging I checked that the new value of Name field is successfully passed to Model of my View, but in the render result, only the field validation fields are updated, the field value change is not rendered, Could someone help me on how to apply this change?
You got sort of cache problem, clear it with:
[HttpPost]
public ActionResult Create(ContactInfo contactinfo)
{
if (IsModelStateValid(GetIssues(contactinfo)))
{
db.ContactInfoes.Add(contactinfo);
db.SaveChanges();
return RedirectToAction("Index");
}
// Clear the model state.
ModelState.Clear(); // <-----------------------------------------------
// Or just remove the `Name` property:
ModelState.Remove("Name")
contactinfo.Name+="why this is not working".
return View(contactinfo);
}
Related
I am not sure if I am overlooking something obvious.
Once I do a POST, I have the following (Note: What I am trying to do is to default the same view with some null values so the user can create another entry):
[HttpPost]
public ActionResult QkInsert(ProgInfo model)
{
if (ModelState.IsValid)
{
ProgService.InsertQuickEntry(model);
model.Name = null;
model.Address = null;
model.Phone = null;
return view(model);
}
return view(model);
What is strange is that when I look at the value of model in the IsValid()
return view(model)
I do see the null values.
But when it is shown on the view, it is not null. It is basically the same view as when I had entered the data the first time. Any idea? Have I overlooked something?
Also notice how I have done return view(model) twice. Is there any other way of doing this to where I do it only once and not repeat?
That's because HTML helpers are first looking into the ModelState when binding their values and only after that the value in your model. This is by design.
So if you want to change any value of the model inside a POST action you need to remove it from the ModelState first:
[HttpPost]
public ActionResult QkInsert(ProgInfo model)
{
if (ModelState.IsValid)
{
ProgService.InsertQuickEntry(model);
ModelState.Remove("Name");
ModelState.Remove("Address");
ModelState.Remove("Phone");
model.Name = null;
model.Address = null;
model.Phone = null;
return view(model);
}
....
}
Now the view will render the modified values.
If the model is not valid you will return the same model, your second return.
There is no need at all for the first return view(model) as there is no code between it and the second one, so it will call anyway. That is, delete the first return and the logic is identical.
This question already has answers here:
Textbox reverts to old value while Modelstate is valid on postback
(2 answers)
Closed 2 years ago.
Suppose i have a model with a validation
public class LoginModel
{
[Required(ErrorMessage="ID not entered")]
[StringLength(5,ErrorMessage = "Length should be 5")]
public string Id { get; set; }
}
In the view page i have a text box. When the validation fails. The controller returns to the view page with error message.
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(LoginModel lg)
{
if(ModelState.IsValid)
{
return RedirectToAction("Index", "Home");
}
return View();
}
But the text box contains the previous values. How does it retains the value? And is there any way to avoid it?
Thanks
to delete the data just try the link which rattlemouse has posted -
ModelState.Clear()
or you do it manually with
[HttpPost]
public ActionResult Login(LoginModel lg)
{
if(ModelState.IsValid)
{
return RedirectToAction("Index", "Home");
}
else{
lg.Id = string.Empty;
return View(lg);
}
}
Clear ModelState and return view without model.
ModelState.Clear();
return View();
ModelState
Controller.ModelState Property
ModelState is a property of a Controller, and can be accessed from those classes that inherit from System.Web.Mvc.Controller. The ModelState represents a collection of name and value pairs that were submitted to the server during a POST. It also contains a collection of error messages for each value submitted.
I have a simple create action that save a product to DB. after saving the product I have used return View(new Product()); to reset the form fields but the form show the old data(the data before submit the form). Also I use return View(new Product(name="test")); but it does not work too.
what is the problem? the product is saved to DB correctly (it means ModelState.IsValid is true). I don Not want to use RedirectToAction.
[HttpPost]
public ActionResult New(Product product)
{
if (ModelState.IsValid)
{
product.SubmitDate = DateTime.UtcNow;
productRepository.Add(product);
productRepository.Save();
//ViewBag.Message = "product is saved";
return View(new Product());
}
return View(product);
}
I think the recommended practice is to use RedirectToAction() but if you want to try it your way, you could try
ModelState.Clear();
return View(new Product());
If you intend to modify a property which is already in the model state you will need to remove it or the HTML helpers that are bound to this value would always use the value in the model state and not the one that you modified:
ModelState.Remove("SubmitDate");
product.SubmitDate = DateTime.UtcNow;
return View(product);
And if you want to clear all properties it would be better to redirect or clear the entire model state collection: ModelState.Clear();
I'm passing in some values to my controller action and everything is binding up fine. There will be two properties missing from the form POST by design.
I am then setting the missing values but then I want to validate the model and it is still saying false since it looks like the ModelState hasn't caught up with my changes.
[HttpPost, Authorize]
public ActionResult Thread(int id, string groupSlug, Comment comment, string submitButton)
{
comment.UserID = UserService.UID;
comment.IP = Request.UserHostAddress;
UpdateModel(comment); //throws invalidoperationexception
if (ModelState.IsValid) // returns false if i skip last line
{
//save and stuff
//redirect
}
//return view
}
What is the cleanest way to pat the ModelState on the head and tell it that everything will be okay whilst still validating everything else that was bound from the user's POST
If the missing Values are required for your model but will not be provided until after binding you may need to clear the errors caused by those two values from the ModelState.
[HttpPost, Authorize]
public ActionResult Thread(int id, string groupSlug, Comment comment, string submitButton)
{
comment.UserID = UserService.UID;
comment.IP = Request.UserHostAddress;
//add these two lines
ModelState["comment.UserID"].Errors.Clear();
ModelState["comment.IP"].Errors.Clear();
UpdateModel(comment); //throws invalidoperationexception
if (ModelState.IsValid) // returns false if i skip last line
{
//save and stuff
//redirect
}
//return view
}
I'm using the ASP.NET Core 1.0.0 and async binding and for me the solution was to use ModelState.Remove and pass the property name (without object name).
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Submit([Bind("AerodromeID,ObservationTimestamp,RawObservation")] WeatherObservation weatherObservation)
{
weatherObservation.SubmitterID = this.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
weatherObservation.RecordTimestamp = DateTime.Now;
ModelState.Remove("SubmitterID");
if (ModelState.IsValid)
{
_context.Add(weatherObservation);
await _context.SaveChangesAsync();
return RedirectToAction("Index", "Aerodrome");
}
return View(weatherObservation);
}
Before .NET Core you can use Validate(TEntity entity) function of controller. But first you have to clear existing ModelState errors.
Suppose you set a missing required property to entity.
ModelState.Clear();
Validate(entity);
if (!ModelState.IsValid) {}
With Core you can use TryValidateModel instead of ModelState.IsValid
see thiis: https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-5.0
I have a UserController and an Edit.aspx. There is one field that is my primary key so i dont want to allow users to edit this field.
The issue is that if i remove the
<%= Html.TextBox("Email", Model.Email) %>
then when the asp.net-mvc magic calls my Controller code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, tblMailingList user_)
{
try
{
repo.UpdateUser(user_);
return RedirectToAction("Index");
}
catch
{
return View();
the email field of the tblMailingList is null. The issue is that i need this as the lookup in the table to retrieve the current record and obviously if its null i get an exception.
When i put the textbox back for this field, it works fine. It seems crazy that i would have to have a textbox and allow editing to pass this field over to the controller. i tried putting it in a label and it still shows up as null in the controller.
any suggestions?
My first question would be why are you doing the lookup on the Email field and not the Id field?
You can pass parameters in your Form declaration to be passed through to your Controller.
<% using (Html.BeginForm(
"MethodName", "Controller", FormMethod.Post,
new { id = Model.Id, email = Model.Email)) { %>
I'm not sure if I got the method declaration correct so please check.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, string email, tblMailingList user_)
{
try
{
repo.UpdateUser(user_);
return RedirectToAction("Index");
}
catch
{
return View();
I would recommend updating slightly differently as your tblMailingList user will not be valid to be updated in your Repository.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection form)
{
tblMailingList user = repo.GetUser(id); // get the user using the id
// so we can update in the same
// context
UpdateModel(user); // this will automatically update
// your user model with values
// from the form
try
{
repo.UpdateUser(user);
return RedirectToAction("Index");
}
catch
{
return View();
If you just want a field that could passed to controller which needs to be invisible in the form, Html.HiddenField could work for your case.
Do I get wrong?