使用IValidatableObject进行验证时,来自refrenced模型类的C#/ MVC / Entity Access属性

时间:2016-11-17 07:45:53

标签: c# asp.net-mvc validation asp.net-mvc-4 asp.net-web-api

我创建了一个WebAPI Web应用程序,我通过实现IValidatableObject来验证数据。根据验证结果,正在调用外部API,并且如果模型有效,则保存数据。 我已经创建了调用外部API的逻辑。

我的模型具有以下结构:

public static void SelectionSort<T>(T[] numArray)
    where T: IComparable<T>
{
   for (int i = 0; i < numArray.Length -1; ++i)
   {
       T minElement = numArray[i];
       int minLocation = i;

       for (int j = i + 1; j < numArray.Length; ++j)
       {
           if (numArray[j].CompareTo(minElement) < 0)
           {
               minElement = numArray[j];
               minLocation = j;
           }
       }

       if (minLocation != i)
       {
           T temp = numArray[minLocation];
           numArray[minLocation] = numArray[i];
           numArray[i] = temp;
       }
   }
}

POST的WebAPI控制器:

public class Class1
{
   public string Class1Prop { get; set; }
   public ICollection<Class1Data> Data { get; set; }
}

public class Class1Data : IValidatableObject
{
   public int Id { get; set; }
   public string Prop1{ get; set; }
   public string Prop2 { get; set; }
   ..
   public string Prop10 { get; set; }

   // Validate Model
   private bool validated = false;
   public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
   {
          if (!validated)
          {
                 if ((Prop1 != value1) || (Prop2 != value2) || .. )
                 {
                       // CALL EXTERNAL API
                 }
                 validated = true;
          }     
          yield return ValidationResult.Success;
   }
}       

我想在Class2中的Validate方法调用外部API时包含Class1Prop的值。 我试图找到一种方法来做到这一点,并寻找一种方法,但可以找到一种方法。 尽可能多的我想保留模型的结构。 我希望我的问题没有任何意义和抱歉,如果它没有记录。

1 个答案:

答案 0 :(得分:1)

您可能需要某种授权才能在Class1.Class1Prop内引用Class1Data

public class Class1Data : IValidatableObject
{
    public int Id { get; set; }
    public string Prop1 { get; set; }
    public string Prop2 { get; set; }
    public string Prop10 { get; set; }

    public Func<string> AcquiresParentProp { get; set; }

    // Validate Model
    private bool validated = false;
    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
          if (!validated)
          {
                 if ((Prop1 != value1) || (Prop2 != value2))
                 {
                       // CALL EXTERNAL API
                     if(AcquiresParentProp != null)
                     {
                         var parentProp = AcquiresParentProp();
                         // use parentProp
                     }
                 }
                 validated = true;
          }     
        yield return ValidationResult.Success;
    }
}

设置委派的方法可以放在Class1

public class Class1
{
    public string Class1Prop { get; set; }
    public ICollection<Class1Data> Data { get; set; }

    private string GetProp()
    {
        return Class1Prop;
    }

    public void ParentLookup()
    {
        foreach(var data in Data)
        {
            data.AcquiresParentProp = GetProp;
        }
    }
}

并且可以在验证之前调用该方法:

    [ResponseType(typeof(Class1))]
    public async Task<IHttpActionResult> PostClass1(Class1 class1)
    {
        class1.ParentLookup();
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Class1.Add(class1);
        await db.SaveChangesAsync();

        return CreatedAtRoute("DefaultApi", new { id = Class1.Id }, class1);
    }