基于自定义视图引擎加载类库MVC组件时遇索引参数错误
Hey there! Let's sort out that frustrating MVC index error you're running into when trying to load views and controllers from a class library using a custom view engine. I’ve dealt with this exact issue before, so here’s a step-by-step breakdown of what’s going wrong and how to fix it:
1. Check Your Custom View Engine's View Path Formatting
This error almost always pops up when you’re using string.Format() in your view engine’s FindView or FindPartialView methods, and the number of placeholders in your template doesn’t match the number of parameters you’re passing. For example, if you write something like string.Format("~/Views/{0}/{1}.cshtml", controllerName), you’ve got two {0}/{1} placeholders but only one parameter—boom, index out of bounds.
Fix it like this:
Make sure your template and parameter count align perfectly. Here’s a corrected version of the FindView method:
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache) { var controllerName = controllerContext.RouteData.Values["controller"].ToString(); // Correct: 2 placeholders, 2 parameters (controllerName + viewName) var viewPath = string.Format("~/YourClassLibrary/Views/{0}/{1}.cshtml", controllerName, viewName); if (FileExists(controllerContext, viewPath)) { return new ViewEngineResult(CreateView(controllerContext, viewPath, masterName), this); } // Fall back to the default view engine if we can't find the custom view return base.FindView(controllerContext, viewName, masterName, useCache); }
2. Ensure Class Library Views Are Set as Embedded Resources
MVC can’t access views in a class library unless you mark them as embedded resources. Here’s how to do it:
- Right-click each
.cshtmlfile in your class library’s Views folder - Go to Properties
- Set Build Action to
Embedded Resource
You’ll also need to update your view engine to read these embedded resources instead of looking for physical files. Here’s how to adjust the FileExists and CreateView methods:
protected override bool FileExists(ControllerContext controllerContext, string virtualPath) { // Convert the view path to an embedded resource name (e.g., YourLibrary.Views.Home.Index.cshtml) var resourceName = $"YourClassLibraryNamespace{virtualPath.Replace("~/", ".").Replace("/", ".")}.cshtml"; return Assembly.Load("YourClassLibrary").GetManifestResourceInfo(resourceName) != null; } protected override IView CreateView(ControllerContext controllerContext, string viewPath, string masterPath) { var resourceName = $"YourClassLibraryNamespace{viewPath.Replace("~/", ".").Replace("/", ".")}.cshtml"; var resourceStream = Assembly.Load("YourClassLibrary").GetManifestResourceStream(resourceName); return new RazorView(controllerContext, viewPath, masterPath, false, null); }
3. Register Class Library Controllers in Your MVC Project
MVC won’t automatically pick up controllers from a class library unless you tell it to. Add this code to your MVC project’s Global.asax.cs (in Application_Start()) or Startup.cs (if using MVC 5+):
// Register the class library's controller namespace ControllerBuilder.Current.DefaultNamespaces.Add("YourClassLibrary.Controllers"); // If you have multiple sub-namespaces, use this instead: // ControllerBuilder.Current.DefaultNamespaces.Add("YourClassLibrary.Controllers.*");
4. Verify View Namespace References
Make sure your class library’s views have the correct namespace references at the top. If your view uses models or helpers from the class library, missing references can cause indirect parsing errors:
@using YourClassLibrary.Models @using System.Web.Mvc
5. Debug Parameter Values in Your View Engine
Add breakpoints to your custom view engine’s methods to check if viewName, controllerName, or other parameters are empty or malformed. For example, if controllerName is null when you try to pass it to string.Format(), that’ll trigger the index error too.
Once you work through these steps, that index out of bounds error should disappear. The root cause is almost always a mismatch between placeholder count and parameters in your view path formatting, or missing setup for embedded resources.
内容的提问来源于stack exchange,提问作者Dhanuka777

