Я заметил следующее поведение, и мне интересно, может ли кто-нибудь объяснить, почему это происходит и как его можно предотвратить.ASP.NET MVC считывает свойства при создании объекта
В моих частных классах я добавил различные свойства только для чтения, которых нет в базе данных. Когда объект создается, эти свойства доступны, прежде чем мы перейдем к методу Create контроллера. Однако свойства, объявленные только с get; set;
, не доступны.
Разрабатывать, используя самые простые примеры, если у меня есть следующие свойства:
public bool getBoolProperty {
get {
return true;
}
}
public bool getSetBoolProperty {
get; set;
}
Если бы я тогда поставил точки останова на свойства, когда объект создается точка останова для первого свойства, но не второй. Однако, если у меня есть метод:
public bool getBoolProperty() {
return true;
}
тогда к этому нельзя обратиться.
Я пробовал все виды вариаций и аннотации
// empty set
public bool getBoolProperty {
get {
return true;
}
set {}
}
// not mapped attribute
[NotMapped]
public bool getBoolProperty {
get {
return true;
}
}
// getting private variable
private bool _boolProperty = true;
public bool getPrivateBoolProperty {
get {
return _boolProperty;
}
}
Я пытался объявить свойства virtual
, но все варианты, кроме get; set;
сорта, которые доступны, когда объект будет создаваться. Это также происходит для целочисленных свойств
public virtual int getIntProperty {
get {
return 1;
}
}
и свойств даты/времени,
public virtual DateTime getDateProperty {
get {
return DateTime.Now;
}
}
но не для строковых свойств
public string getStringProperty {
get {
return "Hello String";
}
}
или других сущностей свойства
public Item getItem {
get {
return new Item();
}
}
Th е У меня проблема в том, что некоторые из этих свойств может включать в себя некоторую логику, которая может понадобиться доступ к базе данных, например,
public bool HasChildren {
get {
return this.Children !== null && this.Children.Count > 0;
}
}
, который, в момент создания, компания не будет иметь.
Очевидно, что я могу обойти это, сделав все методом, но мне было бы интересно узнать, почему ASP.NET MVC обращается к этим свойствам при создании объекта (возможно, какая-то внутренняя проверка), и мне было бы интересно узнать если есть какие-либо способы предотвращения этого, возможно, путем аннотации, с которой я не сталкивался.
Мой проект базы данных первых, C#, EF 4,1, MVC
Редактировать
Я хотел бы также отметить, я использую POCO объектов и доступа к базе данных с помощью хранимых процедур/импорта функций.
Одна мысль пришла мне в голову, что эти свойства доступны как часть системы отслеживания изменений, как обсуждалось here. Кажется, что, вероятно, происходит моментальный снимок вновь созданного элемента. Я попытался отключив создание прокси
dbContext.ContextOptions.ProxyCreationEnabled = false;
но свойства все еще получать доступ по созданию. Предложение
Редактировать 20130322
Следующие @ ladislavmrnka по изучению трассировки стека я получил это:
at System.ComponentModel.ReflectPropertyDescriptor.GetValue(Object component)
at System.Web.Mvc.AssociatedMetadataProvider.<>c__DisplayClassb.<GetPropertyValueAccessor>b__a()
at System.Web.Mvc.ModelMetadata.get_Model()
at System.Web.Mvc.DataAnnotationsModelValidator.<Validate>d__1.MoveNext()
at System.Web.Mvc.ModelValidator.CompositeModelValidator.<Validate>d__5.MoveNext()
at System.Web.Mvc.DefaultModelBinder.OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model)
at System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor)
at System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
at System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)
at System.Web.Mvc.Controller.ExecuteCore()
at System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext)
at System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext)
at System.Web.Mvc.MvcHandler.<>c__DisplayClass6.<>c__DisplayClassb.<BeginProcessRequest>b__5()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass1.<MakeVoidDelegate>b__0()
at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
at System.Web.Mvc.MvcHandler.<>c__DisplayClasse.<EndProcessRequest>b__d()
at System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f)
at System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action)
at System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult)
at System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result)
at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)
В нем вы увидите вызовы валидатора или два. В качестве теста я изменил свое свойство Его к обнуляемому BOOL собственности:
public bool? getBoolProperty {
get {
return true;
}
}
На этот раз свойство не доступно, когда был создан объект. Это мое желаемое поведение, однако, я не хочу, чтобы все мои пользовательские свойства были обнуляемы, поэтому мой вопрос теперь становится ...
Есть ли способ сообщить структуре не проверять имущество? Возможно через атрибут. This answer почти отвечает на вопрос, но поскольку я сначала использую базу данных, у меня, похоже, нет свойства ValidateOnSaveEnabled
для отключения. Возможно, мне нужно вернуться к моим моделям.
Доступ к свойствам, вероятно, является некоторой картиной или отражением. Во всяком случае, вы должны аннотировать свойства с помощью [NotMapped]. –
Итак, отладчик не останавливается, только когда вы используете свойство auto? Отладчик не останавливается на автоматически реализованных свойствах, если вы не используете [трюк] (http://stackoverflow.com/questions/4408110/debugging-automatic-properties). Для других свойств начинайте с изучения стека вызовов, чтобы узнать, что вызывает доступ. –
@LadislavMrnka, я использую Web Developer Express, к сожалению, у которого нет окна точек останова. Хороший совет в стеке вызовов, хотя – Webbie4