Razor foreach помещает свойство / имя переменной в id, name и * для атрибутов в отображаемых HTML - PullRequest
2 голосов
/ 30 мая 2020

Инструменты и Pltaform: ASP. NET Core MVC 3.1, Visual Studio 2019, Win 10

Обновление: это представление Upsert. Я пытаюсь l oop через свойства модели на странице Razor для создания меток и ввода HTML элементов внутри тега формы, но визуализированный HTML имеет «Item» (имя переменной в foreach ) в качестве значения идентификатора, имени и * для атрибутов HTML.

Отображается HTML в браузере

<div class="form-group row">
  <div class="col-3">
    <label for="item">item</label>
  </div>
  <div class="col-6">
    <input class="form-control" type="text" id="item" name="item" value="Author">
    <span class="text-danger field-validation-valid" data-valmsg-for="item" data-valmsg-replace="true"></span>
  </div>
</div>

HTML отображается в браузере HTML displayed in the browser Razor foreach l oop производит HTML

 @{ var propList = new string[] { "Name", "Author", "ISBN" };}
 @foreach (var item in propList)
    {
        <div class="form-group row">
            <div class="col-3">
                <label asp-for="@item"></label>
            </div>
            <div class="col-6">
                <input asp-for="@item" class="form-control" />
                <span asp-validation-for="@item" class="text-danger"></span>
            </div>
        </div>
    }

Может кто-нибудь объяснить, почему это происходит?

Обновление: Основываясь на предложениях «@Ben Sampica», я внес эти изменения. Как бы выглядело мое представление. Я имею в виду, что помню, как использовал список моделей для представления в виде таблицы (я использовал ASP. NET MVC несколько лет назад, теперь перехожу к. net core), вот внесенные мной изменения,

Просмотр:

@foreach (var book in Model.Books)
  {
    <div class="form-group row">
      <div class="col-3">
        <label asp-for="@book.Name"></label>
      </div>
      <div class="col-6">
        <input asp-for="@book.Name" class="form-control" />
        <span asp-validation-for="@book.Name" class="text-danger"></span>
      </div>
    </div>
  }

Я использую точное Модель просмотра, как вы описали "BooksViewModel"

Я не указывал, что в вопросе раньше, но для ясности, я создаю представление Upsert, поэтому теперь ViewModel представляет собой список, хотя меня беспокоит только по одной записи за раз, модель представления пуста при действии создания, потому что в списке нет данных.

1 Ответ

1 голос
/ 30 мая 2020

Если вы посмотрите Microsoft Docs на ASP. NET Core Tag Helpers , вы увидите, что asp-for на <label> получит атрибут [Display] из свойства. (если имеется). В качестве резервной копии будет использоваться имя свойства. В вашем случае вы передаете коллекцию строк, поэтому давайте погрузимся в то, что видит Razor

PropList[]
{
    string item = "Name"
    string item = "Author"
    string item = "ISBN"
}

Когда это повторяется, свойство Display отсутствует, поэтому из наших правил выше, какая конвенция? Используя имя свойства (которое вы назвали item в своем итераторе).

Я думаю, что то, что вы пытаетесь сделать , может быть лучше выполнено в специальном классе модели, таком как:

public class BookViewModel
{
   public string Name { get; set; }
   public string Author { get; set; }
   public string ISBN { get; set; }
}

затем на вашем экране

@using BookViewModel

<form>
    <div class="form-group row">
      <div class="col-3">
        <label asp-for="@Model.Name"></label>
      </div>
      <div class="col-6">
        <input asp-for="@Model.Name" class="form-control" />
        <span asp-validation-for="@Model.Name" class="text-danger"></span>
      </div>
    </div>
    <div class="form-group row">
      <div class="col-3">
        <label asp-for="@Model.Author"></label>
      </div>
      <div class="col-6">
        <input asp-for="@Model.Author" class="form-control" />
        <span asp-validation-for="@Model.Author" class="text-danger"></span>
      </div>
    </div>
    <div class="form-group row">
      <div class="col-3">
        <label asp-for="@Model.ISBN"></label>
      </div>
      <div class="col-6">
        <input asp-for="@Model.ISBN" class="form-control" />
        <span asp-validation-for="@Model.ISBN" class="text-danger"></span>
      </div>
    </div>
    <button type="submit">Submit</button>
</form>

Ответ на обновление: Ниже приведен ответ из чата ч / б операция и плакат с ответом

  1. Если бы я делал это, я бы просто сделал два действия (Добавить и Edit) и поделитесь частичным представлением для входных данных формы, чтобы код использовался повторно в максимально возможной степени - при этом не слишком умно с решением с этим upsert. Это только моё мнение. Я думаю, что это было частью того, почему я не мог понять, что вы искали.

  2. Я бы также не стал использовать такие вещи, как отражение, чтобы писать HTML. Если вы хотите повторно использовать общий макет типа ввода (например, текстовое поле), в лучшем случае я бы создал компонент представления и передал свойство. Я бы не стал использовать всю модель сразу - как бы вы определить, что такое раскрывающийся список? А как насчет флажка? Вы быстро попадете в очень плохую ситуацию с умными решениями, которые невозможно поддерживать.

Наконец,

Если вы ВСЕ ЕЩЕ хотите продолжить - вы изначально были на правильном пути с отражением - см. Следующую tnet скрипку. Не обращайте внимания на предупреждение компилятора и скопируйте блок @foreach в свой собственный проект.

Foreach в модели просмотра

...