Changing text if a form has an error - asp.net-mvc

I currently have a summary message at the top of my form, inviting my user to login. If the form does not validate on submit, I wish for this to then be replaced with the relevant error.
The only way I can think of is by hiding the initial text (perhaps in a #Html.Label) and then showing a #Html.ValidationSummary. However, I feel there is most likely a far more efficient way of doing this.
Can anybody help?

I would have an #Html.Label helper, and use the ViewBag object to pass data to it. That way in your controller when you test for ModelState.IsValid, if that is false you can set the ViewBag property so that it passes to the label helper.
Make sense? That's how I'd do it.

turn on the validation summary
#Html.ValidationSummary(true)
in your post ActionResult check the ModelState
[HttpPost]
public ActionResult Foo( Bar _bar){
if(ModelState.IsValid){
//noral course of action
return RedirectToAction("Foo"); //Redirect to the GET method
}
ModelState.AddModelError("", "|Your Message Here");
return View(_bar);
}

No, there is no problem with the approach.
I generally use single div with jquery for the stuff like form validation etc.
I create a single div on page where any kind of message can be displayed for user guideance.
ex:
if I've display some kind of information to user, it will be displayed as following:
div id='divMessage'</div>
$('#divMessage').html('Please fill the following form.').removeClass().addClass('msg');
While in case of some error same div will be used to display the error message:
$('#divMessage').html('some error occurred.').removeClass().addClass('errmsg');
I hope till will be of any use.

Related

Mvc flash message as a partial view

I'm using a FlashHelper to show flash message to users and I need to show partial view istead of default flash message. How can I do that or is that possible or not?.
I need a helper like that:
Flash.Success("_FlashMessagePartial",model)
Or Is there any library you suggest ?
You can't use it like this. If I have understand correct you want to show something like notifications to the users and you don't want your page to be refreshed. The correct answer is that you can do it but it is not correct. Your code will look as a mess you will have a hidden field for the notification and so on. It depends of what you what you want to accomplish. For example:
I am using in my layout a global notification and my snipped looks like this
On the top of the layout just before the
I place an if statement that checks whether error message exists in the TempData
#if(TempData["error"])
{
// here you can visualize it well styled by some template for example
<div class="notification-error">#TempData[error]</div>
}
#if(TempData["success"])
{
// here you can visualize it well styled by some template for example
<div class="notification-error">#TempData[error]</div>
}
Then in your controller if you have something to say to the user you can
just do what you are doing like:
public ActionResult SomeAction(MyModel model)
{
if(something is not valid)
{
this.TempData["error"] user error
return this.View(model);
}
}
That case was if you need some server validation and proper message to the
user. After that option you have to set a script on your layout that removes
the error and success notifications if they exist on the page loads.
The other option if you need some modelstate validation on the client side you can take a look for js-unobtrusive validation that is driven by the viewmodel's attributes and it makes you automatic check on client side before it goes to the server.
The third option is if you need some other notification you can use a JS library called toastr. Examples library url It is light and very easy to use
Hope that this answer is explaining exactly what you need.

MVC3 Validation on Sub-Form

I have a page that I want to have a list of items (header items) with some details and a link to view and a link to edit them. In addition at the top of the list I want to have a form to get the basic details (start and end date) and create a new header item using that data.
What I've done:
created a header controller
created an index view (gets list of items)
created a startHeader view (has a form with start, end date and a button, form has an actionName of "addHeader")
added the "ValidationMessageFor" for the start and end date
added the startHeader view as a partial view to the index view
Everything generally appears to be working except for some validation. The required field validation appears to be working as expected (i.e. if you don't put in a start date and click the button it says "Start Date is required").
However I've added some additional validation that doesn't appear to be working:
added IValidatableObject interface to the header class
added validation code
if (this.StartDate > this.EndDate)
{
yield return new ValidationResult("Start Date must be prior to End Date.", new[] { "StartDate" });
}
when the button is pressed this code runs as expected
however it doesn't stay on the index screen and display the validation message
rather it goes through to the addHeader view
i had expected this to work the same as the required field validation and display the validation message
Is there something I'm missing here?
why is this validation running, but not displaying the error message?
do i need to add something to get this validation to run and remain on the page?
is there a better method of doing something like this?
It could be that your required field validation is displaying via Unobtrusive Client Validation (your model might include the data annotation [Required]). This validation runs on the client-side via JavaScript, and so doesn't post back to the server at all.
The validation code you have written, contrastingly, runs after the form has posted-back to the server. You will need to trap this in you addHeader() method. Something along these lines:
[HttpPost]
public ActionResult addHeader(addHeader model)
{
if (!ModelState.IsValid)
{
return View();
}
else
{
//Do Work to add your header...
return View("Index");
}
}
As long as you have #Html.ValidationSummary(true) in your view, then it will display the ValidationResult automatically. See this for more details.

How do i submit the complete viewmodel to an other view?

I'm using MVC3 (razor) and i'm trying to get the following working.
I have a list of snippets. These snippets have some general settings and then have a translation for an unknown ammount of languages.
Now i'm trying to do the following:
On the 'Create' page (url: Screen) of a snippet i set the general settings. under that there is a list of filled translations (empty at the start). When you press the 'Opslaan' button, i want the form to save the general settings and the list of translations.
When i push the 'Add' button i want to submit the complete viewmodel (settings + list of translations) to an other page where i can fill in a translation. After i filled in a translations, i want to return to this page (url: Screen). Here, a translation is filled in the list.
Now i'm doing someting wrong, because i cant get the viewmodel to submit to the 2nd page.
this is my code:
button 'add translation':
#Html.ActionLink("Add", "CreateTranslation", new { oSnippeteditviewmodel = this.Model }, null)
SnippetController:
public ActionResult Create()
{
SnippetEditViewModel oItem = new SnippetEditViewModel();
oItem.lSnippetsPerLanguage = new List<SnippetPerLanguageEditViewModel>();
return View(oItem);
}
[HttpPost]
public ActionResult Create(SnippetEditViewModel Snippeteditviewmodel)
{
if (ModelState.IsValid)
{
Snippeteditviewmodel.Bookmark = Snippeteditviewmodel.Bookmark.Replace(' ', '_');
_repoSnippet.CreateSnippet(Snippeteditviewmodel);
return RedirectToAction("Index");
}
return View(Snippeteditviewmodel);
}
public ActionResult CreateTranslation(SnippetEditViewModel oSnippeteditviewmodel)
{
return View(oSnippeteditviewmodel);
}
And in the controller, action CreateTranslation the object 'oSnippeteditviewmodel' stays null.
annyone who has a simular problem? Or a solution?
First, you should try to generate action link like this
#Html.ActionLink("Add", "CreateTranslation", this.Model, null)
In this case mvc will try to pass correctly serialized model values for your link and if your model is simple enough, CreateTranslations will get its model correctly. But, I would not do it that way. Generated link is static. What if user changes Snippet values on client side? When it comes to adding Translation, all the changed form values will be lost (Link will pass initial, server generated values). So, you should try one of the followings
Create the form with two buttons, one for CratingTranslation and one for Saving. When creating translation, dynamically change form's action and method parameters to GET the CreateTranslation action. This way, form will serialize all its current Snippet settings and pass to desired action, and you get the current snippet model passed to CreateTranslation action.
Use ajax. Just dynamically inject translation creation input fields into same page. That's simple and more user friendly (no bundle of navigations), and more http traffic is reserved (Passing all the translations and snippet to second page, and then returning all of these + 1 translation could get you in trouble). I would reccomend this approach. This is far more simple than first or your approaches.
I am not getting you properly but if you wanna add data by "create" controller then you don't need to specify object in "oSnippeteditviewmodel". You can get all form data by
Request.Form["controlName"]
and fill the Snippeteditviewmodel data member by above and save that.

ASP.NET MVC 3 POST ModelState and ViewModel

In my ASP.NET MVC 3 app I have a page where, after its form is submitted I need to change a value from the form. If I do it in the ViewModel it has no effect, I have to do it use ModelState["Field"].Value.
The thing is that I actually have a lot of work I have to do on the ViewModel when the pages loads AND after the POST. So I have a method which receives the ViewModel and do all that work. But, as I said, after the POST, modifying the ViewModel object is useless. Why is that? The method on the controller is returning View(viewModel);. Shouldn't the view use the ViewModel values?
I'd like to understand why is useless to modify the ViewModel and also know if there is some method in the ModelState which "refresh" the fields values throw a ViewModel object.
Here is my controllers code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Index(MyViewModel viewModel)
{
try
{
if (ModelState.IsValid)
//Do stuff and redirect
}
catch(Exception ex)
{
//Log and add error to the ModelState
}
someMethodWhichDoesALotOfThingsInTheViewModel(viewModel);
return View(viewModel);
}
I think the rest of the code is unnecessary, if anyone think it would help let me know!
Update
I don't want to lose any errors, not even those of the fields changed in the ViewModel. A good example would be a captcha, if the users makes any error in the form (only with the captcha field or only with any other fields and not with the captcha) I want to show him all his errors and also update the captcha. It makes no sense to render the form with the old captcha value inserted so I want to blank that field.
Update 2
I've opted to put #Value = Model.PropertyInViewModel in the HTML Attributes of each Html.TextBoxFor. But I'd prefer to avoid that nasty work so if someone comes out with any better solution please let me know.
The following will work:
ModelState.Remove("MyProperty");
viewModel.MyProperty = "new value";
You need to remove it from the model state because HTML helpers first look in there when binding their value.
All I could came out with is to add #Value = Model.PropertyInViewModel to each Html.TextBoxFor that is going to be modified in the ViewModel.
Another way, as #Darin Dimitrov said, would be to make my own helpers.
If you decide to remove modelstate values to prevent round-tripping take a look at this RemoveFor() extension method I made to remove ModelState errors without magic strings.

ASP.NET MVC Unbind Action Parameter

Is it possible to disable a certain action parameter from retaining its value across requests?
[HttpPost]
public ActionResult MyAction(string value1, string value2)
{
if(value1=="hi")
ModelState.AddModelError("value1", "Can't have hi");
//do stuff
if(ModelState.IsValid)
return RedirectToAction("Finish");
else
return View()
}
[HttpGet]
public ActionResult MyAction()
{
return View()
}
The view consists of a simple form with two input boxes (value1 and value2). Once submitted and validation fails, the view is returned. I want to always have the value of the textbox in the view to be empty.
The value for the textbox "value1" is retained if the the model is invalidated.
I tried to declare the textbox as <%= Html.TextBox("value1", null) %> but the value is still retained. I also tried to use [Bind(Exclude="value1")] but that dosen't work on a single variable.
Update 2:
I'm doing this for a textbox that is used for Captcha (custom solution) input. I want the textbox to be cleared any time the page is loaded, but I want validation to remain.
Try calling
ModelState["value1"].Value
= new ValueProviderResult(null, string.Empty, CultureInfo.InvariantCulture);
before you return the view from within your controller action.
What this does is keep all the errors associated with the key "value1", but replaces the value with an empty value.
What are you doing that's causing it to be retained? There isn't anything like ViewState in MVC that will persist a value over multiple requests unless you're writing code or using form fields to make it do so.
What does the view look like? Is this action method being called via GET or POST? What's the "do stuff" contained in your method?
Edit: You're still showing //do stuff in your example code. Does that stuff contain any references to ViewData? Your question is about binding, but I don't see any binding happening. Maybe this is beyond my understanding.
Edit 2: Glad Phil saw this one! The original question didn't mention the ModelState.

Resources