Trouble accessing ModelState Errors in view - c#

So I am having some trouble accessing my model errors within my Razor view.
In my controller, when either the ModelState is not valid or some other custom validation does not pass, I add model errors like this: ModelState.AddModelError("ModelState", "Please fill out all required fields.");
Then I return a redirect like so:
return RedirectToAction("Register", "Account");
Seems fairly simple, however, when I try and access the model state errors, loop through them, and add them each as a separate span to my view, I get nothing at all displayed. Here's the code in the view:
#foreach (var error in ViewData.ModelState.Values.SelectMany(modelState => modelState.Errors))
{
<span>#error.ErrorMessage</span>
<br />
}
Am I doing something wrong here, or not doing something I should be?

You should not redirect to action, just return same view:
///
/// Displays form to edit model
///
public ActionResult Edit(int id)
{
MyModelClass m = new MyModelClass();
return View(m);
}
[HttpPost]
public ActionResult Edit(MyModelClass m)
{
if( !ModelState.IsValid )
{
// Got error, return view
return View(m);
}
return RedirectToAction("/mymodel/success");
}
Updated: ModelState.IsValid - mistyped :)

Related

TextBoxFor default value and keep edited value after validation fail

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);
}
}

DropDownListFor getting null value and appear ArgumentNullException

I attempting to do is passed a viewData from controller to view and display it in drop down list.
I wish to add the selected Id pass into m.movie_type_id.
But I keep on getting ArgumentNullException. Detailed information state that the Value cannot be null.
Below is how I was code and getting error exception.
<%=Html.DropDownListFor(m=> m.movie_type_id,new SelectList((IEnumerable)ViewData["MT"],"Id","Type")) %>
In Controller
public ActionResult AddMovie()
{
ViewData["MT"] = db.MovieType.ToList();
return View();
}
[HttpPost]
public ActionResult AddMovie()
{
return view();
}
Current stage is just for testing purpose. Since the error occur during the data pass back to the controller, I wish to fix it before i proceed.
Where did I done wrong?
Please make sure that viewdata is filled by some collection and passed into your view like
public ActionResult MyAction()
{
ViewData["MT"] =YourIEnumerableCollection() //Code to get the collection
return view(model);
}
EDIT
I think you are getting this in POST scenario, you need to pass the ViewData in POST too like
[HttpPost]
public ActionResult AddMovie()
{
ViewData["SQ"] = db.MovieType.ToList();
return View();
}

Change model property in post request asp.net mvc

I have one problem.
This is short example.
This is model.
public class MyModel
{
string Title{get;set;}
}
In view I write
#Html.TextBoxFor(model => model.Title)
This is controller.
public ActionResult EditNews(int id)
{
var model = new MyModel;
MyModel.Title = "SomeTitle"
return View("News/Edit", model);
}
//for post
[HttpPost]
public ActionResult EditNews(MyModel model)
{
//There is problem.When I do postback and
// change Title in this place,Title doesn't change in view textbox
//Only when I reload page it change.
model.Title = "NEWTITLE"
return View("News/Edit", model);
}
It won't change because by default (many think this is a bug) MVC will ignore the changes you make to the model in a HttpPost when you're returning the same View. Instead, it looks in the ModelState for the value that was originally served to the view.
In order to prevent this, you need to clear the ModelState, which you can do at the top of your HttpPost by doing:
ModelState.Clear();

return view doesn't run controller code mvc

I have a problem with "return view()" that doesn't excute code in my controller.
I have a controller with this code:
public class BrokerController : BaseController
{
public ActionResult BestallMaklarBild()
{
return View(new BestallMaklarBildViewModel());
}
[HttpPost]
public ActionResult BestallMaklarBild(FormCollection collection)
{
try
{
//Some code
return View("MaklarBildBestalld",new MaklarBildBestalldViewModel());
}
catch
{
return View(new BestallMaklarBildViewModel());
}
}
public ActionResult MaklarBildBestalld()
{
//Some code
return View(new MaklarBildBestalldViewModel());
}
}
When I post to my controller "BestallMaklarBild" and then try to return the view("MaklarBildBestalld",new MaklarBildBestalldViewModel()), the code in "MaklarbildBestalld" doesn't execute. So when the model is returned to the view it doesn't contain any data, and cause my view leaving me with an error saying that the model.something = null when I try to output some data to the view.
Don't know what Im doing wrong.
That's normal. You need to redirect to this controller action if you want the code to execute:
try
{
//Some code
return RedirectToAction("MaklarBildBestalld", new { id = "some id" });
}
catch
{
return View(new BestallMaklarBildViewModel());
}
and now the action will execute:
public ActionResult MaklarBildBestalld(string id)
{
//Some code
return View(new MaklarBildBestalldViewModel());
}
Here's the correct workflow:
The BestallMaklarBild POST controller action is invoked and passed a view model
This controller action attempts to persist the model and redirects in case of success to the MaklarBildBestalld controller action passing it an unique identifier as query string of this model so that this action is able to retrieve the model back. In case of failure it simply redisplays the form so that the user can fix the errors he did, or see the error message that there was a problem processing his request.
You must ensure that your view has the model in your parameters as a generic type.

URL stays same when returning different view of same controller

I am trying to return a different view from my controller. However, although the correct view is displayed the URL stays same.
This is my form in /Company/Create view.
#using (Html.BeginForm("Create", "Company", FormMethod.Post))
{
// Form here
}
So basically, the form and model is submitted to /Company/Create action. If the submitted model is valid, then I process the data and redirect to /Company/Index view with
return View("Index");
As I said, correct view is displayed however, URL (address bar) is still http://.../Company/Create
I tried RedirectToAction("Index"); It does not work also. And I do not think its a good MVC practice. I have a single layout and Company views are rendered with RenderBody()
Any ideas ?
Thanks.
Edit :
This is my action method,
[HttpPost]
public ActionResult Create(CompanyCreate model)
{
/* Fill model with countries again */
model.FillCountries();
if (ModelState.IsValid)
{
/* Save it to database */
unitOfWork.CompanyRepository.InsertCompany(model.Company);
unitOfWork.Save();
RedirectToAction("Index");
return View();
}
// If we got this far, something failed, redisplay form
return View(model);
}
You need to redirect to another action if you want the url changed.
However RedirectToAction doesn't redirect instantly but returns aRedirectToRouteResult object which is an ActionResult object.
So you just need to return the result of RedirectToAction from your action:
[HttpPost]
public ActionResult Create(CompanyCreate model)
{
/* Fill model with countries again */
model.FillCountries();
if (ModelState.IsValid)
{
/* Save it to database */
unitOfWork.CompanyRepository.InsertCompany(model.Company);
unitOfWork.Save();
return RedirectToAction("Index");
}
// If we got this far, something failed, redisplay form
return View(model);
}

Categories