erstellt Ich habe das folgende Verhalten bemerkt und ich frage mich, ob jemand erklären kann, warum es geschieht und wie kann verhindert werden.ASP.NET MVC liest Eigenschaften, wenn das Objekt
In meinen partiellen Klassen habe ich verschiedene Nur-Lese-Eigenschaften hinzugefügt, die in der Datenbank nicht vorhanden sind. Wenn das Objekt erstellt wird, wird auf diese Eigenschaften zugegriffen, bevor wir zur Create-Methode des Controllers gelangen. Auf Eigenschaften, die nur mit get; set;
deklariert sind, wird jedoch nicht zugegriffen.
Um dies näher auszuführen, sehr einfache Beispiele, wenn ich die folgenden Eigenschaften haben:
public bool getBoolProperty {
get {
return true;
}
}
public bool getSetBoolProperty {
get; set;
}
Wenn ich setzte Haltepunkte auf den Eigenschaften dann, wenn das Objekt erstellt wird der Haltepunkt für die erste Eigenschaft getroffen wird, aber nicht der Zweite. Wenn ich jedoch eine Methode habe:
public bool getBoolProperty() {
return true;
}
dann wird nicht darauf zugegriffen.
Ich habe alle möglichen Variationen ausprobiert und Anmerkungen
// 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;
}
}
Ich habe versucht virtual
die Eigenschaften zu erklären, aber alle Variationen, mit Ausnahme der get; set;
Vielfalt, zugegriffen werden, wenn das Objekt erstellt wird. Dieses Verhalten tritt auch für Integer-Eigenschaften
public virtual int getIntProperty {
get {
return 1;
}
}
und Datum/Zeit Eigenschaften,
public virtual DateTime getDateProperty {
get {
return DateTime.Now;
}
}
aber nicht für String-Eigenschaften
public string getStringProperty {
get {
return "Hello String";
}
}
oder eine andere Einheit Eigenschaften
public Item getItem {
get {
return new Item();
}
}
Das Problem em ich habe, ist, dass einige dieser Eigenschaften eine gewisse Logik beinhalten können, die Zugriff auf die Datenbank zB
public bool HasChildren {
get {
return this.Children !== null && this.Children.Count > 0;
}
}
, die zum Zeitpunkt der Erstellung benötigen könnten, nicht das Unternehmen haben.
Offensichtlich kann ich das umgehen, indem ich alles zu einer Methode mache, aber ich wäre interessiert zu wissen, warum ASP.NET MVC auf diese Eigenschaften bei der Objekterstellung zugreift (eine Art interne Validierung vielleicht), und würde mich interessieren zu wissen wenn es irgendwelche Methoden gibt, dies zu verhindern, möglicherweise durch eine Anmerkung, die ich nicht gesehen habe.
Mein Projekt ist Datenbank zuerst, C#, EF 4.1, MVC
bearbeiten
ich auch darauf hinweisen, sollte ich POCO Entitäten bin mit und die Datenbank über gespeicherte Prozeduren/Funktion importiert zugreifen.
Ein Gedanke kam mir der Gedanke ist, dass diese Eigenschaften im Rahmen des Change Tracking-System wie diskutiert here zugegriffen wird. Es scheint, dass wahrscheinlich ein Schnappschuss von dem neu erstellten Gegenstand gemacht wird. Ich versuchte ausgeschaltet Proxy-Erstellung
dbContext.ContextOptions.ProxyCreationEnabled = false;
aber die Eigenschaften sind nach wie vor auf die Schaffung zugegriffen zu werden.
bearbeiten 20130322
Nach Vorschlag des @ ladislavmrnka die Stack-Trace zu erforschen ich diese bekam:
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)
Darin finden Sie die Anrufe zu einem Prüfer oder zwei bemerken. Als Test änderte ich meine Bool-Eigenschaft auf eine Nullable-Bool Eigenschaft:
public bool? getBoolProperty {
get {
return true;
}
}
Dieses Mal ist die Eigenschaft nicht zugegriffen wurde, wenn das Objekt erstellt wurde. Dies ist mein gewünschtes Verhalten, aber ich möchte nicht alle meine benutzerdefinierten Eigenschaften ändern müssen, um NULL-fähig zu sein, so dass meine Frage jetzt wird ...
Gibt es eine Möglichkeit, das Framework nicht zu validieren ein Eigentum? Vielleicht über ein Attribut. This answer fast beantwortet die Frage, aber da ich Datenbank zuerst verwende, scheint ich nicht eine ValidateOnSaveEnabled
Eigenschaft zu deaktivieren. Vielleicht muss ich meine Modelle noch einmal besuchen.
Der Zugriff auf die Eigenschaften ist wahrscheinlich eine Mapping- oder Reflektionssache. Wie auch immer, Sie sollten die Eigenschaften mit [NotMapped] kommentieren. –
So stoppt der Debugger nicht nur, wenn Sie Auto-Eigenschaft verwenden? Der Debugger stoppt nicht bei automatisch implementierten Eigenschaften, es sei denn, Sie verwenden einen [Trick] (http://stackoverflow.com/questions/4408110/debugging-automatic-properties). Für andere Eigenschaften starten Sie, indem Sie den Aufruf-Stack untersuchen, um herauszufinden, was den Zugriff verursacht. –
@LadislavMrnka, verwende ich Web Developer Express, die leider kein Breakpoints-Fenster hat. Netter Tipp auf dem Call-Stack obwohl – Webbie4