Runtime exception when using System.Web.Http.HttpRouteCollectionExtensions.MapHttpRoute - c#

Getting a runtime exception when using MapHttpRoute extension method
Library: Microsoft.AspNet.WebApi (5.2.4), System.Web.Http (5.2.4)
Exception:
System.MissingMethodException
HResult=0x80131513
Message=Method not found: 'System.Web.Http.Routing.IHttpRoute System.Web.Http.HttpRouteCollectionExtensions.MapHttpRoute(System.Web.Http.HttpRouteCollection, System.String, System.String, System.Object, System.Object, System.Net.Http.HttpMessageHandler)'.
Web.config dependent assembly mapping is also present
<dependentAssembly>
<assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.4.0" newVersion="5.2.4.0" />
</dependentAssembly>
I have tried re-installing the Microsoft.AspNet.WebApi library but to no avail.

Related

Project MetadataReferences is not populated when ProjectReferences are present

I'm loading in a solution in the MSBuildWorkspace:
var msWorkspace = MSBuildWorkspace.Create();
var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;
Projects without ProjectReferences show all MetadataReferences, including mscorlib. Projects with ProjectReferences have an empty collection of MetadataReferences.
As compilation works, I guess the compiler platform for some reason is not populating this collection, and I'm wondering why?
If I remove the ProjectReferences, the MetadataReferences collection gets populated correctly.
EDIT: Diagnostics contains errors for missing mscorlib-types like Object and DateTime, so the project seems to not compile because of these missing references.
I finally figured out what was going on by checking the .Diagnostics on MSBuildWorkspace object after attempting to open the solution:
[Failure] Msbuild failed when processing the file 'c:\xxx\someproject.csproj' with message: C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Roslyn\Microsoft.CSharp.Core.targets: (84, 5): The "Csc" task could not be instantiated from the assembly "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\Roslyn\Microsoft.Build.Tasks.CodeAnalysis.dll". Please verify the task assembly has been built using the same version of the Microsoft.Build.Framework assembly as the one installed on your computer and that your host application is not missing a binding redirect for Microsoft.Build.Framework. Unable to cast object of type 'Microsoft.CodeAnalysis.BuildTasks.Csc' to type 'Microsoft.Build.Framework.ITask'.
It seems different versions of MSBuild were being used. Adding assembly redirects (copied from C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\MSBuild\15.0\Bin\MSBuild.exe.config) to my projects app.config solved it:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Framework" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Conversion.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Tasks.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Utilities.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Engine" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Build.Conversion.Core" culture="neutral" publicKeyToken="b03f5f7f11d50a3a" />
<bindingRedirect oldVersion="0.0.0.0-99.9.9.9" newVersion="15.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
All references are now correctly populated on every project in the solution.
I'm on VS2017 15.7.1 and targeting .NET 4.7.1 so no NuGet packages were needed on top of the Microsoft.CodeAnalysis packages (I'm using 2.8.0).

Handling Entity Framework 5 .Include() method when using binding redirection and EF6 dlls

I've got the setup below:
In my AwesomeApp, I use a binding redirect in order to load EF6 when EF
<dependentAssembly>
<assemblyIdentity name="EntityFramework"
publicKeyToken="b77a5c561934e089"
culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
Everything works EXCEPT a EF5 .Include() call - when I invoke that call, I get the following exception:
Is there a workaround here?

Exception could not load assembly Cors

I'm developing a webApi inside my app. I have a strange issue. I tried to do this project inside an independent console application and everything runs well. My problem is when I try to load that web api inside another big application. I'm getting this error:
Could not load file or assembly 'Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
This is the class where I use it:
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll); //HERE IS THE PROBLEM
HttpConfiguration configuration = new HttpConfiguration();
configuration.Routes.MapHttpRoute(
name: "TestApi",
routeTemplate: "test/{controller}/{id}",
defaults: new {id = RouteParameter.Optional}
);
app.UseWebApi(configuration);
}
}
I debugged, and my problem is when I use the app.UserCors(CorsOptions.AllowAll) function. I installed Microsoft CORS package using Nuget package manager and I tried to update it but still getting this error. I searched here Can't load System.Web.Cors assembly after call to Microsoft.Owin.Cors but the solution is not working for me.
I have this app.config file:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.2.0" newVersion="2.0.2.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.2.0" newVersion="3.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Cors" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
</assemblyBinding>
Maybe the problem is in System.Web.Cors? I'm a bit lost.
In your config you say
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.2.0" newVersion="2.0.2.0" />
</dependentAssembly>
that means, that you use Microsoft.Owin version 2.0.2.0
but some of your code (implementation of IAppBuilder i suppose) requres "Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
If you use NuGet, upgrade package, If not - you should download 3.0.1.0 version, update reference and change config file

AutoFixture with NUnit and AutoData throws TargetParameterCountException

In my unit test project I have installed AutoFixture (v3.40.0), NUnit (v2.6.4.) and AutoFixtrue.NUnit2(v3.39.0).
I'm using AutoData attribute on one of the dummy test cases
[Test, AutoData]
public void IntroductoryTest(
int expectedNumber)
{
}
, but when running the test I get the
System.Reflection.TargetParameterCountException : Parameter count mismatch.
at System.Reflection.RuntimeMethodInfo.InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at NUnit.Core.Reflect.InvokeMethod(MethodInfo method, Object fixture, Object[] args)
at NUnit.Core.TestMethod.RunTestMethod()
at NUnit.Core.TestMethod.RunTestCase(TestResult testResult)
Is there anything I haven't installed or I'm missing?
That exception is caused by NUnit not loading the AutoFixture add-in at runtime so the test parameters don't get any arguments.
The reason is that AutoFixture.NUnit2 is compiled against version 2.6.2 so if you want to use it with 2.6.4 you'll have to add the following assembly binding redirects to the configuration file of your test project:
<configuration>
<runtime>
<dependentAssembly>
<assemblyIdentity
name="nunit.core.interfaces"
publicKeyToken="96d09a1eb7f44a77"
culture="neutral" />
<bindingRedirect
oldVersion="0.0.0.0-2.6.4.14350"
newVersion="2.6.4.14350" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity
name="nunit.core"
publicKeyToken="96d09a1eb7f44a77"
culture="neutral" />
<bindingRedirect
oldVersion="0.0.0.0-2.6.4.14350"
newVersion="2.6.4.14350" />
</dependentAssembly>
</runtime>
</configuration>
Note that the version of NUnit you need to redirect to is the one used by the test runner, which could be different than the version used during compilation.
So, while you might be compiling your tests against version 2.6.4, if your test runner uses version 2.6.3, then you need to redirect to 2.6.3 instead:
<configuration>
<runtime>
<dependentAssembly>
<assemblyIdentity
name="nunit.core.interfaces"
publicKeyToken="96d09a1eb7f44a77"
culture="neutral" />
<bindingRedirect
oldVersion="0.0.0.0-2.6.3.13283"
newVersion="2.6.3.13283" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity
name="nunit.core"
publicKeyToken="96d09a1eb7f44a77"
culture="neutral" />
<bindingRedirect
oldVersion="0.0.0.0-2.6.3.13283"
newVersion="2.6.3.13283" />
</dependentAssembly>
</runtime>
</configuration>

Why can I have multiple identical binding redirects in web.config?

Assuming I have one web.config with the following two identical sections:
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30AD4FE6B2A6AEED" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30AD4FE6B2A6AEED" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
Why does this work, and what will happen if someone changes one of the redirects, such as to newVersion="4.0.0.0" instead of newVersion="6.0.0.0"?
If you have more than one binding redirect defined for one assembly, it uses the first one that it found and ignores all others.
So if you change the newVersion of the first one to 4.0.0.0 the runtime will try to load Version 4.0.0.0 of the assembly. The second redirect is ignored.
See also How the Runtime Locates Assemblies. When I understand it correctly it tooks the first element that has the matching assemblyIdentity
The elements are order-sensitive.....In case of a
conflict in redirection, the first matching redirection statement in
the configuration file is used.
Taken from https://msdn.microsoft.com/en-us/library/433ysdt1(v=vs.100).aspx

Categories

Resources