3

Is it possible to place conditions on a ViewModel where data equals a specific value in one field within the entity framework, the required element or entire object is removed from the ViewModel before using TryValidateModel on the ViewModel?

I would like to remove HomeValue and PurchasePrice from the Model validation where OwnOrRent (model.OwnOrRent) is not equal to 1 or 9.

Model.cs

public class Address
{
    public int Id { get; set; }

    [DisplayName("House Name or Number")]
    [StringLength(50)]
    public string HouseNameOrNumber { get; set; }

    [DisplayName("Post Town")]
    [StringLength(50)]
    public string PostTown { get; set; }

    [Required(ErrorMessage = "Own or Rent is Required")]
    [DisplayName("Own or Rent")]
    [StringLength(50)]
    public string OwnOrRent { get; set; }

    [Required(ErrorMessage = "Mortgage/Rent Amount is Required")]
    [DisplayName("Mortgage/Rent Amount")]
    [StringLength(50)]
    public string MortgageRent { get; set; }

    [Required(ErrorMessage = "Home Value is Required")]
    [DisplayName("Home Value")]
    [StringLength(50)]
    public string HomeValue { get; set; }

    [Required(ErrorMessage = "Purchase Price is Required")]
    [DisplayName("Purchase Price")]
    [StringLength(50)]
    public string PurchasePrice { get; set; }
}

HomeController.cs

public ActionResult Application(int id)
{
    var viewAddressModel = new Address();

    using (
        var dbEntities = new DbEntities(new EntityConnection(_df.DbEntities)))
    {
        var model = dbEntities.Applications.Single(e => e.Id == id);

        viewAddressModel.Id = Id;
        viewAddressModel.HouseNameOrNumber = model.HouseNameOrNumber;
        viewAddressModel.PostTown = model.PostTown;
        viewAddressModel.OwnOrRent = GetStatus(model.OwnOrRent);
        viewAddressModel.MortgageRent = model.MortgageRent.ToString();
        viewAddressModel.HomeValue = model.HomeValue;
        viewAddressModel.PurchasePrice = model.PurchasePrice;

        if (model.OwnOrRent != "1" || model.OwnOrRent != "9")
        {
            ModelState.Remove("HomeValue");
            ModelState.Remove("PurchasePrice");
        }

        if (!TryValidateModel(viewAddressModel))
        {
            return PartialView("Address", viewAddressModel);
        }
    }

    var vm = new ApplicationViewModel { Item = CreateApp(id) };

    return PartialView("Application", vm);
}

As you can see I have tried to use ModelState.Remove but this has no effect.

Any assistance with this would be much appreciated?

4
  • Remove really? Or you want them to be excluded from validation... Commented May 19, 2015 at 9:17
  • There is no point in ModelState.Remove("HomeValue"); - there are no values in ModelState at that point. And why are you calling TryValidateModel in a GET method? I suggest you do some research on ModelState to understand what it is and how it works. Commented May 19, 2015 at 9:23
  • The reason for TryValidateModel is to recheck old data that was stored pre MVC and prior to my involvement, to ensure any issues such as missing data are presented to the user requesting data to address the issue and rectify before carrying on with an application. Commented May 19, 2015 at 10:11
  • As for remove, I wish to turn off the validation, when model.OwnOrRent is not 1 or 9 as no data exists for HomeValue or PurchasePrice as it is not required. Commented May 19, 2015 at 10:13

2 Answers 2

4

Based on your comments you want to populate a model from the database, then validate it (because its old data which may not be valid), but not display errors for HomeValue or PurchasePrice based on the value of OwnOrRent, in which case you need to call TryValidateModel first, then remove ModelState errors

var viewAddressModel = new Address();
.... // set values
if (!TryValidateModel(viewAddressModel))
{
  if (model.OwnOrRent != "1" || model.OwnOrRent != "9")
  {
    if (ModelState.ContainsKey("HomeValue"))
    {
      ModelState["HomeValue"].Errors.Clear();
    }
    if (ModelState.ContainsKey("PurchasePrice"))
    {
      ModelState["PurchasePrice"].Errors.Clear();
    }
  }
}

You can now use if (ModelState.IsValid) to check if there are any other validation errors and return the appropriate view

Side note: I just used your if condition relating to the OwnOrRent value, but I suspect what you really want is

if (!(model.OwnOrRent == "1" || model.OwnOrRent == "9"))
Sign up to request clarification or add additional context in comments.

8 Comments

Thank you, I have tried your code, I'm still getting the partial view as the TryValidateModel is still invalid, I can see the errors remove, but as the partial view is returned, so return the error messages.
Is there a way of updating the model state and perhaps retrying TryValidateModel after the errors have been removed?
Do you mean you are getting an error for property HomeValue? Are you actually hitting the ModelState["HomeValue"].Errors.Clear(); lines? As I noted I think your if (model.OwnOrRent != "1" || model.OwnOrRent != "9") is incorrect.
No you cant use TryValidateModel again, that just adds the errors you just removed so its a bit pointless.
Yes, the code hits the lines you've added and I can see that initially HomeValue has 1 error count, after the code moves on HomeValue has a 0 error count, but as the line `return PartialView("Address", viewAddressModel);' still exists within the TryValidateModel check the partial view renders and so reappears the errors for HomeValue and PurchasePrice.
|
1

There is a thread about the different options to do conditional validation: ASP.NET MVC Conditional validation

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.