title: ASP.net WebApi - Custom Message for malformed post data
body: <p>I have an MVC 4 WebAPI application.  What i want to do is filter out any <code>ModelState</code> errors that happen because of malformed data sent during the put/post.</p>
  
  <p>I have an <code>ActionFilterAttribute</code> that checks if the <code>ModelState</code> is valid.  I want to send the state's <code>ErrorMessage</code>s back to the user.  This part is working fine.</p>
  
  <pre><code>/// &lt;summary&gt;
  /// This filter will validate the models that are used in the webapi
  /// &lt;/summary&gt;
  public class MyValidationFilter :System.Web.Http.Filters.ActionFilterAttribute
  {
      public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
      {
          if (!actionContext.ModelState.IsValid)
          {
              //ErrorResponse is just a simple data structure used to hold response
              ErrorResponse errorResponse = new ErrorResponse();
  
              //loop through each key(field) and see if it has any errors
              foreach (var key in actionContext.ModelState.Keys)
              {
                  var state = actionContext.ModelState[key];
                  if (state.Errors.Any())
                  {
                      string validationMessage = state.Errors.First().ErrorMessage;
                      errorResponse.ErrorMessages.Add(new ErrorMessage(validationMessage));                      
                  }
              }
  
              //this is a custom exception class that i have that sends the response to the user.
              throw new WebAPIException(HttpStatusCode.BadRequest, errorResponse );
  
          }
  
      }
  }
  </code></pre>
  
  <p>Normal validation (Required, StringLength, Regex) all work fine, because I can control those messages.</p>
  
  <pre><code>[Required(ErrorMessage = "ID is required")]
  public string ID { get; set; }
  </code></pre>
  
  <p>However, I can't control the message if someone passes incorrectly formatted XML or JSON data. If that happens, then I might get</p>
  
  <blockquote>
    <p>Unterminated string. Expected delimiter: \". Path '', line 1, position
    9.</p>
  </blockquote>
  
  <p>or</p>
  
  <blockquote>
    <p>Invalid character after parsing property name. Expected ':' but got:
    }. Path '', line 1, position 9.</p>
  </blockquote>
  
  <p>or these ones which shows my namespace.</p>
  
  <blockquote>
    <p>Error converting value \"Medium\" to type
    'MyNameSpace.Tenant.WebAPIs.Library.IndividualRegistrationInfo'. Path
    '', line 1, position 8.</p>
    
    <p>Error in line 1 position 7. Expecting element
    'IndividualRegistrationInfo' from namespace
    'http://schemas.datacontract.org/2004/07/MyNameSpace.Tenant.WebAPIs.Library.IndividualRegistrationInfo'..
    Encountered 'Element'  with name 'asdf', namespace ''</p>
  </blockquote>
  
  <p>I want to somehow send back a generic "Invalid data" message when this happens. Is there another filter that I could use, or some other place that could catch and override these messages? </p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>Here is what I ended up doing based on Chris's advice:</p>
  
  <p>I created 2 new Formatters for JSON and XML.</p>
  
  <pre><code>public class JsonFormatter : JsonMediaTypeFormatter
  {
      public override System.Threading.Tasks.Task&lt;object&gt; ReadFromStreamAsync(Type type, System.IO.Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
      {
  
         System.Threading.Tasks.Task&lt;object&gt; task = base.ReadFromStreamAsync(type, stream, contentHeaders, formatterLogger);
  
          //parse error if null
         if (task.Result == null)
         {
             //handle error here.
         }
  
         return task;
      }
  }
  
  
  public class XMLFormatter : XmlMediaTypeFormatter
  {
      public override System.Threading.Tasks.Task&lt;object&gt; ReadFromStreamAsync(Type type, System.IO.Stream stream, System.Net.Http.Headers.HttpContentHeaders contentHeaders, IFormatterLogger formatterLogger)
      {
  
          System.Threading.Tasks.Task&lt;object&gt; task = base.ReadFromStreamAsync(type, stream, contentHeaders, formatterLogger);
  
          //parse error if null
          if (task.Result == null)
          {
              //handle error here
          }
  
          return task;
      }
  }
  </code></pre>
  
  <p>and in the <code>Application_Start</code> method in global.asax</p>
  
  <pre><code>GlobalConfiguration.Configuration.Formatters.Insert(0, new JsonFormatter());
  GlobalConfiguration.Configuration.Formatters.Insert(1, new XMLFormatter());
  </code></pre>
  
  <p>I am not sure if there is a better way, but this seems to work.</p>