{"id":58,"date":"2018-12-12T15:13:41","date_gmt":"2018-12-12T14:13:41","guid":{"rendered":"https:\/\/wissing.me\/daan\/blog\/?p=58"},"modified":"2018-12-12T15:13:41","modified_gmt":"2018-12-12T14:13:41","slug":"upgrading-to-net-core-part-3-using-net-standard-in-an-existing-net-framework-project","status":"publish","type":"post","link":"https:\/\/daan.wsng.eu\/index.php\/2018\/12\/12\/upgrading-to-net-core-part-3-using-net-standard-in-an-existing-net-framework-project\/","title":{"rendered":"Upgrading to .NET Core (part 3): Using .NET Standard in an existing .NET Framework project"},"content":{"rendered":"<p>So, you&#8217;ve got .NET Core, .NET Standard and .NET Framework. Microsoft, when developing all this, had the brilliant idea to create a set of APIs that should be available on both Framework and Core. A Standard set, if you will. Thus, .NET Standard was born. Libraries targeting this &#8220;platform&#8221; (which technically is not really a platform) will be available on both .NET Core and .NET Framework. Therefore, whenever you can target .NET Standard when developing a library, you should do so.<\/p>\n<p>That was the start for me when upgrading our systems to .NET Core: take the internal libraries, transform them to .NET Standard, and tadaa, they can be used immediately in the projects already there. Just put them in your local NuGet server, make sure it references the right packages, and everything solves itself.<\/p>\n<p>Except when it doesn&#8217;t.<\/p>\n<h2>MissingMethodException!<\/h2>\n<p>I got the strangest error while updating a newly migrated library in my project to the .NET Standard version in a WebApi project. As expected, some extra dependencies came in that were not necessary first (e.g. System.ComponentModel.Annotations). All was installed and built correctly, but when running and trying to open the Swagger UI page, the following error popped up:<\/p>\n<pre>System.MissingMethodException: 'Method not found: 'System.String\r\nSwashbuckle.Application.SwaggerDocsConfig.DefaultRootUrlResolver(System.Net.Http.HttpRequestMessage)'.'<\/pre>\n<p>Nice. A quick search around the internet found me <a href=\"https:\/\/github.com\/dotnet\/standard\/issues\/613\">this github issue<\/a>. Cool, so<\/p>\n<ul>\n<li>Go to the Error List window in Visual Studio.<\/li>\n<li>Find a warning looking like &#8220;Found conflict between different versions of the same dependent assembly.&#8221;.<\/li>\n<li>Double-click the warning. This will show a dialog asking to automatically generate binding redirects.<\/li>\n<li>Click &#8220;OK&#8221; to add the binding redirects to your web.config file.<\/li>\n<li>Now you can run again!<\/li>\n<\/ul>\n<h2>Test projects<\/h2>\n<p>So I was happily updating all references to this package to the version with .NET Standard, expecting all to be good. But no, I got a problem on&#8230; my test projects. All tests that actually touch the controllers fail with an exception. Again, the <code>System.MissingMethodException<\/code>. But when I went looking for the warning message in the Error List, I couldn&#8217;t find any. How weird. So, back to the internet it was, where I came upon <a href=\"https:\/\/github.com\/Microsoft\/msbuild\/issues\/1310\">this github issue<\/a>. Apparently, the trick with automatically generate binding redirects doesn&#8217;t work on Library projects, and of course test projects are library projects.<\/p>\n<p>To make those run as well, do the following:<\/p>\n<ul>\n<li>In Visual Studio, &#8220;unload&#8221; the project (or open the project file in a different text editor).<\/li>\n<li>Find the first <code>&lt;PropertyGroup&gt;<\/code> tag.<\/li>\n<li>Insert the following line of XML at the end of the tag:<\/li>\n<\/ul>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;AutoGenerateBindingRedirects&gt;true&lt;\/AutoGenerateBindingRedirects&gt;\r\n<\/pre>\n<ul>\n<li>Go to the end of the file where a bunch of <code>&lt;Target&gt;<\/code> tags are defined.<\/li>\n<li>Insert the following <code>&lt;Target&gt;<\/code> tag:<\/li>\n<\/ul>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;Target Name=&quot;ForceGenerationOfBindingRedirects&quot;\r\n        AfterTargets=&quot;ResolveAssemblyReferences&quot;\r\n        BeforeTargets=&quot;GenerateBindingRedirects&quot;\r\n        Condition=&quot;'$(AutoGenerateBindingRedirects)' == 'true'&quot;&gt;\r\n  &lt;PropertyGroup&gt;\r\n    &lt;!-- Needs to be set in a target because it has to be set after the initial evaluation in the common targets --&gt;\r\n    &lt;GenerateBindingRedirectsOutputType&gt;true&lt;\/GenerateBindingRedirectsOutputType&gt;\r\n  &lt;\/PropertyGroup&gt;\r\n&lt;\/Target&gt;\r\n<\/pre>\n<ul>\n<li>Open\/load the project again in Visual Studio and rebuild.<\/li>\n<li>The redirects are generated automatically<\/li>\n<\/ul>\n<p>All tests were green! So, while using .NET Standard is a great way for gradually migrating your projects, some work still needs to be done before everything works in your .NET Framework projects.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>So, you&#8217;ve got .NET Core, .NET Standard and .NET Framework. Microsoft, when developing all this, had the brilliant idea to create a set of APIs that should be available on both Framework and Core. A Standard set, if you will. Thus, .NET Standard was born. Libraries targeting this &#8220;platform&#8221; (which technically is not really a&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"twitterCardType":"","cardImageID":0,"cardImage":"","cardTitle":"","cardDesc":"","cardImageAlt":"","cardPlayer":"","cardPlayerWidth":0,"cardPlayerHeight":0,"cardPlayerStream":"","cardPlayerCodec":""},"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/posts\/58"}],"collection":[{"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/comments?post=58"}],"version-history":[{"count":9,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/posts\/58\/revisions"}],"predecessor-version":[{"id":67,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/posts\/58\/revisions\/67"}],"wp:attachment":[{"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/media?parent=58"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/categories?post=58"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daan.wsng.eu\/index.php\/wp-json\/wp\/v2\/tags?post=58"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}