У нас есть веб-приложение, использующее ASP.NET MVC, которое поддерживает методы контроллера, которые принимают объект класса в качестве параметра. Существует автоматическое связывание опубликованных значений формы для создания и заполнения объекта класса, что происходит еще до того, как будет вызван фактический код метода контроллера. Пока все хорошо, но вот моя проблема: в процессе конструирования объекта класса механизм связывания ASP.NET вызывает каждое открытое свойство класса. Некоторые из этих свойств включают в себя некоторые дорогостоящие вычисления (итерация внутренних списков, подсчет операций и т. Д.), И раздражает, что их вызывают без всякой причины и отбрасывают значения. Это свойства, доступные только для чтения, с только «get» и без «set», поэтому связыватель не может касаться их для назначения им значений. Как мы можем предотвратить это?
Вот то, что до сих пор безуспешно пробовалось:
- Используйте [Bind (Include = "...")] в объявлении метода контроллера, чтобы ограничить другие (не только для чтения) свойства, которые фактически могут быть назначены.
- Используйте аннотацию [BindNever] для свойств только для чтения в определении класса.
Наш текущий обходной путь заключается в том, что мы просто полностью отказываемся от реализации свойства только для чтения и переписываем их все как методы. Связующий код не вызывает методы, поэтому это работает, но мы все равно предпочли бы иметь их в качестве свойств, и это похоже на проблему, которая должна быть способной к решению. Есть какие-нибудь мысли?
== РЕДАКТИРОВАТЬ =============
В ответ на приведенные здесь ответы попробовал дополнительные вещи, которые все еще не работали:
- Используйте [Bind (Exclude = "...")] в объявлении метода контроллера, указав свойства, которые мы не хотим вызывать. (Они все равно вызываются.)
== РЕДАКТИРОВАТЬ 2 =============
Дополнительные детали по запросу. Я использую VS 2015, .NET Framework 4.5.2. Только сейчас я создал пример программы для демонстрации проблемы:
- Файл -> Создать -> Проект -> Веб -> Веб-приложение ASP.NET
- В разделе «Шаблоны ASP.NET 4.5.2» выберите «MVC»
- В ManageViewModels.cs есть класс с именем «AddPhoneNumberViewModel». Этот класс встречается как параметр метода ManageController.AddPhoneNumber (версия HttpPost). Добавьте открытое свойство в класс с именем «PropertyThatShouldNeverBeCalled» и поместите в него точку останова (см. Пример кода ниже).
- Скомпилируйте и запустите приложение в режиме отладки. Чтобы получить доступ к конечной точке / Manage / AddPhoneNumber, вам нужно будет создать учетную запись, затем снова получить доступ к конечной точке, ввести номер телефона и нажать «Отправить».
- Обратите внимание, что вы достигли своей точки останова в PropertyThatShouldNeverBeCalled.
- Попробуйте одно из неудачных исправлений, описанных выше (например, добавьте [Bind (Exclude = "PropertyThatShouldNeverBeCalled")] к определению ManageController.AddPhoneNumber).
- Повторите шаг 4 выше. Заметьте, что вы все еще достигли своей точки останова.
Пример кода 1 (из ManageViewModel.cs):
public class AddPhoneNumberViewModel
{
[Required]
[Phone]
[Display(Name = "Phone Number")]
public string Number { get; set; }
public bool PropertyThatShouldNeverBeCalled
{
get
{
bool returnVal = true; // place breakpoint here
return returnVal;
}
}
}
Пример кода 2 (из ManageController.cs):
//
// POST: /Manage/AddPhoneNumber
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> AddPhoneNumber([Bind(Exclude = "PropertyThatShouldNeverBeCalled")]AddPhoneNumberViewModel model)
{
// etc.
}
P.S. Проблема также возникает, когда проект компилируется в режиме выпуска и выполняется без отладки. Я использовал ведение журнала, чтобы подтвердить это в моем первоначальном проекте. Для целей примера проекта просто проще наблюдать за проблемой, используя точку останова.