View not found in MVC4 / ASP.net 4.5 hybrid application - asp.net-mvc-4

Our main site is ASP.net 4.5 and uses Ektron (A .net CMS) I'm attempting to turn it into an MVC4 / Webforms hybrid.
As far as I can tell I have everything MVC4 needs installed correctly but when I try to hit the default Home controller I get the classic
[InvalidOperationException: The view 'Index' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/home/Index.aspx
~/Views/home/Index.ascx
~/Views/Shared/Index.aspx
~/Views/Shared/Index.ascx
~/Views/home/Index.cshtml
~/Views/home/Index.vbhtml
~/Views/Shared/Index.cshtml
~/Views/Shared/Index.vbhtml]
I installed MVC4 using NuGet and by copying over the default controllers, view and associated App_Start and Global.asax files from a default MVC4 application. I also installed WebAPI which is working fine (so that tells me routing does seems to be working correctly, i.e. I can go to API/Values and get the default values api data back just fine).
The site is installed as a main website, i.e. not as a sub site or sub application.
I initially thought maybe there was an issue with the handlers section as Ektron (our CMS) has a ton of handlers it adds but have torn the web.config apart and can't find any problems in there. I even tried replacing it with the one from the default MVC4 application and got the same error.
Note, I did have to change one section the default web.config and in my custom one.
When I have this section in there:
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.1.10.0" newVersion="2.1.10.0" />
</dependentAssembly>
I get the error
Could not load file or assembly 'System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
I looked at the assembly details for that DLL and found it was version 4.0.0.0 so I changed that section to say
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
Which fixes that error and as far as I can tell is OK but again, I'm left with the above problem of the views not being found.
Any help would be greatly appreciated.

OK, I feel dumb.
#SLaks simple question helped me find the answer.
We have a rather complicated build system. It combines the Ektron base code project, which is a web site not a project, with our main project and class libraries into output directories, in this case /debug which is where my IIS is pointing. There's several steps involved, including converting our web project back into a web site during "build" (don't ask, it's a pain but speeds up build times a ton).
Anyway, we only copy certain file types out and .cshtml wasn't in the list, so yeah, no view folder in the output debug directory . . .

Related

Share DLLs between projects

I have multiple projects in my solution. Each project references other projects. The dlls are quite big and I don't want them to be included in the bin of every project that references it.
What are my options? Ideally I'd like to place them in one location and reference that without needing to include them in my bin folder for each project. The only location I can think of is the GAC. Are there any ideas/suggestions on how you have gotten around this?
Is it possible to use probing paths? Anyone used this before/point me to a tutorial?
I've tried probing paths, get an error when running the application, is this not set up correctly? I've placed my dlls I wish to load from this path in the C:\Projects\myProject\bin folder. And set copy to false in the reference
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="C:\Projects\myProject\bin"/>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
</assemblyBinding>
Thanks
I guess what you prefer, is turning off CopyLocal when referencing assemblies in Visual Studio
The steps could be:
Open Solution Explorer
Right click at the reference item (project or assembly)
Select Properties in the context menu.
Set CopyLocal to False (default is true)
Then the references won't be copied to your project\bin\debug or etc.
UPDATE
You still need to copy your dependency to the same folder, or GAC, or probing paths to run your application.
That is how .Net resolve the assemblies references.
You may refer to How the Runtime Locates Assemblies.
UPDATE 1
MSDN Specifying an Assembly's Location
Using the <probing> Element
The runtime locates assemblies that do not have a code base by probing. For more information about probing, see How the Runtime Locates Assemblies.
You can use the element in the application configuration file to specify subdirectories the runtime should search when locating an assembly. The following example shows how to specify directories the runtime should search.
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="bin;bin2\subbin;bin3"/>
</assemblyBinding>
</runtime>
</configuration>
The privatePath attribute contains the directories that the runtime should search for assemblies. If the application is located at C:\Program Files\MyApp, the runtime will look for assemblies that do not specify a code base in C:\Program Files\MyApp\Bin, C:\Program Files\MyApp\Bin2\Subbin, and C:\Program Files\MyApp\Bin3. The directories specified in privatePath must be subdirectories of the application base directory.
You can add referenced libraries to the output folder of start up project only:
1) Right click on starting project, "Add", "Existing Item". Or [Shift]+[Alt]+[A] combination in VS2010 with defaults.
2) Change type selector to "All files (*)", find and select your library.
3) Change "Add" selector to "Add As Link" and press it.
4) Select a link just added to a project, and in Properties window set "Copy to Output Directory" to "Copy always". Now, each time you building the solution, this library will be copied to the output folder of your startup project.
5) If you want to restrict copying this dll to the output of project that uses it, right-click on reference in that project, and in Properties window set "Copy Local" to false.
Implications:
The only place where your referenced dll's will appear will be your start-up project's output directory.
Disadvantages:
If you'll change your start-up project, you'll need to add all the links to it again.
Start-up project directory in Solution Explorer becomes messy.

How do I pull DotNetOpenAuth assembly references into unit test project for ASP.NET MVC4 solution?

Tl;dr version: I am stuck with the exception: System.IO.FileLoadException : Could not load file or assembly 'DotNetOpenAuth.AspNet, Version 4.0.0.0 ...
A bit dismayed that msft used so many static classes and methods for auth in the new MVC4 project template. Want to wrap all membership/auth functionality into a class that implements an interface so that I can mock for unit tests.
After a couple of evenings of struggling, I have decided to start from scratch, so I removed all DotNetOpenAuth* assembly references and nuget package.config references. I have similarly removed all references to Micrsoft.Aspnet.WebPages.OAuth.dll.
Reinstalling packages: I run install-package dotnetopenauth.aspnet against three projects in solution which need the dll references.
Solution will not build, as my wrapper has a method which wraps: Microsoft.AspNet.WebPages.OAuth(.dll).OAuthWebSecurity.RegisteredClientData and therefore I need a reference to this assy, so I run install-package microsoft.aspnet.webpages.oauth against the same three projects.
Solution builds, but when I run the unit test referencing Microsoft.AspNet.WebPages.OAuth(.dll).OAuthWebSecurity.RegisteredClientData I get a runtime exception: System.IO.FileLoadException : Could not load file or assembly 'DotNetOpenAuth.AspNet, Version 4.0.0.0 ...
The references to this assembly in all three projects reference 4.1.0.0, as does the DotNetOpenAuth.AspNet assemblyIdentity in my web.config.
I'm using resharper to run the test, and the tests are nunit style.
And finally here is a paste of what I see in fuslogvw. Obviously something is looking for 4.0.0.0 but I can't figure out what or what to do about it (I have a couple of times deleted the temp data folder referenced in this dump):
***** Assembly Binder Log Entry (11/13/2012 # 10:04:54 PM) ************
The operation failed.
Bind result: hr = 0x80131040. No description available.
Assembly manager loaded from: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\clr.dll
Running under executable C:\Program Files (x86)\JetBrains\ReSharper\v7.0\Bin\JetBrains.ReSharper.TaskRunner.CLR4.MSIL.exe
--- A detailed error log follows.
=== Pre-bind state information ===
LOG: User = i7\dave
LOG: DisplayName = DotNetOpenAuth.AspNet, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246
(Fully-specified)
LOG: Appbase = file:///C:/SVN/trunk/SoAndSo45/SoAndSo.Com.Tests.Unit/bin/Debug
LOG: Initial PrivatePath = NULL
LOG: Dynamic Base = NULL
LOG: Cache Base = C:\Users\dave\AppData\Local\Temp\kpsvgxtp.io4
LOG: AppName = SoAndSo.Com.Tests.Unit
Calling assembly : SoAndSo.Com.Tests.Unit, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null.
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using host configuration file:
LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework64\v4.0.30319\config\machine.config.
LOG: Post-policy reference: DotNetOpenAuth.AspNet, Version=4.0.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246
LOG: GAC Lookup was unsuccessful.
LOG: Attempting download of new URL file:///C:/SVN/trunk/SoAndSo45/SoAndSo.Com.Tests.Unit/bin/Debug/DotNetOpenAuth.AspNet.DLL.
LOG: Assembly download was successful. Attempting setup of file: C:\SVN\trunk\SoAndSo45\SoAndSo.Com.Tests.Unit\bin\Debug\DotNetOpenAuth.AspNet.dll
LOG: Entering download cache setup phase.
LOG: Assembly Name is: DotNetOpenAuth.AspNet, Version=4.1.0.0, Culture=neutral, PublicKeyToken=2780ccd10d57b246
WRN: Comparing the assembly name resulted in the mismatch: Minor Version
ERR: The assembly reference did not match the assembly definition found.
ERR: Setup failed with hr = 0x80131040.
ERR: Failed to complete setup of assembly (hr = 0x80131040). Probing terminated.
Thanks!
I think you should be able to install these as NuGet packages into your unit test project and have them work if you include these binding redirects to your test project's app.config file:
<dependentAssembly>
<assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="2780ccd10d57b246" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="DotNetOpenAuth.Core" publicKeyToken="2780ccd10d57b246" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
</dependentAssembly>
If you have a fresh MVC project and run NuGet's Update-Package command on it, these are automatically created. If you hadn't run that, and installed the NuGet packages fresh into your unit test project, then your unit test project would have references to newer assemblies than your web project did. That would cause the load failure you saw, I think. You just have to make sure that either all your assemblies have common versions across your solution, or that the required binding redirects are in place. And in fact I think the binding redirects are required anyway, since the DotNetOpenAuth assemblies have been updated more recently than the Microsoft.AspNet.WebPages.OAuth package has.
Got some good help from a PM on the ASP.NET team at Msft, who recommended that I copy/reuse the collection of DLLs that are included in the MVC4 project template, which I have done and it's currently working for me.
I copied the DLLs directly to a "non-managed" folder outside of NuGet's purview so that they don't inadvertently get updated unless I really want them to be.
Also worth noting, I had to clean out some references and assy forwarding in web.config to 4.1.0.0, since the MVC4 project template includes 4.0.* of all of the DotNetOpenAuth stuff.

Registration Free Com and dll manifests

I'm trying to setup registration free COM, but have a slight problem in that I another COM object may be the client.
App.exe----->COM Server/Client dll(registered or not)-------->COM Server DLL (NOT Registered)
My questions is, is it possible to create a manifest for the second dll (COM Server/Client dll)? I do not have control of the executable, but if I did, this works if I create a client manifest for the executable and a server manifest for the COM server dll.
this is the manifest file for the middle dll. I tried embedding it and tried it external. Still doesn't work.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32"
name="COMCliSer.dll"
version="1.0.0.0"
/>
<dependency>
<dependentAssembly>
<assemblyIdentity
name="COMSer.dll"
version="1.0.0.0"
/>
</dependentAssembly>
</dependency>
</assembly>
On further investigation, I can get this all to work as long as the middle dll is also registration free and the exe has an application manifest. As soon as I register the middle dll, and drop the application manifest (I do not have control of what exe will use my dll), the whole thing stops working.
If the exe has no manifest, then the dll's manifest is not taken into consideration. I can prove this by setting up everything to work. Then putting a mistake in the assembly manifest. This pops up the usual message :
Unable to create process: This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.
If I then drop the application manifest, the application loads (albeit the CoCreateInstance fails because the dependencies are not taken into consideration)
Just add an assembly dependency to the server/client dll's manifest that points to the com server dll.
Remember that assembly manifests are different to 'application' manifests: An assembly manifest describes an assembly: gives it a name, and lists its dlls.
An application manifest is the RT_MANIFEST embedded resource, which describes the current modules dependencies.
So, in the final analysis, you would have:
app.exe, with an external (app.exe.manifest) or embedded RT_MANIFEST describing a dependency on an assembly called 'acme.clientserver'
acme.clientserver.manifest describing an assembly, and listing 'clisrv.dll' as a registration free com dll.
clisrv.dll, with an external (clisrv.dll.2.manifest) or embedded RT_MANIFEST, describing a dependency on an assembly called 'acme.server'
acme.server.manifest, describing an assembly, listing serv.dll as a registration free com dll.
serv.dll - which may, or may not in turn have a manifest listing yet more dependent assemblies.
It is technically possible to call the assembly by the dll's name, and merge both the assembly and dll manifest together - the win32 loader supports this, but some settings that are valid in application manifests are not valid in assembly manifests, which can cause the resulting assembly to fail to load. It also makes it very hard to digitally sign.
WRT the exe having to have a manifest: Usually the exe's manifest sets up the processes default activation context. I'm not 100% sure how windows behaves when the exe has no manifest, but I'm pretty sure that manifests in dlls will still be processed.
Which means the problem comes down to the lack of isolation support in CoCreateInstance - for some reason - by default - CoCreateInstance only looks in the default activation context for reg free com entries.
The way to override it is to manually build your own activation context, using the Activation Context API
The basic method would be to call:
CreateActCtx - to create an activation context from your dlls manifest.
ActivateActCtx - to activate the context
CoCreateInstance - will now search the current activation context for reg free com entries.
DeactivateActCtx - to restore the default activation context.
You can add /D ISOLATION_AWARE_ENABLED to wrap most windows calls that are effected by activation contexts, for some reason CoCreateInstance is not wrapped :/

How to recompile Sharp Architecture library to use NHIbernate 2.1.0.4000 instead of 2.1.0.3001

I have updated the Sharp Architecture solution (SharpArchitecture_1.0_RTM_build_486) (my local copy) and referenced NHibernate 2.1.0.4000 instead of NHibernate 2.1.0.3001 dll. I have also updated all other NHibernate related references in Sharp Architecture solution.
I was able to rebuild Sharp Architecture and to pass all the tests using the NHibernate version 2.1.0.4000. I have used the provide build script.
When I update the references (NHibernate and recompiled Sharp dlls) in my application and try to initialize NHibernate, the application is throwing "Could not load file or assembly 'NHibernate, Version=2.1.0.3001, Culture=neutral, PublicKeyToken=aa95f207798dfdb4' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)"
This error is thrown in NHibernateSession.Init method. The calling assembly is SharpArch.Data.
Besides recompiling the Sharp Architecture with new dlls, is there something else that needs to be done? The Sharp Architecture is strongly typed against NHibernate 2.1.0.3001.
The reason why I'm doing this is because I want to include NHibernate.Cache in my application. The NHibernate.Cache is compiled against NHibernate 2.1.0.4000 (NHibernate-2.1.0.GA-bin)
Add the following within your web.config file before the opening of the system-web tag.
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="NHibernate" publicKeyToken="AA95F207798DFDB4" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-2.1.0.3001" newVersion="2.1.0.4000"/>
</dependentAssembly>
</runtime>
This should solve the problem.
A similar question has been asked in the s# group and and by Tom Cabanski
There are name changes that need to be made in both the original S#-Arch source, so you'd need to re-build that too (not just your own solution derived built on the framework).
As of writing these changes are not yet in the trunk so might be worth waiting unless you're really desperate?
Try to find and delete all 2.1.0.3001 versions of the DLL from your PC (including versions of the DLL in the GAC) and then recompile / rerun. Hopefully you'll get an error from whatever was trying to reference that version of the DLL and you can update that reference to use the newer 2.1.0.400 version of the DLL.
newVersion="2.1.0.4000" should be newVersion="2.1.1.4000"

How do I reference different DLLs in Kaxaml

I want to work with a DataGrid in Kaxaml. How do I reference the toolkit dll?
Copy WPFToolkit.dll to "C:\Program Files\Kaxaml\"
Restart Kaxaml
Now you can use such namespace:
xmlns:dg="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit"
Another option would be to make a junction and add a probing path to Kaxaml's config.
Make Junction to code
run elevated cmd
cd "c:\Program Files (x86)\Kaxaml"
mklink /J ProbeFolder "c:\path-to-your-code"
Modify Kaxaml.exe.config
run elevated notepad
open "C:\Program Files (x86)\Kaxaml\Kaxaml.exe.config"
add the following to the <configuration>:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<probing privatePath="ProbeFolder"/>
</assemblyBinding>
</runtime>
save the file
restart kaxaml
When mapping custom classes and namespaces in XAML using the clr-namespace/assembly notation, you can't specify the path of the assembly containing the class but just the assembly's name (more details can be found on MSDN), since all referenced assemblies must be linked during the XAML compilation via the project file.
Kaxaml doesn't support the concept of a project since it doesn't do any compilation but rather dynamically parses and renders the XAML entered in the editor "on-the-fly" by using the System.Windows.Markup.XamlReader class.
This means that when using Kaxaml you can only reference classes contained in the assemblies that are part of the .NET Framework.
Building on top of Todd White's solution (& this is future reference for myself too) your XAML in Kaxaml would reference a 3rd party library as follows:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:dxlc="clr-namespace:DevExpress.Xpf.LayoutControl;assembly=DevExpress.Xpf.LayoutControl.v13.2"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- Layout Control Start -->
<dxlc:LayoutControl Orientation="Horizontal">
</dxlc:LayoutControl>
<!-- Layout Control End -->
</UserControl>