0

ListingController.cs:

public IActionResult Create()
{
    CreateListingViewModel model = new()
    {
        AllCities = new SelectList(_addressRepo.AllCities()),
        AllItems = new SelectList(_itemRepo.FindAll(), "Id", "Name")
    };
    return View(model);
}

[HttpPost]
public IActionResult Create(CreateListingViewModel model)
{
    if (!ModelState.IsValid)
    {
        foreach (var key in ModelState.Keys)
            Console.WriteLine($"{key}: {ModelState.GetValidationState(key)}");

        model.AllCities = new SelectList(_addressRepo.AllCities());
        model.AllItems = new SelectList(_itemRepo.FindAll(), "Id", "Name");
        return View(model);

    }

    Address address = _addressRepo.FindOrCreate(model.Address);
    Building building = _buildingRepo.FindOrCreate(address, model.Building);
    List<Item> items = _itemRepo.FindByIdIn(model.Items);
    Apartment apartment = _apartmentRepo.FindOrCreate(building, items, model.Apartment);
    Terms terms = _termsRepo.FindOrCreate(model.Terms);
    _listingRepo.Create(apartment, terms, model.Listing);
    return RedirectToAction("Index");
}

CreateListingViewModel.cs:

public class CreateListingViewModel
{
    public IEnumerable<SelectListItem> AllCities { get; set; }
    public AddressViewModel Address { get; set; }
    public BuildingViewModel Building { get; set; }
    public ApartmentViewModel Apartment { get; set; }
    public IEnumerable<SelectListItem> AllItems { get; set; }
    public IEnumerable<long> Items { get; set; }
    public TermsViewModel Terms { get; set; }
    public ListingViewModel Listing { get; set; }
}

_CreateForm.cshtml:

<div class="row mb-3">
    <label class="col-sm-2 col-form-label" asp-for="Address.City">Grad</label>
    <div class="col-sm-4">
        <select class="form-select" asp-for="Address.City" asp-items="Model.AllCities"></select>
    </div>
</div>

I cannot pass form validation, because AllItems and AllCities, forms that are used for populating select dropdowns, are invalid. Like what?

Items: Valid
AllItems: Invalid
AllCities: Invalid
Terms.Deposit: Valid
Terms.ForWorkers: Valid
Terms.ForStudents: Valid
Terms.PetsAllowed: Valid
Terms.DateAvailable: Valid
Terms.SmokingAllowed: Valid
Address.City: Valid
Address.Street: Valid
Address.StreetNum: Valid
Listing.Title: Valid
Listing.Description: Valid
Building.Cctv: Valid
Building.Garage: Valid
Building.Parking: Valid
Building.Elevator: Valid
Building.Intercom: Valid
Building.NumOfFloors: Valid
Building.YearConstructed: Valid
Apartment.Area: Valid
Apartment.Floor: Valid
Apartment.Price: Valid
Apartment.State: Valid
Apartment.Heating: Valid
Apartment.Equipment: Valid
Apartment.NumOfRooms: Valid

Here's the project: https://github.com/IgorArnaut/ASP-NET-Validation-Problem. These two are not supposed to be validated at all. They just populate dropdowns.

1
  • So is your question “how do I exclude them from validation?”? Commented Jul 3 at 15:32

1 Answer 1

1

Properties that are not Form Entry Data (filled in by the user) should ideally not be added into the Model class of the Create action method, otherwise they go through validation, as you are experiencing.

This is probably why lots of MVC examples are putting things like dropdown list option values into ViewBag properties.

You could also start using ViewBag, or consider splitting the single ViewModel class into two classes: a RenderViewModel for rendering the View (has the option list properties) + a CreateViewModel for the Create action method (without option list properties).

The RenderViewModel class could inherit from the CreateViewModel, or they could have a shared (abstract) base class.

Personally I think that although ViewBag can be easy, it really is ugly and hacky because all values you put in there become dynamics and cause you to lose useful and important features like static type checking, the ability to easily refactor, usage tracking and intellisense. So although a bit more work, I'd recommend taking the split models route.

Sign up to request clarification or add additional context in comments.

1 Comment

I think that adding [ValidateNever] above those fixed the issue.

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.