title: ASP.NET MVC Done Right: ValidateModelState loses Query Parameters using ValidateModelStateAttribute
body: <p>using <a href="http://ben.onfabrik.com/posts/automatic-modelstate-validation-in-aspnet-mvc" rel="nofollow">Ben Foster Automatic Validate Model State</a> I have this code :</p>
  
  <pre><code>[ImportModelStateFromTempData]
  public ActionResult Edit(int id, int otherProperty) {
      // ...
      return View()
  }
  
  [HttpPost,ValidateModelState]
  public ActionResult Edit(int id, PaymentOrderCreateUpdateCommand order) {
      // ...
      return RedirectToAction("Index", new {otherProperty = order.otherProperty}
  }
  </code></pre>
  
  <p>Being on the url : </p>
  
  <pre><code>/Edit/5?otherProperty=4
  </code></pre>
  
  <p>If a fill a some form that post to Edit [HttpPost] action with an invalid model state, the ValidateModelState do it's thing and returns the request to </p>
  
  <pre><code>/Edit/5 
  </code></pre>
  
  <p>problem is the ?otherProperty=4 needed for that view to be generated is lost in the Redirect.</p>
  
  <p>Anyone knows of a way to modify the automatic model state validation attribute so it includes the query parameters on it ?</p>
  
  <p>for completion on the question I add the ValidateModelStateAttribute class :</p>
  
  <pre><code>[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
  public class ValidateModelStateAttribute : ModelStateTempDataTransfer {
      public override void OnActionExecuting(ActionExecutingContext filterContext) {
          if (!filterContext.Controller.ViewData.ModelState.IsValid) {
              if (filterContext.HttpContext.Request.IsAjaxRequest()) {
                  ProcessAjax(filterContext);
              } else {
                  ProcessNormal(filterContext);
              }
          }
  
          base.OnActionExecuting(filterContext);
      }
  
      protected virtual void ProcessNormal(ActionExecutingContext filterContext) {
          // Export ModelState to TempData so it's available on next request
          ExportModelStateToTempData(filterContext);
  
          // redirect back to GET action
          filterContext.Result = new RedirectToRouteResult(filterContext.RouteData.Values);
      }
  
      protected virtual void ProcessAjax(ActionExecutingContext filterContext) {
  
          var errors = filterContext.Controller.ViewData.ModelState.ToSerializableDictionary();
          var json = new JavaScriptSerializer().Serialize(errors);
          // send 400 status code (Bad Request)
          filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
          filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
          filterContext.HttpContext.Response.StatusDescription = "Invalid Model State";
          filterContext.Result = new ContentResult() { Content = json };
      }
  }
  </code></pre>