I wouldn't usually recommend doing this but in some cases it might be needed.
I recently ran into a similar problem and needed to do the same.
Instead of trying to parse the ModelState
in razor
view, i did it in the controller, before returning the view. Here is the extension i used:
(Please Note that this hasnt been extensively tested, but seems to be working - i just wrote it)
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace WebApplication.Common
{
public static class ModelStateExtension
{
public static void RemoveDuplicateErrorMessages(this ModelStateDictionary modelStateDictionary)
{
//Stores the error messages we have seen
var knownValues = new HashSet<string>();
//Create a copy of the modelstatedictionary so we can modify the original.
var modelStateDictionaryCopy = modelStateDictionary.ToDictionary(
element => element.Key,
element => element.Value);
foreach (var modelState in modelStateDictionaryCopy)
{
var modelErrorCollection = modelState.Value.Errors;
for(var i = 0 ; i < modelErrorCollection.Count ; i++)
{
//Check if we have seen the error message before by trying to add it to the HashSet
if (!knownValues.Add(modelErrorCollection[i].ErrorMessage))
{
modelStateDictionary[modelState.Key].Errors.RemoveAt(i);
}
}
}
}
}
}
You simple need to call the extension on your ModelState
before returning the view:
using WebApplication.Common;
if (!ModelState.IsValid)
{
//viewModel code omitted
ModelState.AddModelError("0", "Server Side Validation failed");
ModelState.RemoveDuplicateErrorMessages();
return View(viewModel);
}