Tôi đã nhận thấy hành vi sau và tôi tự hỏi liệu có ai có thể giải thích lý do tại sao nó xảy ra và cách nó có thể được ngăn chặn.ASP.NET MVC đọc thuộc tính khi đối tượng được tạo
Trong các lớp học một phần của mình, tôi đã thêm các thuộc tính chỉ đọc khác nhau không có trong cơ sở dữ liệu. Khi đối tượng được tạo, các thuộc tính này được truy cập trước khi chúng ta tới phương thức Create của controller. Tuy nhiên, các thuộc tính được khai báo chỉ với get; set;
không được truy cập.
Để xây dựng, sử dụng ví dụ rất đơn giản, nếu tôi có các thuộc tính sau:
public bool getBoolProperty {
get {
return true;
}
}
public bool getSetBoolProperty {
get; set;
}
Nếu tôi sau đó đặt breakpoint trên các thuộc tính, khi đối tượng được tạo ra breakpoint là hit cho các tài sản đầu tiên nhưng không thư hai. Tuy nhiên, nếu tôi có phương thức:
public bool getBoolProperty() {
return true;
}
thì điều này không được truy cập.
Tôi đã thử tất cả các loại biến thể và chú thích
// 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;
}
}
Tôi đã thử khai báo các thuộc tính virtual
, tuy nhiên tất cả các biến, ngoại trừ get; set;
đa dạng, được truy cập khi đối tượng được tạo ra. Hành vi này cũng xảy ra đối với tài sản số nguyên
public virtual int getIntProperty {
get {
return 1;
}
}
và tài sản ngày/giờ,
public virtual DateTime getDateProperty {
get {
return DateTime.Now;
}
}
nhưng không phải cho các thuộc tính chuỗi
public string getStringProperty {
get {
return "Hello String";
}
}
hoặc tổ chức khác thuộc tính
public Item getItem {
get {
return new Item();
}
}
Các probl em là tôi có một số các đặc tính này có thể liên quan đến một số logic mà có thể cần truy cập cơ sở dữ liệu ví dụ
public bool HasChildren {
get {
return this.Children !== null && this.Children.Count > 0;
}
}
đó, tại thời điểm tạo ra, đơn vị sẽ không có. Rõ ràng là tôi có thể giải quyết vấn đề này bằng cách làm mọi thứ thành một phương pháp, nhưng tôi muốn biết tại sao ASP.NET MVC truy cập các thuộc tính này trên tạo đối tượng (Một số loại xác nhận nội bộ), và tôi muốn biết nếu có bất kỳ phương pháp nào ngăn chặn điều này, có thể bằng cách chú thích mà tôi không gặp phải.
dự án của tôi là cơ sở dữ liệu đầu tiên, C#, EF 4.1, MVC
Sửa
Tôi cũng nên chỉ ra tôi đang sử dụng các đối tượng POCO và truy cập vào cơ sở dữ liệu thông qua các thủ tục lưu trữ/chức năng nhập khẩu.
Một ý nghĩ xảy ra với tôi là các thuộc tính này đang được truy cập như một phần của hệ thống theo dõi thay đổi như được thảo luận here. Có vẻ như những gì có thể xảy ra là một ảnh chụp đang được chụp của mục mới được tạo ra. Tôi đã cố gắng tắt tạo proxy
dbContext.ContextOptions.ProxyCreationEnabled = false;
nhưng các thuộc tính vẫn đang được truy cập khi tạo. đề nghị
Sửa 20130322
Sau @ ladislavmrnka của khám phá stack trace Tôi nhận điều này:
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)
Trong đó bạn sẽ nhận thấy các cuộc gọi đến một hoặc hai validator. Khi thử nghiệm, tôi đã thay đổi thuộc tính bool thành thuộc tính bool rỗng:
public bool? getBoolProperty {
get {
return true;
}
}
Lần này thuộc tính không được truy cập khi đối tượng được tạo. Đây là hành vi mong muốn của tôi, tuy nhiên, tôi không muốn phải thay đổi tất cả các thuộc tính tùy chỉnh của mình thành rỗng, do đó, câu hỏi của tôi bây giờ trở thành ...
Có cách nào để yêu cầu khung không xác thực bất động sản? Có lẽ thông qua một thuộc tính. This answer gần như trả lời câu hỏi, nhưng vì tôi đang sử dụng cơ sở dữ liệu đầu tiên, tôi dường như không có thuộc tính ValidateOnSaveEnabled
để tắt. Có lẽ tôi cần phải xem lại các mô hình của tôi.
Truy cập các thuộc tính có thể là một số điều bản đồ hoặc phản chiếu. Nhưng dù sao, bạn nên chú thích các thuộc tính với [NotMapped]. –
Vậy trình gỡ lỗi không chỉ dừng lại khi bạn sử dụng thuộc tính tự động? Trình gỡ lỗi không dừng lại trên các thuộc tính được tự động triển khai trừ khi bạn sử dụng [trick] (http://stackoverflow.com/questions/4408110/debugging-automatic-properties). Đối với các thuộc tính khác bắt đầu bằng cách khám phá ngăn xếp cuộc gọi để tìm hiểu nguyên nhân truy cập. –
@LadislavMrnka, tôi đang sử dụng Web Developer Express không có cửa sổ điểm ngắt. Mẹo hay trên ngăn xếp cuộc gọi mặc dù – Webbie4