Ninject + MVC3 = InvalidOperationException: Trình tự không chứa phần tử


90

Tôi đã tạo một dự án MVC3 mới, nhấn F5, xem trang mẫu.

Sau đó, tôi sử dụng NuGet để lấy phần mở rộng Ninject.MVC . Tôi đã sửa đổi global.asax của mình theo tài liệu Ninject, Cách thiết lập ứng dụng MVC3 :

public class MvcApplication : NinjectHttpApplication
{
   public static void RegisterGlobalFilters(GlobalFilterCollection filters)
   {
       filters.Add(new HandleErrorAttribute());
   }

   public static void RegisterRoutes(RouteCollection routes)
   {
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

       routes.MapRoute(
           "Default", // Route name
           "{controller}/{action}/{id}", // URL with parameters
           new { controller = "Home", action = "Index", 
               id = UrlParameter.Optional });
   }

   protected override IKernel CreateKernel()
   {
       var kernel = new StandardKernel();
       kernel.Load(Assembly.GetExecutingAssembly());
       return kernel;
   }

   protected override void OnApplicationStarted()
   {
       base.OnApplicationStarted();

       AreaRegistration.RegisterAllAreas();
       RegisterGlobalFilters(GlobalFilters.Filters);
       RegisterRoutes(RouteTable.Routes);
   }
}

Bây giờ khi tôi chạy ứng dụng, tôi nhận được màn hình màu vàng chết chóc với ngoại lệ sau:

InvalidOperationException - Chuỗi không chứa phần tử.

tại System.Linq.Enumerable.Single (...)

tại Ninject.Web.Mvc.Bootstrapper.Initialize (...) dòng 67.

Và chắc chắn, dòng 67 của tệp đó gọi .Single (), do đó sẽ loại bỏ ngoại lệ.

Tôi đang làm gì sai?

Câu trả lời:


101

Bạn có thể nhận thấy rằng sau khi cài đặt ninject.mvc3NuGet, có một App_Startthư mục con được tạo bên trong dự án của bạn chứa một NinjectMVC3.cstệp. Xóa thư mục này và thử lại. Vì vậy, đây là các bước tôi đã làm theo:

  1. Tạo một dự án ASP.NET MVC 3 mới bằng cách sử dụng mẫu mặc định
  2. Mở cửa sổ Bảng điều khiển Trình quản lý Gói (Xem -> Windows Khác -> Bảng điều khiển Trình quản lý Gói)
  3. install-package ninject.mvc3trên dòng lệnh
  4. Thay thế mã mặc định Global.asaxbằng mã trong câu hỏi của bạn
  5. Xóa AppStartthư mục con được tạo trong quá trình cài đặt gói
  6. Chạy ứng dụng
  7. Tận hưởng vẻ đẹp của /Home/Indextrang mặc định được mở trong trình duyệt web Google Chrome của bạn :-)

3
Điều đó đã hiệu quả. Tôi không biết tại sao. Tôi không thích sửa lỗi mà không hiểu nó ... nhưng cảm ơn, điều này đã mở khóa cho tôi.
Judah Gabriel Himango

19
Nó không phải là một lỗi. Gói NuGet chỉ sử dụng một cách khác để thiết lập hạt nhân để nó không phải thay đổi global.asax. Ứng dụng của bạn đã sử dụng cả hai cách một cách ngẫu nhiên khiến tiện ích mở rộng ở trạng thái không hợp lệ vì nó được khởi động hai lần.
Remo Gloor

Cảm ơn bạn đã giải thích hữu ích, Remo.
Judah Gabriel Himango

4
Cách chính xác để giải quyết vấn đề này mà không xóa thư mục App_Start là gì?
Ryan Lundy

12
@Kyralessa, bằng cách để nguyên Global.asax (không bắt nguồn từ NinjectHttpApplication) và định cấu hình hạt nhân trong ~/App_Start/NinjectMVC3.cstệp ( RegisterServicesphương thức).
Darin Dimitrov

120

Tôi phải thêm vào điều này với hy vọng rằng ai đó sẽ giải quyết vấn đề nhanh chóng hơn và không muốn nhổ từng sợi tóc trên đầu họ như tôi đã từng làm.

Tôi cần đổi tên mọi thứ trong dự án của mình để phù hợp với các điều khoản kinh doanh mới. Tôi đã thay đổi không gian tên ở khắp mọi nơi và tôi thậm chí còn thay đổi Tên hợp ngữ (nhấp chuột phải vào tab dự án> thuộc tính> ứng dụng) để hợp ngữ được tạo phù hợp với quy ước đặt tên mới. Việc đổi tên lắp ráp là điều khiến Ninject rất tức giận!

Bằng cách đổi tên assembly được tạo ra một tệp mới với tên mới đã được tạo khi chúng tôi biên dịch. Tuy nhiên, tập tin cũ với tên cũ vẫn nằm trong thư mục bin! Nếu bạn kích hoạt Ninject thông qua lớp đã thêm trong App_Start thì lớp kích hoạt này sẽ được gọi trong CẢ HAI tập hợp (cũ VÀ mới được đổi tên). Đừng hỏi tôi làm thế nào hoặc tại sao, nhưng nó có và nó cung cấp cho bạn lỗi "đã được khởi tạo" này.

Ngay cả giải pháp làm sạch cũng không hoạt động vì Visual Studio sẽ chỉ xóa các tệp nhị phân mà nó đang tạo ra, đó sẽ là các tệp được đổi tên mới. Nó để lại những cái cũ chỉ ngồi đó một mình.

Hãy xóa thư mục bin của bạn trước khi bạn thử làm bất cứ điều gì khác! Tôi hy vọng điều này sẽ giúp người khác khỏi lãng phí những giờ làm việc quý giá!


7
Chà, tôi đã lãng phí 40 phút trước khi tình cờ nhận ra câu trả lời của bạn. Cảm ơn Alex!
Maxim V. Pavlov

3
Câu trả lời được chấp nhận không làm điều đó cho tôi nhưng câu trả lời này đã làm. Cảm ơn Alex.
Pluc

2
Cảm ơn bạn rất nhiều! Tôi đã đốt cháy một giờ cho vấn đề này, và sẽ còn nhiều hơn nữa nếu không có phản hồi của bạn. Đây phải là câu trả lời chính xác cho câu hỏi thích hợp.
Doug

2
Xuất sắc! Cảm ơn Alex. Tôi đã lãng phí rất nhiều thời gian để tìm hiểu vấn đề này, giải pháp của bạn đã hoạt động hoàn hảo.
Apogee

3
Điều này thật tuyệt vời. Cảm ơn bạn rất nhiều. Tôi đã làm chính xác điều này, đổi tên một không gian tên đầy đủ và thậm chí không quy các vấn đề của tôi là do assembly vẫn được xây dựng trong thùng. Cảm ơn rât nhiều!
David L

23

Tôi đã cập nhật Wiki tài liệu được liên kết trong câu hỏi của bạn để chỉ ra cả hai cách để thiết lập ứng dụng MVC3. Tôi khuyên bạn nên sử dụng tùy chọn thứ hai, đây là cách ưa thích cho NuGetpackage.

Thay vì bắt nguồn từ NinjectHttpApplication, nó đang sử dụng NinjectMVC.cs trong thư mục AppStart được tạo trong quá trình cài đặt gói. Đây cũng là vị trí mà bạn tạo hạt nhân và nơi bạn tải các mô-đun của mình hoặc nơi bạn xác định các ràng buộc.


Rất hữu ích, Remo. Vì tôi đã đánh dấu một câu trả lời nên tôi sẽ chỉ ủng hộ câu trả lời của bạn và có thể ủng hộ một vài câu trả lời khác của bạn. Cảm ơn bạn đã ở trên và hơn thế nữa trong việc trả lời và cập nhật Wiki.
Judah Gabriel Himango

4

Như Alex Ford đã nói:

Tôi phải thêm vào điều này với hy vọng rằng ai đó sẽ giải quyết vấn đề nhanh chóng hơn và không muốn nhổ từng sợi tóc trên đầu họ như tôi đã từng làm.

Tôi đã có một phiên bản đặc biệt của vấn đề đó có thể được giải quyết như sau:

Chi tiết ngoại lệ: System.InvalidOperationException: Chuỗi không chứa phần tử

Lỗi này là do có 2 dự án với App_Start / NinjectWebCommon.cs

Xóa tệp sẽ loại bỏ lỗi.

Lưu ý: nếu bạn đang nhận Ninject.Web.Common vì bạn cần tham chiếu hợp ngữ Ninject.Web.Common cho một trong các dự án thư viện lớp của mình, bạn có thể xóa thư mục “App_Start” và “NinjectWebCommon.cs” một cách an toàn. Nó dành cho các dự án web / api web.

> bấm vào đây để xem mục blog gốc <


Sau khi thay đổi Không gian tên của các dự án của tôi, hôm nay tôi lại gặp phải vấn đề tương tự. Tất cả các giải pháp ở đây đã không giúp đỡ. Làm sạch và xây dựng lại không giúp được gì. Nhưng điều đã giúp là xóa các thư mục bin và obj trong dự án của tôi. Có vẻ như vẫn còn mắc kẹt một số phần của phần không gian tên cũ trong đó mà không bị xóa khi dọn dẹp.
Wowe

Chào Da_Wolf, Thats it. Cảm ơn bạn. Bạn đã giải quyết được vấn đề của tôi
VivekDev

2

Giải pháp của tôi là tôi đã đặt thuộc tính thư mục App_Start, Nhà cung cấp không gian tên thành True.

Tôi đã thay đổi điều này thành Sai để Resharper không đánh dấu vùng tên KHÔNG khớp với cấu trúc thư mục.


Đây là nó cho tôi, làm cho tôi phát điên.
rableighp

2

Muốn thêm một nguyên nhân nữa ...

Chúng tôi đã cài đặt gói Ninject.MVC3 cho nhiều dự án - chỉ một trong số đó là ứng dụng MVC thực tế. Tuy nhiên, chúng tôi đã quên xóa thư mục App_Start.

Xóa thư mục App_Start khỏi dự án được tham chiếu đã giải quyết được sự cố.


Vâng! Đây chính là nó! Tôi đã thêm nhầm tệp Ninjectwebcommon.cs thứ hai trên một tệp khác! Đây là nó (Sử dụng MVC 5)
Jose A

1

Để giải quyết câu trả lời của @ Chev ... đây cũng là vấn đề cuối cùng của tôi. Nếu bạn đang triển khai Trang web Azure (hiện có tên là AppSite), bạn muốn nhấp vào hộp này trong xuất bản để xóa các tệp cũ

xuất bản lên ảnh chụp màn hình azure


Đây là hình ảnh giống hệt như tôi đã đăng! Tôi ước tôi đã cuộn xuống câu trả lời này, nhưng những câu trả lời trên dẫn tôi đến ý tưởng này. +1
Jess
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.