Validation / Error Messages in ASP.Net MVC 2 View Unrelated to a Property - asp.net-mvc-2

What pattern can I use to display errors on an MVC 2 view that are not related to a single property?
For example, when I call a web service to process form data, the web service may return an error or throw an exception. I would like to display a user-friendly version of that error, but have no logical means to relate the error to any given property of the model.
UPDATE:
Trying to use this code as suggested, but no summary message is displayed:
MyPage.spark:
Html.ValidationSummary(false, "Oopps it didn't work.");
Controller:
ViewData.ModelState.AddModelError("_FORM", "My custom error message.");
// Also tried this: ViewData.ModelState.AddModelError(string.Empty, "My custom error message.");
return View();
UPDATE 2
What does this mean?
next to each field.
Instead of always displaying all
validation errors, the
Html.ValidationSummary helper method
has a new option to display only
model-level errors. This enables
model-level errors to be displayed in
the validation summary and
field-specific errors to be displayed
next to each field.
Source: http://www.asp.net/learn/whitepapers/what-is-new-in-aspnet-mvc#_TOC3_14
Specifically, how does one add a model level error (as opposed to a field-specific error) to the model?
UPDATE 3:
I noticed this morning that Html.ValidationSummary is not displaying any errors at all, not even property errors. Trying to sort out why.

Simply adding a custom error to the ModelState object in conjunction with the ValidationSummary() extension method should do the trick. I use something like "_FORM" for the key... just so it won't conflict with any fields.
As far as patterns go, I have it setup so that my Business Logic Layer (called via services from the controller) will throw a custom exception if anything expected goes wrong that I want to display on the view. This custom exception contains a Dictionary<string, string> property that has any errors that I should add to ModelState.
HTHs,
Charles

Related

TYPO3 How can I get all validation errors before being output to view

In TYPO3 own extension validation of form inputs is done before control is handed over to the controller action. How can I get to work on the validation errors before being handed over to view?
Usually there should be no reason to do this. However, what you could do is to override the errorAction() method (which is inherited from AbstractActionController) in your controller. There, you can get the validationResults like this:
$validationResults = $this->arguments->getValidationResults()
Then you can fiddle with them before they are bound to the current request object:
$originalRequest = clone $this->request;
$this->request->setOriginalRequest($originalRequest);
$this->request->setOriginalRequestMappingResults($validationResults);

material-input with validation and error message in AngularDart

I would like to use validation and error message with material-input in AngularDart.
We have a default message error (Enter a number) in this component, as we can see in the figure below:
I need to validate if a percentual field input is between 0 and 100%, for example. If not, a message error should be displayed.
What is the way to work with input validation and error messages in AngularDart with Material Components?
The components have a couple of validators already written which can help you here.
<material-input type=[percent] [lower]="0" [upper]="100"></material-input>
These validators are coming from here. The error messages are set to percent friendly here. If you wanted to override your own messages you can do that too here is the code. Sorry in advance for any errors whiteboard coding:
import 'package:angular_components/forms/error_renderer.dart';
#Component(
selector: 'my-form'
template: '<material-input type="percent" percentErrorRenderer="myErrors">')
class MyForm {
ErrorFn myErrors = replaceErrors(
{'lower-bound-number': 'Bigger number please',
'upper-bound-number': 'Smaller number please'});
}
The error renderer pattern allows you to use the common validators but change the messages to whatever you want. You can also use errorRenderer for regular inputs, but percent needs it's own attribute since it is directly using input.
If your validation needs to be more complicated than the defaults that are included I suggest you use the validators linked above as an example of creating one.

Get object from form with errors in play framework 2.0

I am getting an error when I try to extract a user from a form with validation errors.
I have the following route configured in my routes file:
GET /users/:user controllers.UsersController.viewUser(user: models.User)
GET /users/:user/edit controllers.UsersController.editUser(user: models.User)
This is fine at this point, and I can render a link to the user view from my scala templates:
routes.UsersController.viewUser(myUserObject)
My problem is that in my user edition form I need to get myUserObject from a Form[User] object. What I am currently doing is:
routes.UsersController.viewUser(userForm.get)
However, when the userForm has any errors, the get method raises an exception, as shown in the documentation.
The approach I have taken is passing an additional User parameter to the scala view, together with the Form[User] parameter I was passing up to now, I mean,
userEdit.render(user, userForm)
instead of just
userEdit.render(userForm)
However, I would like to know if there is a more suitable solution that does not involve including an additional parameter.
The documentation states that you can prefill a form with existing data:
val filledForm = userForm.fill(User("Bob", 18))
Given the preexisting User, it should be trivial to adapt to your example.

MVC 2 partial for edit/create return error

I got a question about MVC 2 and returning views for partials:
I got two views for creating and editing a user, the views both uses a partial so i can reuse the form fields.
UserPartial.ascx, EditUser.aspx, CreateUser.aspx
I got some logic in the controller post method (EditCreateUser) which finds out if its a new or existing user which is beeing submitted and this works fine.
The problem is when I try to return the edited user: return View(user). MVC complains about EditCreateUser file not existing. But thats only the method name, i want to return the object to the EditUser view which I am already on.
I could use RedirectToAction but i rather not because this problem would occur also if i want to return the same object when some errors has occured.
Any ideas on how to do this or some pointers in the right direction would be awesome.
Thanks
Within an action method named EditCreateUser, the statement return View(user) will by default look for a view with the same name as the action. You need return View("EditUser", user)

MVC2 sending collections from the view a controller via json

I've been looking on forums for 2 days now and can't find a good answer so I'll just post it.
I appear to be having a problem posting JSON back to the controller to save. The JSON should map to model view but it keeps getting default(constructor)values rather then the values from the POST.
We have a series of JS widgets that contain a data field with json in them. We do all our data manipulation in these widget objects on the client side. When a user wants to save we grab the data we need from the widgets involved and we put it into another JSON object that matches a ViewModel and POST that back to the server.
For example:
$("#Save").click(function () {
if (itemDetails.preparedForSubmit() && itemConnections.preparedForSubmit()) {
itemComposite.data.Details = itemDetails.data;
itemComposite.data.Connections= itemConnections.data;
$.post(MYURL, itemComposite.data);
} else {
alert("failed to save");
}
});
The preparedForSubmit() method simple does stuff like any validation checks or last minute formatting you might need to do client side.
The itemDetails widgets data matches a ViewModel.
The itemConnections widgets data matches a collection of ViewModels.
The Controller looks like this:
[HttpPost]
virtual public JsonResult SaveItemDetailsComposite(ItemComposite inItemData)
{
if (ModelState.IsValid)
{
try
{
_Mapper.Save(itemComposite.Details , itemComposite.Connections);
return Json(true);
}
catch (Exception ex)
{
_log.Error("Exception " + ex.InnerException.Message);
throw;
}
}
return Json(SiteMasterUtilities.CreateValidationErrorResponse(ModelState));
}
The ItemComposite Class is a simple View Model that contains a single itemDetails object and a collection of itemConnections. When it returns data to here it is just getting the default data as if it got a new ItemComposite rather than converting the POST data.
in Firebug I see the data is posted. Although it looks weird not automatically formatted in firebug.
Are you saying that itemComposite.data is formatted as a JSON object? If so, I'm pretty sure you're going to have to de-serialize it before you can cast it to your object. Something like:
ItemComposite ic = jsSerializer.Deserialize<ItemComposite>(this.HttpContext.Request.Params[0]);
You may want to look into a framework like JSON.NET to ensure that your data is being serialized properly when it gets supplied to your Action.
JSON.NET seems like it's one of the main stream frameworks: http://json.codeplex.com/releases/view/43775
Hope this helps.
Cory
You could also use the JSON Serializer in WCF: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx
SO wouldn't let me put both links in one answer, sorry for the split answer.
Thanks everyone. I think I have solved my problem and I'm pretty sure that I had four issues. For the most part I followed thatSteveguys's suggestion and read more on this article: http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx
Using jQuery's post() method and specifying json as the type didn't seem to actually send it as json. By using the ajax() method and specifying json it sent it as json.
The JSON.serialize() method was also need to cleanly send over the json.
Also my ViewModel design was a big problem. We are using the MS code analytic build junk and it didn't want me having a setter for my collections in the ViewModel. So me being from a java/hibernate world, thought it didn't need them to bind and it would just come in as a serialized object magically. Once I just suppressed the error and reset up my setters. I am getting the collections now in my controller.
I believe using the MVC2 Future's Value Providers are doing something but it still doesn't convert json dates robustly, So I am still investigating the best way to do that.
I hope my issues help out others.
UPDATE: using this method to update collections of data appears to be super slow. A collection with 200 entries in it and 8 fields per entry takes 3 minutes to get to the controller. Just 1 or 2 entries take very little time. The only thing I know of that is happening between here is data binding to the model view. I don't know if MVC2 provides a easy way to send this much data and bind it.