Problem Background
To save myself from duplicating validation logic I am following a pattern of pushing Server side ModelState
errors to my View Model (MVVM KnockoutJS).
So by convention my Property Names on my KO
ViewModel Match the Properties my Api is exposing and expecting, therefore I can map one to the other easily using a little Knockout plugin I wrote.
<validation-summary params="vm: $data, class: 'alert alert-error'"></validation-summary>
...
<div class="control-group" data-bind="errorCss: {'error': spend }">
<label class="control-label" for="spend">Spend</label>
<div class="controls">
<div class="input-prepend">
<span class="add-on">$</span>
<input type="text" data-bind="value: spend" id="spend" class="input-medium" placeholder="Spend USD" />
</div>
<validation-message params="bind: spend, class: 'text-error'"></validation-message>
</div>
</div>
The Problem
Problem for me is that when JSON.Net serialises the JSON I send via and AJAX and when it encounters an exception it adds this to the ModelState
as and Exception
on the ModelError
Class.
Example Response:
{
"message": "The request is invalid.",
"modelState": {
"cmd.spend": [
"Error converting value \"ii\" to type 'System.Double'. Path 'spend', line 1, position 13.",
"'Spend' must be greater than '0'."
],
"cmd.Title": [
"'Title' should not be empty."
]
}
}
The Problem Being that this message doesn't exactly give a great UX:
Error converting value "ii" to type 'System.Double'. Path 'spend', line 1, position 13.
And the fact that I am unable to separate this exception message from my validation messages as they are all in one Array.
I would prefer to remove this and handle this matter in my ValidationClass
I can remove them manually like so, and this is in a ActionFilter so I only have this once.
public class ValidateCommandAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
ModelStateDictionary modelState = actionContext.ModelState;
#if !DEBUG
for (int i = 0; i < modelState.Values.Count; i++)
{
ModelErrorCollection errors = modelState.ElementAt(i).Value.Errors;
for (int i2 = 0; i2 < errors.Count; i2++)
{
ModelError error = errors.ElementAt(i2);
if (error.Exception != null)
{
// TODO: Add Log4Net Here
errors.RemoveAt(i2);
}
}
}
#endif
if (!modelState.IsValid)
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
}
}
I know JSON.Net is highly configurable and wanted to know if there is somewhere in the API for it where I can turn this off, or suppress it?
You can set an error handler. For example (from the json.net docs),
List<string> errors = new List<string>();
List<DateTime> c = JsonConvert.DeserializeObject<List<DateTime>>(@"[
'2009-09-09T00:00:00Z',
'I am not a date and will error!',
[
1
],
'1977-02-20T00:00:00Z',
null,
'2000-12-01T00:00:00Z'
]",
new JsonSerializerSettings
{
Error = delegate(object sender, ErrorEventArgs args)
{
errors.Add(args.ErrorContext.Error.Message);
args.ErrorContext.Handled = true;
},
Converters = { new IsoDateTimeConverter() }
});
// 2009-09-09T00:00:00Z
// 1977-02-20T00:00:00Z
// 2000-12-01T00:00:00Z
// The string was not recognized as a valid DateTime. There is a unknown word starting at index 0.
// Unexpected token parsing date. Expected String, got StartArray.
// Cannot convert null value to System.DateTime.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With