2012-12-13 53 views
5

Nhìn qua Breeze Tôi đã rất ấn tượng với nhiều tính năng của nó.Xác thực phía máy chủ Breeze

Tôi gặp sự cố khi tìm hiểu cách nhận các lỗi xác thực DbContext phía máy chủ quay lại máy khách. Tôi hiểu rằng Breeze có trình xác nhận mặc định phản ứng với một vài thuộc tính như "Bắt buộc", nhưng còn tất cả các thuộc tính khác thì sao? Tôi có thể viết trình xác nhận javascript tùy chỉnh cho Breeze để kiểm tra phía máy khách, nhưng tôi cũng cần kiểm tra để đảm bảo thực thể hợp lệ ở phía máy chủ.

Ví dụ: Ứng dụng yêu cầu "Người" để có địa chỉ Email hợp lệ. Người dùng độc hại xuất hiện và nhận địa chỉ email qua ứng dụng khách và bài đăng tới máy chủ có ngày không vượt qua trình xác thực "EmailAddress". Vì vậy, đến nay kinh nghiệm của tôi với Breeze là địa chỉ email sẽ tiết kiệm và không bong bóng lên bất kỳ lỗi DbContext/Entity Framework.

Giả sử mô hình bên dưới, cách tốt nhất để nhận bất kỳ lỗi xác thực đối tượng nào?

public class PeopleContext : DbContext 
{ 
    public PeopleContext() 
     : base("name=ConnectionString"){ } 

    public DbSet<Person> People { get; set; } 
} 

public class Person 
{ 
    public int PersonId { get; set; } 
    public string FirstName { get; set; } 
    [Required] 
    public string LastName { get; set; } 
    [EmailAddress] 
    [Required] 
    public string Email { get; set; } 
} 

UPDATE 1:

Dưới đây là một số hướng dẫn để tái tạo các vấn đề mà tôi đang trải qua.

  1. theo hướng dẫn để tạo ra các "Todo" sample (http://www.breezejs.com/documentation/start-nuget)
  2. Thêm một validator tùy chỉnh mới cho BreezeSampleTodoItem.cs nộp

    [AttributeUsage(AttributeTargets.Property)] 
    public class CustomValidator : ValidationAttribute 
    { 
        public override Boolean IsValid(Object value) 
        { 
         string val = (string)value; 
         if (!string.IsNullOrEmpty(val) && val == "Error") 
         { 
          ErrorMessage = "{0} equal the word 'Error'"; 
          return false; 
         } 
         return true; 
        } 
    } 
    
  3. Trang trí lĩnh vực Mô tả với các tùy chỉnh mới trình xác thực:

    [CustomValidator] 
    public string Description { get; set; } 
    
  4. Thêm sử dụng phù hợp tất nhiên ("Hệ thống" và "System.ComponentModel.DataAnnotations").

  5. Chạy dự án.
  6. Trong một trong các trường mô tả, hãy nhập "Lỗi" và lưu.

Đây là nơi tôi mong đợi sẽ thấy lỗi xuất hiện thông qua gió hoặc thậm chí là "DbEntityValidationException" được ném từ Khung thực thể. Tôi đã thử trên 2 máy tính riêng biệt với cùng một kết quả. Thực thể lưu vào cơ sở dữ liệu như thể không có lỗi. Trong thực tế, nếu bạn đặt một điểm ngắt bất cứ nơi nào bên trong phương pháp IsValid của trình xác nhận tùy chỉnh, bạn sẽ thấy rằng nó thậm chí không được gọi.

Trả lời

3

Kể từ Breeze v 0.78.1, tất cả các xác thực của máy chủ DbContext đã đăng ký hiện sẽ thực thi trong khi thực hiện cuộc gọi EntityManager SaveChanges. Bất kỳ trường hợp ngoại lệ nào gặp phải sẽ khiến cho quá trình khôi phục trở lại và bất kỳ lỗi xác thực nào được tuần tự hóa trở lại ứng dụng khách của Breeze.

Lưu ý rằng chức năng này chưa được hỗ trợ cho các mẫu ObjectContext cũ hơn (trái với DbContext) dựa trên EF.

Và ... nhờ adamlj để khám phá vấn đề này và đề xuất giải pháp.

1

Tôi không chắc chắn những gì bạn có ý nghĩa bởi

lỗi

get server-side DbContext xác nhận lại cho khách hàng

Bạn có thể có nghĩa là bạn muốn thông báo lỗi xác nhận được gửi cho khách hàng. Nhưng phần còn lại của câu hỏi của bạn cho thấy rằng bạn muốn biết (a) cách chạy xác thực tùy chỉnh trên máy chủ và (b) cách lấy và chạy phiên bản JavaScript tương ứng của xác thực đó trên máy khách. Tôi sẽ giải thích câu hỏi này của bạn.

server

Entity Framework (mà bạn đang sử dụng trong ví dụ của bạn) sẽ tự động chạy dữ liệu Chú quy tắc xác nhận cho bạn ... trừ khi bạn đã vô hiệu hóa có tính năng bằng tay. Nếu bạn tạo tùy chỉnh quy tắc xác thực theo cách thích hợp, EF cũng sẽ chạy các quy tắc này. This post by Daniel Wertheim mô tả cách viết các quy tắc như vậy. Tôi không thể xác minh cho bài viết đó trong từng chi tiết nhưng có vẻ như chính xác với tôi. Nó thậm chí còn định nghĩa một Email-validationattribute tùy chỉnh!

Nếu việc tạo quy tắc xác nhận Chú thích dữ liệu tùy chỉnh có vẻ quá Baroque đối với bạn (như thường với tôi), bạn có thể viết và gọi logic xác thực của riêng mình theo một trong các phương pháp BeforeSave... được thảo luận trong "Server-side Interception".

Tôi nghĩ đây là các tùy chọn máy chủ tốt nhất của bạn. Trên cho khách hàng ...

Khách hàng

Breeze đăng ký client-side JavaScript hợp lệ để phù hợp nhất định của server-side dữ liệu Chú thích (ví dụ, RequiredMaxLength) mà đi qua dây trong siêu dữ liệu. Khi tôi viết, tùy chỉnh Chú thích dữ liệu không được nhận dạng hoặc không được bao gồm trong siêu dữ liệu và chúng không có các tương tự ngoài hộp trên máy khách. Nếu bạn muốn client cấu hình trước các thực thể của bạn bằng cách sử dụng các quy tắc này, bạn sẽ phải viết các trình xác nhận JavaScript tương ứng của riêng bạn và đăng ký chúng cho các loại thực thể thích hợp như được thảo luận trong trang tài liệu Validation.

Nếu bạn có đề xuất hoặc lựa chọn thay thế tốt hơn, chúng tôi rất muốn nghe chúng.

+0

Xin chào Ward, Cảm ơn bạn đã trả lời và dự án tuyệt vời! Tôi đã chỉnh sửa câu hỏi của mình để cung cấp ví dụ về cách nhân rộng vấn đề mà tôi đang gặp phải. Vấn đề tôi gặp phải là không có chú thích dữ liệu nào đang được đánh giá khi sử dụng phương thức EFContextProvider.SaveChanges (saveBundle). Tôi đã kéo xuống mã nguồn cho Breeze và nếu tôi thay đổi mã cho phương thức EFContextProvider.SaveChangesCore sử dụng ((DbContext) (đối tượng) Ngữ cảnh) .SaveChanges() thay vì ObjectContext.SaveChanges(), thì chú thích được đánh giá đúng. Nhưng tôi không muốn sửa đổi Nguồn. – adamlj

+0

Một lưu ý nữa, tôi đã kiểm tra các phương pháp BeforeSave. Mối quan tâm của tôi là tôi chỉ có thể trả lại một bool. Đối với các lỗi xác nhận, cần có cách nào đó để nhận lại thông báo lỗi cho người dùng. – adamlj

+0

Bạn nên ném một ngoại lệ bao gồm giải thích về sự thất bại, ví dụ: 'ném mới InvalidOperationException ("Không thể lưu thực thể loại không xác định"); 'Returning false chỉ yêu cầu ContextProvider bỏ qua thực thể đó trong quá trình lưu; nó không chấm dứt việc lưu! Xem phần "[Chặn phía máy chủ] (http: //www.breezejs.com/documentation/server-side-interception) "trang trong tài liệu. – Ward

Các vấn đề liên quan