ASP.NET Core MVC controllers in separate assembly - asp.net-core-mvc

I'm using ASP.NET MVC Core RC-2. I have a web project targeting the full .NET framework. I also have a separate class library in the solution, also targeting the full framework.
In the class library, I have a controller, marked with a route attribute. I have referenced the class library from the web project. This assembly references the nuget package Microsoft.AspNetCore.Mvc v. 1.0.0-rc2-final.
It was my understanding that this external controller would be discovered automatically, e.g.
http://www.strathweb.com/2015/04/asp-net-mvc-6-discovers-controllers/
However this doesn't work for me- I browse to the URL of the route and I get a blank page and it doesn't hit my controller breakpoint.
Any ideas how to get this working?
Interestingly, it does seem to work for web projects targeting .NET Core Framework, referencing a class library also targeting .NET Core. But not for a web project targeting the full framework, referencing a standard .NET class library.
Note: this is MVC Core which is supposed to support this kind of scenario without any MVC<=4 routing overrides.

Still an issue in ASP.Net Core 1.0, not sure if it's by design now. Easiest solution is to do this in Startup.cs/ConfigureServices
services.AddMvc()
.AddApplicationPart(typeof(<class in external assembly>).Assembly)
.AddControllersAsServices();
AddApplicationPart explicitly includes the assembly in searches for controllers.
The call to AddControllersAsServices() will add all the discovered controllers into the services collection, and if you put a breakpoint after this line and inspect 'services', you will see in the collection all the controller types which have been found.
You might also want to check here: https://docs.asp.net/en/latest/migration/rc1-to-rtm.html#asp-net-5-mvc-compile-views as the discovery rules are now changed for controllers from RC1.
Also remember to use IActionResult instead of ActionResult!

I believe you are hitting the following known issue in RC2.
https://github.com/aspnet/Mvc/issues/4674 (workaround is mentioned in the bug)
This has been fixed since then but will only be available in next release (unless you are ok with using nightly builds)

Related

How to add mediatr in .NET 6?

In .NET Core, we can add it in ConfigureServices method
services.AddMediatR(typeof(Startup));
But in .NET 6, there is only Program.cs. How to add mediatr in .NET 6?
Tried with this code but got build error
builder.Services.AddMediatR(Assembly.GetExecutingAssembly());
Edit (Explanation): The AddMediatR extension method needs an addembly to scan so it can register all the handlers and mediator types. In previous versions of dotnet we used the typeof(Startup) to point to the assembly of our asp project. We can always do the same thing instead of getting the executing assembly by creating an interface in our asp project, which can also be helpful at testing. Just create an empty interface with a meaningful name, for example something like IProjectNameMarker and then you can use typeof(IProjectNameMarker).
The above answer is correct, but you could also do
builder.Services.AddMediatR(typeof(Program));

How on Earth do I reference a class library in both my ASP.NET Core AND Xamarin projects?

I have both a Xamarin Client and Asp Core Web API that need to reference the same project, which will be used as a Portable Class Library. Sounds simple, but I'll take you through my process. The PCL is just a Model so I can use the same classes for transporting JSON between them).
Process:
I create a standard .NET PCL, then attempt to reference it in my Xamarin project. Xamarin is unable to add it since "Portable Library projects can only reference other Portable Library projects". Ok, no worries. I'll create one of those and try it.
I Create a "Class Library (Portable)" dll instead. I configure the project so it matches the same targets (one of them being "ASP.NET Core 1.0") as my Xamarin project, and it imports perfectly. I can use it fine - yay!
Alright, since the "Class Library (Portable)" dll targets ASP.NET Core 1.0, I shouldn't have any issues referencing it in my Web API project. I add it to my project.json...
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dotnet5.6",
"portable-net45+win8"
],
"dependencies": {
"TestClassLibraryPortableDll": {
"target": "project"
}
}
}
},
and all is well. BUT, I can't actually refer to the namespace from within my WebAPI project.
This is as far as I have gotten, after trying so many different things. Standard .NET dll's, ASP.NET Core class libraries, .NET Platform Standard conversions... all sorts.
I feel like I'm missing a very simple but very important step. Any ideas?
My WebAPI will be deployed on Linux, if that helps. Does this mean I have to go with the new netstandard? It seems dodgy at best (and has very little documentation).
I've also posted in the ASP.NET Core forums, and was told this:
If you need to target linux, then you need to target netstandard and
so can only use netstandard libraries. You need to change your model
(MUST be a netstandard library) and add it to the dependencies.
And here's my reply:
Ok, so I create a NetStandard PCL as my Model class. This references
perfectly on my WebAPI project, but not on my Xamarin project.
Error Image.
This happens AFTER I convert my Xamarin project to a netstandard
library, as detailed in this post.
Does anyone have any suggestions? I may just have to have a set of
classes that I can include in each of the projects (or perhaps keep
the models in my WebAPI project, and reference it from my Xamarin, if
possible) just so I can move on and get some work done.

MvvmCross with two core libraries

Is it possible to link two Core libraries into your app?
I would like to create one Common.Core library that has login and account view models.
I would like another one Domain.Core library that has some domain view models in it.
These could be used across a couple different projects.
In my app, I do a new Setup().Initialize().
My Setup class overrides CreateApp() ...
public class Setup : MvxPhoneSetup
{
protected override IMvxApplication CreateApp()
{
CreatableTypes().EndingWith("Service").AsInterfaces().RegisterAsLazySingleton();
return new Common.Core.App();
// TODO: can I setup a Domain.Core library here too?
}
}
I have tried doing this ...
CreatableTypes(Assembly.Load("Domain.Core")).EndingWith("Service").AsInterfaces().RegisterAsLazySingleton();
but I'm getting a ReflectionTypeLoadException when I try to resolve a domain model from there.
Anyone tried something like this?
Thanks!
Yes, using multiple 'core' projects should work.
The ReflectionTypeLoadException occurring on Resolve suggests that maybe your second Assembly requires another Assembly that isn't available? Do you get the same problem with a very simple second core project? Can you get any more information about the exception? Which platform is this occurring on?
If you want to load ViewModel types from multiple assemblies, then there is a Setup method you can override - The default ViewModelLocator in MvvmCross gets its list of ViewModels from the assemblies listed in Setup - see MvxSetup.cs
(Sorry this list is in the ui project - should really be in the main core project)
For cross-platform compatibility, I don't recommend using Assembly.Load - better to use a more static method like typeof(Domain.Core.Something).Assembly
Working on 'packaged application' platforms like xamarin.android and (especially) xamarin.ios I don't recommend using Assembly.Load - this will only work on the iOS platforms if the assembly is referenced statically and has already been loaded - that's the reason plugins have a special bootstrap file on iOS. Also be aware that the name used in Assembly.Load is different on different platforms - eg in Android you must use the filename ending in .dll - see MvxAndroidSetup.cs. For other platforms like WP and winRT, then Assembly.Load may work more conventionally though - although I've personally spent hours/days/weeks swearing at this sort of code in the last year.

MVC-3 Doesn't Find Pre-compiled Views

I have a common MVC3 project which has some views which are compiled into the assembly using RazorGenerator. I've confirmed that the classes show up in the resulting DLL. I've referenced this project from another MVC3 project. When I try to use a view in the common MVC project (the view's namespace is CommonMvcProject.Views.Shared, for instance)...
#{Html.RenderPartial("ViewFromCommonMVCProject");}
...I get an error:
The partial view 'ViewFromCommonMVCProject' was not found or no view engine
supports the searched locations.
I don't want to use the physical views, I want to use the pre-compiled views in the common MVC project's assembly. How can I configure this project to search within the common assembly?
The following post looks like it has the details you need.
http://www.chrisvandesteeg.nl/2010/11/22/embedding-pre-compiled-razor-views-in-your-dll/
Hope that helps.

VS2010 loses Intellisense

I have a solution which has mixed .net framework.
Environment(in solution) : Website 3.5 Framwork
Class Library 2.0 Framwork
another Class Library 3.5 Framwork
I have added another class library with 3.5 framwork to use LINQ to SQL
add new item linq-to-sql and then added reference to website . once I have added this additional classLibrary with linq-to-sql my intellisense is lost. Even it doesn't recongnise txtBox in the markup. I can only include stadard data types like string , int etc..(If I force using Ctrl+spacebar).
Unfortunately there are probably quite a few reasons why this could happen. According to here there is something called "Low-Impact Intellisense" which can be toggled on and off by pressing Ctrl+Alt+Space.

Resources