У меня проблема с компилированием Razor Views и попыткой передать здесь модель.Итак, это ошибка:
The model item passed into the dictionary is of type 'MvcApplication2.PluginHelloWorld.HelloWorldPluginViewModel', but this dictionary requires a model item of type 'MvcApplication2.PluginHelloWorld.HelloWorldPluginViewModel'
У меня есть файл плагина .cs (метод контроллера):
public class PluginHelloWorldController : PluginController
{
public PluginHelloWorldController(string pluginDirectory) : base(pluginDirectory) { }
[HttpGet]
public ActionResult Index()
{
return RelativeView("index.cshtml", new HelloWorldPluginViewModel());
}
[HttpPost]
public ActionResult Index(HelloWorldPluginViewModel model)
{
return RelativeView("index.cshtml", model);
}
}
И метод контроллера плагина:
public abstract class PluginController : Controller
{
protected string PluginDirectory;
// pluginDirectory will have a value like '~/extensions/plugins/rating/'
public PluginController(string pluginDirectory)
{
if (pluginDirectory.EndsWith("/"))
{
PluginDirectory = pluginDirectory;
}
else
{
PluginDirectory = pluginDirectory + "/";
}
}
public ViewResult RelativeView(string viewName, object model)
{
viewName = PluginDirectory + viewName;
return base.View(viewName, model);
}
}
Итак, у меня есть ошибка:
return base.View(viewName, model);
Я хочу передать Model в этот метод (файл .cs моего просмотра)
public class _Page_index_cshtml : System.Web.Mvc.WebViewPage<MvcApplication2.PluginHelloWorld.HelloWorldPluginViewModel>
{
#line hidden
public _Page_index_cshtml()
{
}
protected System.Web.HttpApplication ApplicationInstance
{
get
{
return ((System.Web.HttpApplication)(Context.ApplicationInstance));
}
}
public override void Execute()
{
WriteLiteral("\r\n<h2>Hello!</h2>\r\n<p>");
Write(Html.TextBox("hello", Model.foo));
WriteLiteral("</p>");
}
}
Я изменил код следующим образом:
public class _Page_index_cshtml : System.Web.Mvc.WebViewPage<dynamic>
{
#line hidden
public _Page_index_cshtml()
{
}
protected System.Web.HttpApplication ApplicationInstance
{
get
{
return ((System.Web.HttpApplication)(Context.ApplicationInstance));
}
}
public override void Execute()
{
var ViewModel = Model as MvcApplication2.PluginHelloWorld.HelloWorldPluginViewModel;
WriteLiteral("\r\n<h2>Hello!</h2>\r\n<p>");
Write(ViewModel.foo);
//Write(Html.TextBox("hello", ViewModel.foo));
WriteLiteral("</p>");
}
}
И теперь тамэто ошибка: Ссылка на объект не установлена на экземпляр объекта.
Итак, я попытался проверить ViewModel и ViewModel.foo на ноль, и это правда.Похоже, проблема с передачей нулевого значения, но почему = \
Итак, это последняя точка перед ошибкой:
[HttpGet]
public ActionResult Index()
{
return RelativeView("index.cshtml", new HelloWorldPluginViewModel());
}
другими словами:
public ViewResult RelativeView(string viewName, object model)
{
viewName = PluginDirectory + viewName;
return base.View(viewName, model);
}
Имодель не равна нулю здесь.
Но когда я проверяю это здесь, в методе Execute:
public class _Page_index_cshtml : System.Web.Mvc.WebViewPage<MvcApplication2.PluginHelloWorld.HelloWorldPluginViewModel>
{
#line hidden
public _Page_index_cshtml()
{
}
protected System.Web.HttpApplication ApplicationInstance
{
get
{
return ((System.Web.HttpApplication)(Context.ApplicationInstance));
}
}
public override void Execute()
{
WriteLiteral("\r\n<h2>Hello!</h2>\r\n<p>");
Write(Html.TextBox("hello", Model.foo));
WriteLiteral("</p>");
}
}
Модель равна нулю ...
Ofc, возможно, он работает с интерфейсом, я еще не пробовал, но в чем проблема с простой передачей объектов = \
Все еще не знаю, где ошибка.Мб, я должен зарегистрировать мою проходящую модель представления здесь:
protected void Application_Start()
{
container = new WindsorContainer();
// register 'normal' controllers
container.Register(AllTypes.FromThisAssembly().BasedOn<IController>().If(t => t.Name.EndsWith("Controller")).Configure((ConfigureDelegate)(c => c.LifeStyle.Transient)));
// string is the route path
// type is the plugin controller type
// it maps routes like '/admin/plugins/rating/{action}' to Crash.PageRating.PageRatingController
Dictionary<string, Type> pluginTypes = new Dictionary<string, Type>();
// location of the plugins
var allPluginsDir = new DirectoryInfo(Server.MapPath("~/extensions/plugins/"));
foreach(var dir in allPluginsDir.GetDirectories())
{
string pluginDir = string.Format("~/extensions/plugins/{0}/", dir.Name);
// loop through all dll files, though only one should exist per directory
foreach(var dll in dir.GetFiles("*.dll"))
{
var assembly = Assembly.LoadFrom(dll.FullName);
// register compiled razor views
// e.g. 'settings.cshtml' is registered as '~/extensions/plugins/rating/settings.cshtml'
BoC.Web.Mvc.PrecompiledViews.ApplicationPartRegistry.Register(assembly, pluginDir);
// only one controller per plugin in this case
var controllerType = assembly.GetTypes().Where(t => typeof(PluginController).IsAssignableFrom(t)).FirstOrDefault();
if(controllerType != null)
{
// register controller
// pass pluginDir to the constructor
container.Register(Component.For(controllerType).DependsOn(new { pluginDirectory = pluginDir }).LifeStyle.Transient);
// admin route url
var pluginUrl = string.Format("plugins/{0}/{{action}}", dir.Name);
// map admin route to controller
pluginTypes.Add(pluginUrl, controllerType);
RouteTable.Routes.MapRoute("plugin_" + dir.Name, pluginUrl, new {controller=controllerType.Name.Replace("Controller",""),action="Index" },new[]{controllerType.Namespace});
}
}
}
AreaRegistration.RegisterAllAreas();
// Controller factory
var controllerFactory = new CrashControllerFactory(container.Kernel,pluginTypes);
ControllerBuilder.Current.SetControllerFactory(controllerFactory);
RegisterRoutes(RouteTable.Routes);
}
Похоже, я должен это сделать, но не знаю как = \
Может кто-нибудь помочь передать модель в скомпилированный Razor View?