title: Best approach for complex model/submodel validation (MVC)
body: <h1>Problem</h1>
  
  <p>I know there is a lot of ways of doing Model validation within MVC, and there is quite a lot of documentation regarding this topic. However, I'm not quite sure what's the best approach for validating properties of the <strong>Model</strong> which are <em>"Sub Model"</em> of <strong>same type</strong>. </p>
  
  <p>Keep in mind the following</p>
  
  <ul>
  <li>I still want to to take profit of the <code>TryUpdateModel/TryValidateModel</code> methods</li>
  <li>Each of these <em>"sub models"</em> have strongly typed views</li>
  <li>There is one strongly typed view for the <code>MainModel</code> class that renders the overall display view</li>
  </ul>
  
  <p>It might sound a little confusing but i'll throw in some code to clarify. Take as example the following classes:</p>
  
  <p><strong>MainModel:</strong></p>
  
  <pre><code>class MainModel{
      public SomeSubModel Prop1 { get; set; }
      public SomeSubModel Prop2 { get; set; }
  }
  </code></pre>
  
  <p><strong>SomeSubModel:</strong></p>
  
  <pre><code>class SomeSubModel{
        public string Name { get; set; }
        public string Foo { get; set; }
        public int Number { get; set; }
  }
  </code></pre>
  
  <p><strong>MainModelController:</strong></p>
  
  <pre><code>class MainModelController{
  
      public ActionResult MainDisplay(){
           var main = db.retrieveMainModel();
           return View(main); 
      }
  
      [HttpGet]
      public ActionResult EditProp1(){
           //hypothetical retrieve method to get MainModel from somewhere
           var main = db.retrieveMainModel();
  
           //return "submodel" to the strictly typed edit view for Prop1
           return View(main.Prop1);
      }
  
      [HttpPost]
      public ActionResult EditProp1(SomeSubModel model){
  
           if(TryValidateModel(model)){
                //hypothetical retrieve method to get MainModel from somewhere
                var main = db.retrieveMainModel();
                main.Prop1 = model;
                db.Save();
  
                //when succesfully saved return to main display page 
                return RedirectToAction("MainDisplay");
           }
           return View(main.Prop1);
      }
  
      //[...] similar thing for Prop2 
      //Prop1 and Prop2 could perhaps share same view as its strongly 
      //typed to the same class
  }
  </code></pre>
  
  <p>I believe this code all make sense until now (correct me if it's not the case) because <code>TryValidateModel()</code> is validating against a model with no <code>ValidationAttribute</code>. </p>
  
  <p>The problem lies here, where would be the best place, or what would be the best and most elegant way to have <strong>different validation constraints</strong> for <code>Prop1</code> and <code>Prop2</code> while still taking advantage of <code>TryValidateModel()</code> and not filling the Edit method with conditional statements and <code>ModelState.AddModelError()</code></p>
  
  <p>Usually you could have validation attributes in the <code>SomeSubModel</code> class, but it wouldn't work in this case, because there is different constraints for each property. </p>
  
  <p>Other option is that there could be Custom validation attribute in the <code>MainModel</code> class, but it also wouldn't work in this case because the <code>SomeSubModel</code>object is passed directly to the view and when validating has no reference to its <code>MainModel</code> object.</p>
  
  <p>The only left option I can think about is a ValidationModel for each property, but I am not quite what would be the best approach for this.</p>
  
  <h1>Solution</h1>
  
  <p>Here's solution I implemented, based of @MrMindor's answer.</p>
  
  <p><strong>Base ValidationModel class:</strong></p>
  
  <pre><code>public class ValidationModel&lt;T&gt; where T : new()
  {
      protected ValidationModel() {
          this.Model = new T();
      }
      protected ValidationModel(T obj) { 
          this.Model = obj; 
      }
  
      public T Model { get; set; }
  }
  </code></pre>
  
  <p><strong>Validation Model for Prop1</strong></p>
  
  <pre><code>public class Prop1ValidationModel:ValidationModel&lt;SomeSubModel&gt;
  {
      [StringLength(15)]
      public string Name { get{ return base.Model.Name; } set { base.Model.Name = value; } }
  
      public Prop1ValidationModel(SomeSubModel ssm)
          : base(ssm) { }
  }
  </code></pre>
  
  <p><strong>Validation Model for Prop2</strong></p>
  
  <pre><code>public class Prop2ValidationModel:ValidationModel&lt;SomeSubModel&gt;
  {
      [StringLength(70)]
      public string Name { get{ return base.Model.Name; } set { base.Model.Name = value; } }
  
      public Prop2ValidationModel(SomeSubModel ssm)
          : base(ssm) { }
  }
  </code></pre>
  
  <p><strong>Action</strong></p>
  
  <pre><code>[HttpPost]
  public ActionResult EditProp1(SomeSubModel model){
  
       Prop1ValidationModel vModel = new Prop1ValidationModel(model);
       if(TryValidateModel(vModel)){
  
            //[...] persist data
  
            //when succesfully saved return to main display page 
            return RedirectToAction("MainDisplay");
       }
       return View(model);
  }
  </code></pre>