title: Custom required attribute with C# & Web API and using private access modifier with validation context
body: <p>I have the following custom required attribute:</p>
  
  <pre><code>public class RequiredIfAttribute : RequiredAttribute
  {
      private string _DependentProperty;
      private object _TargetValue;
  
      public RequiredIfAttribute(string dependentProperty, object targetValue)
      {
          this._DependentProperty = dependentProperty;
          this._TargetValue = targetValue;
      }
  
      protected override ValidationResult IsValid(object value, ValidationContext validationContext)
      {
          var propertyTestedInfo = validationContext.ObjectType.GetProperty(this._DependentProperty);
  
          if (propertyTestedInfo == null)
          {
              return new ValidationResult(string.Format("{0} needs to be exist in this object.", this._DependentProperty));
          }
  
          var dependendValue = propertyTestedInfo.GetValue(validationContext.ObjectInstance, null);
  
          if (dependendValue == null)
          {
              return new ValidationResult(string.Format("{0} needs to be populated.", this._DependentProperty));
          }
  
          if (dependendValue.Equals(this._TargetValue))
          {
              var x = validationContext.ObjectType.GetProperty("_Mappings");
  
              var objectInstance = (Dictionary&lt;object, string[]&gt;)x.GetValue(validationContext.ObjectInstance, null);
  
              var isRequiredSatisfied = false;
  
              foreach (var kvp in objectInstance)
              {
                  if (kvp.Key.Equals(this._TargetValue))
                  {
                      foreach (var field in kvp.Value)
                      {
                          var fieldValue = validationContext.ObjectType.GetProperty(field).GetValue(validationContext.ObjectInstance, null);
  
                          if (fieldValue != null &amp;&amp; field.Equals(validationContext.MemberName))
                          {
                              isRequiredSatisfied = true;
                              break;
                          }
                      }
                  }
              }
  
              if (isRequiredSatisfied)
              {
                  return ValidationResult.Success;
              }
              else
              {
                  return new ValidationResult(string.Empty);
              }
          }
          else
          {
              // Must be ignored
              return ValidationResult.Success;
          }
      }
  }
  </code></pre>
  
  <p>What I am trying to achieve with it is that I want to conditionally validate based on a property in a model. It also needs to be generic enough to re-use on more than one model. When a specified property has a specific value (which I specify in the attribute), the custom required validation needs to match on those values. For example in this model:</p>
  
  <pre><code>public class PaymentModel
  {
      public Dictionary&lt;object, string[]&gt; _Mappings 
      {
          get
          {
              var mappings = new Dictionary&lt;object, string[]&gt;();
  
              mappings.Add(true, new string[] { "StockID" });
              mappings.Add(false, new string[] { "Amount" });
  
              return mappings;
          }
      }
  
      [Required]
      public bool IsBooking { get; set; }
  
      [RequiredIfAttribute("IsBooking", false)]
      public decimal? Amount { get; set; }
  
      [RequiredIf("IsBooking", true)]
      public int? StockID { get; set; }
  
      public PaymentModel()
      {
  
      }
  }
  </code></pre>
  
  <p>If the <code>IsBooking</code> property is <code>true</code>, then I want <code>StockId</code> to be required, but if it is <code>false</code>, then <code>Amount</code> should be required.</p>
  
  <p>Currently the solution I have works, but it has 2 problems:</p>
  
  <ol>
  <li>There is a dependency on the <code>_Mappings</code> property, which I would like to not have. Does anyone know how I will get around doing it the way I have?</li>
  <li>If I have to use the <code>_Mappings</code> property as is, is there any way to use it as a <code>private</code> access modifier? Currently I can only make my solution work if <code>_Mappings</code> is <code>public</code>, because <code>validationContext.ObjectType.GetProperty("_Mappings")</code> cannot find <code>private</code> modifiers. (If I want to serialize this model to JSON in a Web API response, then I would ideally not want to send along my validation mappings.)</li>
  </ol>