How do you add htmlHelpers into the Spark virew - spark-view-engine

I want to use the htmlHelpers in my spark view but I keep getting the following errors.
error CS0234: The type or namespace name 'Mvc' does not exist in the
namespace 'System.Web' (are you missing an assembly reference?)
I have added the System.Web.Mvc assembly into the project. I have also added the following code into the module (just for the sake of getting it working - I'll probably need to add this code to the bootstrapper --- not sure how to do that yet!)
var settings = new SparkSettings()
.SetDebug(true)
.SetAutomaticEncoding(true)
.AddAssembly("System.Web")
.AddAssembly("System.Web.Mvc")
.AddNamespace("System.Web.Mvc")
.AddNamespace("System.Web.Mvc.Html");
I also tried adding the namespace to a _global.spark file
Can someone tell me exactly what I must do to use the htmlHelpers in my spark view please.

The default Spark base view for Nancy doesn't include the public HtmlHelper Html { get; set; } property.
You can see the default view here.
The Spark view implemented for MVC integration is here, and you'll see the Html property exposed, which allows your Spark view to access it and invoke helpers.
In theory, you can inherit from NancySparkView, and specify that as your base view in your Spark settings, and add that property along with references to System.Web.Mvc etc in that class and your views should then be able to call into the helpers assuming everything is referenced correctly.

I'm not a Nancy expert, but I'm sure the type of the View is different than that of Asp.Net MVC. So, theoretically, you shouldn't be able to use MVC helpers, since they require the Html property on the View.

Related

Type controller does not have a default constructor

Hi friends in webapi using mvc format i created one webapi project here i added autofac resolver to resolve DI(dependency injection) its working fine then in next step i took this dlls and created new project for this i added the dlls now in this project i added one controller but it is showing the error 'x(controller name)' Type controller does not have a default constructor but for this many people given solution for this add new bootstrap class(which contain autofac for di resolve) but i am inherting my old global.asax file from my current global.asax file so i think dont want to add again all the stuff the autofac resolver will get from old dlls so i find many solutions but now luck can any one help me
Note : please ask me incase of any clarity (my english is not good excluse me for this)
The Mistake I did is Spelling mistake this is if Controller name is SampleController i am putting SampleContoller (missing r in Controller splleing) thats it now i corrected splleing now its working fine

Use custom model binder from different assembly and instantiate object from same

I have a class library which includes a custom MVC model binder to instantiate various concrete types which derive from an abstract class. The model binder is almost identical to the one described in this post.
It works fine when using it from within the same Visual Studio Solution that also includes an MVC web application for testing.
My problem is that having created a nuget package from the assembly and included it in a totally separate MVC application the model binder no longer works, despite having configured it correctly in Global.asax.cs.
After some hair pulling I recreated the model binder directly in the separate MVC app, and as I was doing so I noticed that the overridden CreateModel() method in the binder is protected. It now gets executed and I suspect the protected keyword has something to do with it but I would like someone to explain why exactly.
Even with the 'local' modelbinder there are more problems. When it executes, and tries to instantiate the concrete object, I get an exception Could not load type XXXX from assembly { separate MVC project assembly name} so it seems the model binder is unable to load types from outside its own assembly.
Can anyone give me more information on why this happens and what I can do to work around it? Bearing in mind I need the model binder and models to reside in the class library not in the MVC assembly.
I had the same problem as you did, binding to models in a different assembly, but I needed a different solution. I used the same model binding example that you linked to, and I also got the same exception: Could not load type XXXX from assembly
I ended up needing to use the AssemblyQualifiedName for each concrete type. So my views contain this:
#Html.Hidden("ModelType", Model.GetType().AssemblyQualifiedName)
Instead of this:
#Html.Hidden("ModelType", Model.GetType())
I'm still wondering why this was necessary, since the default model binder can load types from the assembly in question.
OK so I was being stupid. It turns out that a few assumptions led me on a wild goose chase.
The ModelBinder was executing correctly to start with. My viewmodel had nested properties which were also abstract base types and required the model binder but I hadn't put the hidden fields in the view to identify their concrete type, nor had I added them to the Global.asax configuration. Once I did this everything started to work as expected.

Http.EnumRouteContraint must implement System.Web.Routing.IRouteConstraint

I'm using AttributeRouting in my Web API project. I've installed the AttributeRouting for Web API. I want to define an Enum route constraint so I setup my AttributeRoutingHttpConfig config as follows:
using System.Reflection;
using System.Web.Http;
using AttributeRouting.Web.Http.Constraints;
using AttributeRouting.Web.Http.WebHost;
using MyProject.Data.Models;
[assembly: WebActivator.PreApplicationStartMethod(typeof(PhantasyTour.AttributeRoutingHttpConfig), "Start")]
namespace MyProject
{
public static class AttributeRoutingHttpConfig
{
public static void RegisterRoutes(HttpRouteCollection routes)
{
routes.MapHttpAttributeRoutes(
config =>
{
config.AddRoutesFromAssembly(Assembly.GetExecutingAssembly());
config.InlineRouteConstraints.Add("ListType", typeof(EnumRouteConstraint<ListType>));
});
}
public static void Start()
{
RegisterRoutes(GlobalConfiguration.Configuration.Routes);
}
}
}
When I fire up my application I immediately receive the following error:
The constraint "AttributeRouting.Web.Http.Constraints.EnumRouteConstraint`1[[MyProject.Data.Models.ListType, MyProject.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" must implement System.Web.Routing.IRouteConstraint
I've looked at the source code for the AttributeRouting.Web.Http.Constraints.EnumRouteConstraint and confirmed that it implements IHttpRouteConstraint which presumably is the WebAPI equivalent of IRouteConstraint in the MVC namespace.
Does anyone know what I'm doing wrong and how I can get this working?
UPDATE:
I attempted to create a completely blank Web Application and add only WebAPI and AttributeRouting for WebAPI references. Despite having absolutely no references to MVC assemblies, I still receive the same error message. I did discover however that there is another EnumRouteConstraint found in the AttributeRouting.Web.Constraints namespace which works perfectly. It doesn't appear to be MVC specific since it is located in the Core AttributeRouting assembly. I would love to know why there are two different EnumRouteConstraint classes when only one of them works. But that is a question for another time.
It is interesting that the exception you get refers to the MVC interface from the namespace System.Web.Routing.
I would take it as a clue and look at all the references in your project, any place in the config where MVC Routes and Http Routes could have been mixed up.
If possible and if you have any at all, try removing all references to MVC (or System.Web.Routing for a start), and MVC flavour of attribute routing (if it's a separate dll).

MEF and MVC 3 - how to load embedded views dynamically from mef container?

I'm building an MVC 3 application where MEF is used. The main idea is to have plug-in mechanism where models, controllers and views are loaded dynamically during runtime from mef container.
Each plugin/module consists of two assemblies:
Module1.Data.dll (contains definitions of models)
Module1.Web.dll (contains controllers and views)
and are put in the Plugins directory inside web application bin:
WebApp/Bin/Plugins/Module1.Data.dll
WebApp/Bin/Plugins/Module1.Web.dll
WebApp/Bin/Plugins/Module2.Data.dll
WebApp/Bin/Plugins/Module2.Web.dll
WebApp/Bin/Plugins/ModuleCore.Data.dll
WebApp/Bin/Plugins/ModuleCore.Web.dll
etc...
There is also core module that is referenced by all other modules: ModuleCore.Data.dll and respectively ModuleCore.Web.dll.
Then, in Global.asax, container is build in the following way:
AggregateCatalog catalog = new AggregateCatalog();
var binCatalog = new DirectoryCatalog(HttpRuntime.BinDirectory, "Module*.dll");
var pluginsCatalot = new DirectoryCatalog(Path.Combine(HttpRuntime.BinDirectory, "Plugins"), "Module*.dll");
catalog.Catalogs.Add(binCatalog);
catalog.Catalogs.Add(pluginsCatalot);
CompositionContainer container = new CompositionContainer(catalog);
container.ComposeParts(this);
AppDomain.CurrentDomain.AppendPrivatePath(Path.Combine(HttpRuntime.BinDirectory, "Plugins"));
CustomViewEngine is created and registered and used for finding views in module assembly:
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomViewEngine());
controller factory for loading controllers from container:
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory(_container));
and also custom virtual path provider for getting assemblies from container:
HostingEnvironment.RegisterVirtualPathProvider(new ModuleVirtualPathProvider());
Ok, so the whole infrastructure for handling pluggable models, controllers and views are ready. Now everything works... except one thing - strongly typed views.
To ilustrate the problem in more details, let's prepare the scene:
UserDTO model is located in Module1.Data.dll
ShowUserController.cs is located in Module1.Web.dll/Controllers/
Index.cshtml is located in Module1.Web.dll/Views/ShowUser (with declared #model Module1.Data.UserDto)
Now we do the following:
Run the application and go to HOST/ShowUser/Index (action method Index is executed on ShowUserController and view Index.cshtml is fetched)
After the view Index.cshtml is fetched - compilation starts (by RazorBuildProvider)
Exceptions is thrown: "cannot find Data type in namespace Module1", in other words UserDTO couldn't be found during building the view dynamically
So it seems that compiler/builder didnt look through bin/Plugins folder for Module1.Data.dll, because when I copied this file into bin folder - it worded fine.
Question/problem: why builder didn't look into bin/Plugins folder even though this directory was added by AppDomain.CurrentDomain.AppendPrivatePath method?
How to add private paths for assembly builder once so that plugins folder will be taken into consideration??
I have managed to do some work around by creating CustomRazorBuildProvider that overrides standard one:
public class CustomRazorBuildProvider : RazorBuildProvider
{
public override void GenerateCode(System.Web.Compilation.AssemblyBuilder assemblyBuilder)
{
Assembly a = Assembly.LoadFrom(Path.Combine(HttpRuntime.BinDirectory, "Plugins", "Module1.Data.dll"));
assemblyBuilder.AddAssemblyReference(a);
base.GenerateCode(assemblyBuilder);
}
}
but the drawback of this solution is that everytime the view is compiled, references to all assemblies in Plugins folder need to be added, which can cause performance issues later on when lots of plugins will be used.
Any nicer solutions?
Here is a thought.
If you follow the View Model Pattern then instead of sending the DTO's straight to the view use a ViewModel that is would be located in the same assembly as the View.
So Instead of:
UserDTO model is located in Module1.Data.dll
ShowUserController.cs is located in Module1.Web.dll/Controllers/
Index.cshtml is located in Module1.Web.dll/Views/ShowUser (with declared #model Module1.Data.UserDto)
You would have:
UserDTO model is located in Module1.Data.dll
ShowUserController.cs is located in Module1.Web.dll/Controllers/
UserVM located in Module1.Web.dll/ViewModels
Index.cshtml is located in Module1.Web.dll/Views/ShowUser (with declared #model Module1.Web.ViewModels.UserVM)
Have the Controller Map your DTO's to ViewModels
See AutoMapper to help with the Mapping

how to register all classes in assembly with Castle Windsor in MVC 3

I'm starting with ASP.NET MVC 3 and modules.
Like the Orchard CMS modules, I want to have modules as assemblies with Razor pages (inside/outside the DLL). I followed Mika Kolari's tutorial, but I don't know how to include all the classes from the assembly namespace in the core project with Castle Windsor.
I'm able to load Controller from the assembly, but not Model for the view. I get missing namespace error.
In Application_start() I have:
var assembly = Assembly.LoadFrom(dll.FullName);
//different from Mika's
container.Register(AllTypes.FromAssembly(assembly)
.Where(t => t.Name.EndsWith("Model")));
and Settings.cshtml file invoking the error:
#{
Layout = ";~/Views/Shared/_Layout.cshtml";
var viewModel = Model as Crash.PageRating.SettingsViewModel; //error missing namespace Crash.PageRating
}
Mika says that #model does not work for him either.
Here is my solution
Thanks for help!

Resources