I am trying to "re-run" validation of ModelState after I change model within my controller. Is this possible to do? Here is code example that explains it:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ContactUs(ContactUsModel model)
{
model.Email = "defaultemail#world.com";
// Email is required field and even though it's
// now valid ModelState.IsValid is false
// how to re-run validation?
if (ModelState.IsValid)
{
// want to get here
}
}
Clear ModelState and call TryValidateModel
In Your Case
public ActionResult ContactUs(ContactUsModel model)
{
model.Email = "defaultemail#world.com";
ModelState.Clear();
TryValidateModel(model);
if (ModelState.IsValid)
{
//Do something
You can call TryUpdateModel
public ActionResult ContactUs(ContactUsModel model)
{
model.Email = "defaultemail#world.com";
if (TryUpdateModel(model))
{
.... // model has been updated
Refer documentation.
Related
I have the following Get action:
[HttpGet]
[AllowAnonymous, OnlyAnonymous]
public ActionResult VerifyVoucherCode()
{
var model = new VerifyVoucherCodeModel();
model.VoucherCode = Request.GetFirstQueryValue("token", "voucherCode");
if (!string.IsNullOrEmpty(model.VoucherCode))
{
// prepopulates the code for the user already in a form
}
return View(model);
}
And a POST action for when the user submits the form:
[HttpPost, AjaxOnly]
[AllowAnonymous, OnlyAnonymous]
[ValidateAntiForgeryToken]
public ActionResult VerifyVoucherCode(VerifyVoucherCode model)
{
return ExecuteAction(() =>
{
// do something
});
}
I want to change the logic so that if the voucher code is in the request, the form is submitted automatically for the user without them having to submit the form themselves (i.e. it takes them straight to that Post action). I've looked at lots of Stack Overflow questions and answers and it seems I cannot redirect to the Post action. I have also tried creating a second Get action which calls the Post action but that does not work either. Does anyone know the correct way to approach this problem?
Thanks
Assuming the model contains a single string for the voucher, you can do something like this:
[HttpGet]
[AllowAnonymous, OnlyAnonymous]
public ActionResult VerifyVoucherCode(string id)
{
if(string.IsNullOrEmpty(id))
{
MyModel model1 = new MyModel();
...
return View(model1);
}
//otherwise process the voucher here
...
return RedirectToAction("SuccessMsg");
}
Razor code like:
#Html.TextBoxFor(Model => Model.Name, new { #Value = student.t_Name })
and I using .NET MVC's model validation in Controller,
if (ModelState.IsValid)
{
return RedirectToAction("B");
}
else
{
return View(); // when validation failed
}
My situation is I have a edit function, for example:
original data:
birthday: 1992-05-26
after edited:
birthday: 1992-05-32
after I submit this to Controller and make model validation, it will validate fail, and return to previous view(the view before form submit),
I want it shows
birthday:1992-05-32
instead of
birthday:1992-05-26
You should set ViewModel values that come to your controller like this:
public ActionResult YourControllerMethod(YourViewModel model)
{
if (ModelState.IsValid)
{
return RedirectToAction("B");
}
else
{
ViewData.Model = model; //where model is your controller model
return View(); // when validation failed
}
}
You would need to pass the current posted model instance back to view when returning back View something like:
public ActionResult YourAction(SomeModel model)
{
if (ModelState.IsValid)
{
return RedirectToAction("B");
}
else
{
return View(model);
}
}
I have two problems;
First, I can not go to the main page URL. It is not working as it is on the login page:
public ActionResult Index()
{
return View();
}
public ActionResult Login(string email, string password)
{
model = BLcontext.GetUserLogin(email, password);
if (model.UserID > 0)
{
return Redirect("/Home/Index");
or return PartialView("Index");
or return RedirectToAction("Index");
}
return PartialView("Login");
}
Second, how can I get userId value?
clientAuth "c495600a-71b3-44cb-a577-634426597c82,{\"UserID\":2,\"CurrentSessionID\":\"00000000-0000-0000-0000-000000000000\"},16.01.2015 15:50:53"
I did it
clientAuth.Split(',')[1]
but I see it.. I want value 2
return :"{\"UserID\":2"
I'm not entirely sure what or where your problem is based on what you've submitted. However, it should be as easy as this:
Home Controller: (Default Defined in your Routes)
public ActionResult Index()
{
return View();
}
By default that is a Get, which will automatically be returned when you call the raw controller.
On your other page, when you have an Event that occurs from a user interaction, you simply declare the method and direct to proper action like:
[HttpPost]
public ActionResult ValidateCustomer(int? id)
{
if(id != null)
return View("/SomeOtherController/Example");
return View("/Home/Index");
}
That would take the <form action="/Home/ValidateCustomer" method="POST"> and automatically force the submit input to pass your parameter in your fields, then go to the ActionResult ValidateCustomer hopefully this clarifies navigation a bit for you.
Code below:
[HttpGet]
public ActionResult Edit(string id="")
{
// ...
}
[HttpPost]
public ActionResult Edit(string itemId="", EditViewModel viewModel)
{
// ...
RedirectToAction("Edit", new { id = itemId });
}
returns an error: "Optional parameters must appear after all required parameters".
I assume it's trying to redirect to [HttpPost] action.
How to redirect to [HttpGet] action?
I'm trying to implement Save functionality where it will save the edit and reload the form with new values.
Error message is clear...
... if you know that an optional parameter is a parameter with a default value (empty string in your case)
[HttpPost]
public ActionResult Edit(EditViewModel viewModel, string itemId="")
{
// ...
RedirectToAction("Edit", new { id = itemId });
}
and you're done
This is a controller action that I call with ajax post method:
[HttpPost]
public ActionResult Add(Comment comment)
{
if (User.Identity.IsAuthenticated)
{
comment.Username = User.Identity.Name;
comment.Email = Membership.GetUser().Email;
}
if (ModelState.IsValid)
{
this.db.Add(comment);
return PartialView("Comment", comment);
}
else
{
//...
}
}
If the user is logged in, submit form doesn't have Username and Email fields, so they don't get passed by ajax call. When action gets called ModelStat.IsValid returns false, because these two properties are required. After I set valid values to properties, how do I trigger model validation to update ModelState?
You can use a custom model binder to bind the comment's Username and Email properties from User.Identity. Because binding occurs before validation the ModelState will be valid then.
Another option is to implement a custom model validator for the Comment class, that checks the ControllerContext.Controller for a validated user.
By implementing any of these options you can remove the first if check.
You can try calling the built in TryUpdateModel method which returns a boolean so you can check that value.
UPDATE: Try using TryUpdateModel with exceptions. Use a formcollection instead of Comment into the Action.
[HttpPost]
public ActionResult Add(FormCollection collection)
{
string[] excludedProperties = new string[] { "Username". "Email" };
var comment = new Comment();
if (User.Identity.IsAuthenticated)
{
comment.Username = User.Identity.Name;
comment.Email = Membership.GetUser().Email;
}
TryUpdateModel<Comment>(comment, "", null, excludedProperties, collection.ToValueProvider());
if (ModelState.IsValid)
{
this.db.Add(comment);
return PartialView("Comment", comment);
}
else
{
//...
}
}