Удаленная проверка ASP.NET Core 3 с EF Core 3 - PullRequest
0 голосов
/ 30 сентября 2019

На самом деле это вопрос начинающего EF, но я сталкиваюсь с проблемой при использовании [Удаленной] проверки с использованием ASP.NET MVC Core 3 с EF Core 3.

После одного из постов Microsoft этопредложил держать все "СУХОЙ" (не повторяйте себя). В соответствии с указаниями, я добавил свои аннотации данных для проверки в свой класс «сущность» (DbSet в моем контексте). Это выглядит немного странно, смешивая логику презентации с моей логикой БД, но мне также нравится писать вещи только один раз, поэтому я решил попробовать.

Что касается моей сущности. У него есть отношения многие ко многим с другой сущностью. Итак, допустим, моя сущность «Человек», ну, есть список автомобилей, которыми может владеть этот человек.

Мой метод создания

В прошлом с MVC,Я всегда писал свою «модель представления», чтобы она содержала только то, что необходимо для привязки данных в представлении. Тем не менее, желая сохранить вещи СУХИМ, мне, очевидно, нужно использовать свой класс сущностей Person для привязки в представлении, поскольку именно там живут мои DataAnnotations. У него есть множество других свойств, которые мне не нужно заполнять, поэтому я думаю, мне просто не нужно показывать их в пользовательском интерфейсе (хотя я понимаю, что это не остановит хакера, предоставляющего мне эту информацию). .но это другая тема.)

Для создания простых полей ввода это работает отлично, но мне нужно показать пользователю список автомобилей на выбор. Итак, где я могу получить список доступных автомобилей, поскольку он не принадлежит моей организации? Я справился с этим, создав упаковочный класс ViewModel, подобный следующему:

public class MyViewModel
{
    public Person Entity {get; set;}
    public List<Car> Cars {get;set;}
}

Теперь мне нужно связать данные со свойством, которое я назвал «Entity», и я могу получить дополнительные данные автомобилей издругое свойство.

Это тоже хорошо работает. Но затем я сталкиваюсь с проблемой, когда выполняю проверку.

Итак, мой класс Person имеет следующее (воображаемое) свойство

public class Person
{
    [Remote("CheckIdIsAvailable","Persons")]
    public string Id { get; set; }
}

Итак, напоминая, что мой экземпляр Personявляется свойством Entity моей ViewModel, поэтому представление имеет следующую форму:

<tr>
    <td>ID</td>
    <td><input asp-for="Entity.Id" /></td>
    <td><span asp-validation-for="Entity.Id" class="text-danger"></span></td>
</tr>

В моем контроллере есть метод проверки:

[HttpGet]
public async Task<IActionResult> CheckIdIsAvailable(string Id)
{
    ....
}

Однако значениеприходит как «ноль», потому что параметр, отправляемый по проводам: « ...? Entity.Id = ABCD », и моя строка называется «Id», а не «Entity.Id».

Итак, я либо здесь упускаю что-то очевидное, либо ошибаюсь.

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Как сказал Крис Пратт, вы правы в том, что вам следует использовать объект ViewModel для привязки к представлению и из него.

Стоит посмотреть HTML-код, сгенерированный для вас помощником по тегам, и заметить,что вход будет иметь атрибут name с тем свойством, с которым вы связали его в этом объекте (часть asp-for=""). Свойство name - это то, как model binding от представления к контроллеру знает, как отобразить ваш объект, возвращающийся из представления.

Но в идеале вы отправите объект ViewModel в представление после заполненияэто и ожидание одного возврата и сопоставления с вашими сущностями с обеих сторон без отправки / раскрытия ваших сущностей во внешний мир.

public async Task<IActionResult> CheckIdIsAvailable(PersonViewModel model)
{

}

Затем вы добавляете свою проверку в свойства ViewModel, а не в вашу сущность.

Единственные атрибуты, которые вы действительно должны иметь в своих классах Entity, - это если вы используете Code First и определяете поля в базе данных - как атрибут [MaxLength ()] для строковых полей (который являетсяхорошая практика, потому что по умолчанию я думаю, что EF создает строковые поля NVARCHAR (MAX), если вы их не определяете, что не очень хорошо для поиска в дальнейшем. Но это не главное).

Существуют и другие способыопределить свойства поля, а не атрибуты, которые приводят к «более чистым» определениям сущностей, но это также не совсемздесь.

1 голос
/ 01 октября 2019

Вы можете просто получить Entity.Id в объекте в действии удаленной проверки:

[HttpGet]
 public async Task<IActionResult> CheckIdIsAvailable(Person entity)
{
  string Id = entity.Id;
  //other logic
}

Для привязки модели имя параметра равно entity

...