2011-12-27 19 views
33

Cân nhắc điều khiển đơn giản này:Kiểm tra để xem nếu ViewBag có một tài sản hay không, để có điều kiện tiêm JavaScript

Porduct product = new Product(){ 
    // Creating a product object; 
}; 
try 
{ 
    productManager.SaveProduct(product); 
    return RedirectToAction("List"); 
} 
catch (Exception ex) 
{ 
    ViewBag.ErrorMessage = ex.Message; 
    return View("Create", product); 
} 

Bây giờ, trong Create quan điểm của tôi, tôi muốn kiểm tra ViewBag đối tượng, để xem nếu nó có Error tài sản hay không. Nếu nó có thuộc tính lỗi, tôi cần phải tiêm một số JavaScript vào trang, để hiển thị thông báo lỗi cho người dùng của tôi.

Tôi tạo ra một phương pháp mở rộng để kiểm tra này:

public static bool Has (this object obj, string propertyName) 
{ 
    Type type = obj.GetType(); 
    return type.GetProperty(propertyName) != null; 
} 

Sau đó, trong giao diện Create, tôi đã viết dòng mã này:

@if (ViewBag.Has("Error")) 
{ 
    // Injecting JavaScript here 
} 

Tuy nhiên, tôi nhận được lỗi này:

Cannot perform runtime binding on a null reference

Bất kỳ ý tưởng nào?

+0

'ViewBag' là null? –

+0

Mã nào thực sự tạo ra lỗi đó? –

+0

@JohnSaunders, như bạn thấy tôi đã đặt 'ViewBag.Error' trong bộ điều khiển của tôi? Làm thế nào nó có thể được null? –

Trả lời

20

bạn đang doesnt làm việc vì ViewBag là một không dynamic object một 'thực tế' loại.

đoạn mã sau nên làm việc:

public static bool Has (this object obj, string propertyName) 
{ 
    var dynamic = obj as DynamicObject; 
    if(dynamic == null) return false; 
    return dynamic.GetDynamicMemberNames().Contains(propertyName); 
} 
+0

Đề xuất tốt @JeffreyABecker. Cảm ơn, nhưng tôi nhận được 'Không thể thực hiện ràng buộc thời gian chạy trên một ngoại lệ tham chiếu null'. –

+3

Dường như tôi nên sử dụng nó như '((Object) ViewBag) .Has (" PropertyName ")'. –

+0

Tính năng chia sẻ lại đề xuất "trả về động! = Null && dynamic.GetDynamicMemberNames(). Chứa (propertyName);" thay vì 2 dòng cuối cùng. Giải pháp tốt! Cảm ơn! –

3

Tôi sẽ tránh ViewBag ở đây hoàn toàn. Xem suy nghĩ của tôi ở đây về điều này: http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html

Cách khác là ném lỗi tùy chỉnh và bắt. làm thế nào để bạn biết nếu cơ sở dữ liệu là xuống, hoặc nếu một logic kinh doanh của nó tiết kiệm lỗi? trong ví dụ trên, bạn chỉ bắt được một ngoại lệ, thường có cách tốt hơn để nắm bắt từng loại ngoại lệ và sau đó là một trình xử lý ngoại lệ chung cho các ngoại lệ thực sự không được giải quyết, chẳng hạn như các trang lỗi tùy chỉnh hoặc sử dụng ELMAH.

Vì vậy, ở trên, tôi sẽ thay ModelState.AddModelError() Sau đó bạn có thể nhìn vào các lỗi này (giả sử bạn arent jsut sẽ sử dụng được xây dựng trong xác nhận) qua How do I access the ModelState from within my View (aspx page)?

Vì vậy, hãy cẩn thận xem xét hiển thị một tin nhắn khi bạn bắt 'ngoại lệ' bất kỳ.

+0

Dường như tôi đang "necrothreading" này :-) Tôi đã đọc bài viết của bạn, và tôi thực sự sử dụng các mô hình mạnh mẽ gõ trong MVC 4 ... Nhưng tôi không có bất kỳ qualms chống lại bằng cách sử dụng ViewBag cho những điều đơn giản. Hầu hết mọi người đến từ C#, và các ngôn ngữ gõ mạnh khác cau mày khi động lực do di sản của họ (tôi cũng là một anh chàng 'gõ mạnh'). Nhưng tất cả đều đi xuống để KIỂM TRA! Nếu lượt xem của bạn được kiểm tra thì các biến động sẽ không thành vấn đề. Trong thực tế, tốt hơn là sử dụng ViewBag ở khắp mọi nơi và kiểm tra nó nhiều hơn là dựa vào các loại mạnh để đảm bảo tính chính xác. Thử nghiệm tốt tạo ra sự lựa chọn động lực so với các loại tranh luận mạnh mẽ. – Loudenvier

+0

Tôi thích JavaScript, tuy nhiên, tôi liên tục bị lỗi khi gõ. Biến động quan trọng. Có hành vi ẩn đằng sau hậu trường với watchbag trong những người giúp đỡ, nơi bất kỳ giá trị nào được ưu tiên cho bất kỳ thứ gì trong một mô hình. Thứ hai, chúng dễ vỡ để tái cấu trúc và tìm tài liệu tham khảo và phân loại bài tập, vv Kiểm tra không phải là bắt tất cả và kiểm tra chỉ là tốt như thế nào các bài kiểm tra của bạn. Không có bài kiểm tra nào của một người là 100%, không phải ở bất kỳ nơi nào hoặc dự án mà tôi từng thấy và đó là rất nhiều. Một nỗ lực tốt nhất của nó và bạn chắc chắn có thể giới thiệu các lỗi mà không bị bắt bởi các bài kiểm tra, mà bạn cập nhật các bài kiểm tra của bạn để xử lý –

+0

sửa lỗi mới này, nhưng điều đó vẫn không ngăn cản nó. Trong khi tôi vui vì bạn đã đăng phản hồi, tôi không thể đồng ý với điều này: "Trên thực tế, tốt hơn nên sử dụng ViewBag ở mọi nơi và kiểm tra nó nhiều hơn dựa vào các loại mạnh để đảm bảo tính chính xác" Yêu cầu bất kỳ kiến ​​trúc sư nào đang sử dụng MVC trên nhiều dự án nếu họ đồng ý với tuyên bố đó. ViewModels là phương thức được ưu tiên cho toàn bộ danh sách các lý do. Tại sao nó sẽ tốt hơn để sử dụng ViewBag và kiểm tra nhiều, thay vì sử dụng một thuộc tính trong một viewmodel, và đơn giản là không phải lo lắng về nó? –

4

Thay vì sử dụng ViewBag, hãy sử dụng Chế độ xem để bạn có thể kiểm tra mục bạn đang lưu trữ. Đối tượng ViewData được sử dụng làm Từ điển của các đối tượng mà bạn có thể tham chiếu bằng khóa, nó không phải là động như là ViewBag.

// Set the [ViewData][1] in the controller 
ViewData["hideSearchForm"] = true;  

// Use the condition in the view 
if(Convert.ToBoolean(ViewData["hideSearchForm"]) 
    hideSearchForm(); 
+0

Làm thế nào? Hãy cho chúng tôi một ví dụ ít nhất;). –

+0

Đây là một mẫu nhỏ – JustEngland

+1

Vẫn ViewBag có vẻ thanh lịch hơn so với Chế độ xem. Tôi không thích các chỉ mục chuỗi. – JustAMartin

98
@if (ViewBag.Error!=null) 
{ 
    // Injecting JavaScript here 
} 
+4

Kính gửi @jazzcat, trước tiên hãy kiểm tra mã của bạn, sau đó gửi mã.Nếu tôi chưa đặt 'ViewBag.Error' trong bộ điều khiển của tôi, điều đó có nghĩa là ViewBag sẽ không có thuộc tính được gọi là' Error' khi chạy, sau đó tôi sẽ gặp phải một ngoại lệ. –

+20

@SaeedNeamati, mã của jazzcat đã làm việc tốt cho tôi. Đối với ViewBag, bất kỳ mục nào không tìm thấy sẽ không có giá trị. Hãy nhớ rằng động lực cuối cùng có một số mã thực tế đằng sau nó. ViewBag là một DynamicViewDataDictionary, mà dường như quyết định trả về null cho các thuộc tính không tồn tại "" hơn là ném một lỗi. – devrelm

+1

Yup, devrelm là đúng, làm việc cho tôi quá ... – user1068352

2

Bạn có thể sử dụng ViewData.ContainsKey("yourkey").

Trong điều khiển:

ViewBag.IsExist = true; 

Theo quan điểm:

if(ViewData.ContainsKey("IsExist")) {...} 
+0

vui lòng sử dụng thẻ mã khi thích hợp. – matiasg

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