AddRazorRuntimeCompilation causing deployment problems - web-deployment

When I try to deploy my project it fails with the following message:-
Startup.cs(75,25): error CS1061: 'IMvcBuilder' does not contain a definition for 'AddRazorRuntimeCompilation'
and no accessible extension method 'AddRazorRuntimeCompilation' accepting a first argument of type 'IMvcBuilder'
could be found (are you missing a using directive or an assembly reference?)
I found an answer here How to fix 'IMvcBuilder' doesn't contain a definition for 'AddXmlDataContractSerializerFormatters' however after installing the suggested MVC formatter package(s) The issue persisted.
The only way I have been able to deploy is to comment out the following lines in my startup class
var builder = services.AddRazorPages();
if (Env.IsDevelopment())
{
builder.AddRazorRuntimeCompilation();
}
Maybe I need to update something on the deployment server? It is the organisation's first DotNet Core 3.1 application

You need to install Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation, but not the latest version. Something compatible with .Net Core 3.x.
E.g.
Package Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation 3.1.19

Related

Why does a force downgrade causes an assembly load exception in .Net Core?

I have a sample solution with a console and library project. Both reference the same nuget but a different version. The console project also has a reference to the library project. So the structure is like this:
- Solution
- ConsoleApp
- Project Reference: Library
- Nuget: NServiceBus.RabbitMQ (5.2.0)
- Library
- Nuget: NServiceBus.RabbitMQ (6.0.0)
You can find the solution here.
Since Nuget uses the nearest wins rule, the nuget package that gets resolved is version 5.2.0. This is what I want, so far so good. But when I run the application and run a method of the Library I get the following exception:
Could not load file or assembly 'NServiceBus.Transport.RabbitMQ, Version=6.0.0.0, Culture=neutral, PublicKeyToken=9fc386479f8a226c'. The located assembly's manifest definition does not match the assembly reference. (0x80131040)
In .NET Framework I would solve this with an assembly redirect. But that isn't available in .Net Core. I always thought that .Net Core solves this automatically by using the deps.json file. There I see the following statement:
"Library/1.0.0": {
"dependencies": {
"NServiceBus.RabbitMQ": "5.2.0"
},
"runtime": {
"Library.dll": {}
}
}
But still at runtime he tries to resolve the 6.0.0 version. I'm using the latest .Dot Net 3.1.X SDK.
I'm I doing something wrong or does this seem like a bug?
For the record, this is a simple sample project. The actual situation where I need this is much more complex. I also do understand that doing this can cause runtime exceptions while running the application.
It appears to be by design.
A little bit of searching, I found this: https://github.com/dotnet/fsharp/issues/3408#issuecomment-319466999
The coreclr will load an assembly of the version or higher than the reference. If the assembly discovered is lower than the reference then it fails.
Also this: https://github.com/dotnet/sdk/issues/384#issuecomment-260457776
downgrading the assembly version isn't supported on .NET Core
So, to confirm, I spent much more time than I intended looking/searching through https://github.com/dotnet/runtime. Eventually I found the assembly version compatibility method: https://github.com/dotnet/runtime/blob/172059af6623d04fa0468ec286ab2c240409abe3/src/coreclr/binder/assemblybindercommon.cpp#L49-L53
It checks all the components of the version separately, but if we look at just one, we can see what it's doing:
if (!pFoundVersion->HasMajor() || pRequestedVersion->GetMajor() > pFoundVersion->GetMajor())
{
// - A specific requested version component does not match an unspecified value for the same component in
// the found version, regardless of lesser-order version components
// - Or, the requested version is greater than the found version
return false;
}
As the comment says, the loader will reject the assembly if the assembly's version is lower than the requested version. In your case, assuming that the assembly version matches the package version (which it doesn't have to), your library is requesting version 6.0.0, but the assembly loader/binder, found version 5.2.0 on disk, which is lower. Hence, it rejects that dll, keeps looking, but then can't find a suitable version of the assembly on the probing path and eventually throws the FileLoadException.
What's not clear to me is if this assembly compatibility is checked only on the default assembly loader, or even if you add your own event handler to AssemblyLoadContext.Default.Resolving. You could try adding your own handler and when it requests the assembly of the higher version, you return the lower version assembly anyway. It might be a way to work around the issue.

Why VS2019 marks my extension as deprecated

I don't use VSIX for integration (supports old VS and SSMS). Installer puts all dlls to "program files" and pkgdef and manifest to specific folders. Currently VS2019 shows message that my extension use "deprecated API".
Image with message from learn.microsoft.com but it's the same.
I done this steps:
I created asyncPackage (now empty).
Added with
Microsoft.VisualStudio.Component.CoreEditor to vsixmanifest
Generated catalog.json and manifest.json using code from here
My package looks so (constructor is empty now)
[PackageRegistration(UseManagedResourcesOnly = true, AllowsBackgroundLoading = true)]
[InstalledProductRegistration("#110", "#112", "7.1.7", IconResourceID = 115)]
[ProvideMenuResource("MyMenus.ctmenu", 1)]
[ProvideAutoLoad(GuidList.ShellInitialized, PackageAutoLoadFlags.BackgroundLoad)]
[ProvideAutoLoad(VSConstants.UICONTEXT.NoSolution_string, PackageAutoLoadFlags.BackgroundLoad)]
[System.Runtime.InteropServices.Guid(GuidList.guidMyPkgString)]
public sealed class MyPackage : AsyncPackage {
But VisualStudio shows message about deprecated API again and again. What I missed? What VS checks during package loading?
Edit: I created AsyncPackage, added attributes, updated integration files to VsixV3. Why VS loads extension synchronously?
For whom this can help to resolve the same issue.
As I mentioned above we don't use VSIX. And all files are coping by installer. The issue was that this was missed:
[$RootKey$\Packages\{YOUR PACKAGE GUID}]
#="YOUR PACKAGE NAME"
"AllowsBackgroundLoad"=dword:00000001
I've found it during checking all packages in private registry privateregistry.bin
Also don't forget about UI Context if you are using it:
[$RootKey$\AutoLoadPackages\$UICONTEXT_GUID}]
"$YOUR_PACKAGE_GUID”= dword:00000002
Thanks to MS git

Using T4 with .NET Core 2.0 and referencing a package from a template

I tried using T4 in a .NET Core 2.0 app project but it seems that T4 doesn't recognize included namespaces. For example, after installing Microsoft.AspNetCore.All package and having the following piece of code:
<## import namespace="Microsoft.Extensions.Configuration" #>
<#+
public class ConfigurationHelper
{
public string ReadConfig(){
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("Configuration\\CodeGenerationConfig.json");
IConfigurationRoot Configuration = builder.Build();
return Configuration["ConnectionString:Server"];
}
}
#>
I got the error:
The type or namespace name 'IConfigurationRoot' could not be found
(are you missing a using directive or an assembly reference?)
Even I tried using assembly directive:
<## assembly name="C:\Program
Files\dotnet\store\x64\netcoreapp2.0\microsoft.extensions.configuration\2.0.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll"
>
But the following error occurred:
System.IO.FileLoadException: Could not load file or assembly
'file:///C:\Program
Files\dotnet\store\x64\netcoreapp2.0\microsoft.extensions.configuration\2.0.0\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll'
or one of its dependencies. Strong name signature could not be
verified. The assembly may have been tampered with, or it was delay
signed but not fully signed with the correct private key. (Exception
from HRESULT: 0x80131045)
So the question is how can I reference a .NET Core package from within a T4 template?
P.S: I tried Scripty, but it doesn't support .NET Core yet.
Update:
The Visual Studio 2017 and Xamarin Studio now supports to process *.tt files in desing time
but https://github.com/ZeekoZhu/TextTemplatingCore may still be useful if you want to process T4 templates in a dotnet core(netstandard2.0)
project outside IDE (eg. in Linux or macOS with Visual Studio Code)

InvalidOperationException: Could not find 'UserSecretsIdAttribute' on assembly

After deploying ASP.NET Core app to azure and opening the site, I get the following error:
InvalidOperationException: Could not find 'UserSecretsIdAttribute' on
assembly '******, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=null'.
The exception details also include that the error happens at Startup.cs on this line of code:
builder.AddUserSecrets();
Thank you
There was an update to the user secrets module just recently. Version 1.0.1 and up now requires you specify an assembly-level attribute for the id of the user secrets, or as a fallback, the way it was previously in project.json.
Here is the announcement on GitHub: https://github.com/aspnet/Announcements/issues/209
You can define the secrets id in the .csproj like this:
<PropertyGroup>
<UserSecretsId>aspnet-TestApp-ce345b64-19cf-4972-b34f-d16f2e7976ed</UserSecretsId>
</PropertyGroup>
This generates the following assembly-level attribute. Alternatively, instead of adding it in the .csproj file, you can of course add it yourself e.g. to Startup.cs:
[assembly: UserSecretsId("aspnet-TestApp-ce345b64-19cf-4972-b34f-d16f2e7976ed")]
Also, you should use:
builder.AddUserSecrets<Startup>();
It will search for that attribute in the assembly of the given type, in this case I used the Startup class.
Note: this will be deprecated in 2.0: (1.0.2 and 1.1.1 have marked it obsolete)
builder.AddUserSecrets();
I checked the source code for the user secrets configuration, and calling AddUserSecrets() without the type does this:
var attribute = entryAssembly.GetCustomAttribute<UserSecretsIdAttribute>();
if (attribute != null)
{
return AddUserSecrets(configuration, attribute.UserSecretsId);
}
// try fallback to project.json for legacy support
try
{
var fileProvider = configuration.GetFileProvider();
return AddSecretsFile(configuration, PathHelper.GetSecretsPath(fileProvider));
}
catch
{ }
// Show the error about missing UserSecretIdAttribute instead an error about missing
// project.json as PJ is going away.
throw MissingAttributeException(entryAssembly);
It's trying to find the UserSecretsId attribute on your assembly, and failing that, checking if it could find it in project.json. Then (as commented) returns an error about the missing attribute as they wouldn't want to complain about project.json anymore as it is being deprecated.
I want to add to this answer, for those in my situation.
I am writing a .NET Core console app, trying to use the secrets manager (not sure it's meant for console apps). The only way I was able to rid myself of the error was using the assembly level attribute on the assembly where I was using the secrets manager.
As I said, I am not sure if the secrets manager is meant for console apps. So maybe there is an issue with .xproj files vs. .csproj files.
My .NET Core 3.1 Worker Service required additional setup (more than a Web project).
In Program.cs in the CreateHostBuilder method I needed this:
.ConfigureAppConfiguration((ctx, builder) =>
{
// enable secrets in development
if (ctx.HostingEnvironment.IsDevelopment())
{
builder.AddUserSecrets<Worker>();
}
})
But (unlike my Web project) I explicitly needed to add this nuget package:
install-package Microsoft.Extensions.Configuration.UserSecrets
After that I could access secrets.

Unable to update database to match the current model. Failing only on self hosting project

The following code:
Database.SetInitializer
(new MigrateDatabaseToLatestVersion<Db, Migrations.Configuration>(true));
using (var C = new Db())
{
Console.WriteLine(C.Usuarios.Count());
}
Works on a console test project but on the other console with self-hosting it fails with the Unable to update database to match the current model... migration error
Obviously the migrations are up to date since the other project runs fine and they both do the same configuration since the database model and the migration configuration are on a separated library
I tracked down the problem to the Newtonsoft.Json library.
The package Microsoft.AspNet.WebApi.Client depends on the version 6.0.4 of this library which seems to have conflicts with Entity Framework.
Just upgrading the Newtonsoft.Json with Install-Package Newtonsoft.Json solves the problem

Resources