Nswag client generator tries to generate when azure secrets are added - c#

In the project I am involved with now, we are using dotnet-nswag.dll to generate a typescript api client. I am now trying to switch from using local secrets to secrets stored in azure key vault (I hope to simplify new developers' entry to the project). I however bumped into a problem, that when I use something like below:
builder.ConfigureAppConfiguration((ctx, cfg) =>
{
if (ctx.HostingEnvironment.IsDevelopment())
{
var keyVaultEndpoint = new Uri(Environment.GetEnvironmentVariable("DevEnv_KVUri"));
cfg.AddAzureKeyVault(keyVaultEndpoint, new DefaultAzureCredential());
}
});
I no longer can generate the nswag typescript api client. My investigation led me to the discovery that nswag fails becasue DevEnd_KVUri does not exists at the generation time. I have this env var added in my launchSettigns.json and it is available when I test my app. However, I would like to instruct nswag not to try to include whatever is triggering it to also go through that key vault endpoint.
If I hard-code the url (and it is a KeyVault url that I have access to), then the generation passes. Generated client does not have any endpoints pointing to my hard-coded url. However I do not like the solution, where I have to hard-code (not even fake but a working one) my key vault address.
Unfortunately, I did not find any solution to my problem.
Edit 1:
The command that executes generation:
dotnet "C:\Users\myname\.nuget\packages\nswag.msbuild\13.16.0\build\../tools/Net50/dotnet-nswag.dll" run nswag.json /variables:Configuration=Debug`
The exception thrown by the generator when no url is provided
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.ArgumentNullException: Value cannot be null. (Parameter 'uriString')
at System.Uri..ctor(String uriString)
at Lib.KeyVault.Extensions.IWebHostBuilderExtensions.<>c.<UseKeyVault>b__0_1(HostBuilderContext ctx, IConfigurationBuilder bld) in C:\dotnet\net\lib\Lib.KeyVault.Extensions\IWebHostBuilderExtensions.cs:line 50
at Microsoft.Extensions.Hosting.HostBuilder.BuildAppConfiguration()
at Microsoft.Extensions.Hosting.HostBuilder.Build()
at NSwag.Commands.ServiceProviderResolver.GetServiceProvider(Assembly assembly) in /_/src/NSwag.Commands/HostApplication.cs:line 61
at NSwag.Commands.Generation.AspNetCore.AspNetCoreToOpenApiGeneratorCommandEntryPoint.Process(String commandContent, String outputFile, String applicationName) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/AspNetCoreToOpenApiGeneratorCommandEntryPoint.cs:line 27
--- End of inner exception stack trace ---
at System.RuntimeMethodHandle.InvokeMethod(Object target, Span`1& arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at NSwag.AspNetCore.Launcher.Program.Main(String[] args) in /_/src/NSwag.AspNetCore.Launcher/Program.cs:line 132
System.InvalidOperationException: Swagger generation failed with non-zero exit code '1'.
at NSwag.Commands.Generation.AspNetCore.AspNetCoreToSwaggerCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Generation/AspNetCore/AspNetCoreToOpenApiCommand.cs:line 231
at NSwag.Commands.NSwagDocumentBase.GenerateSwaggerDocumentAsync() in /_/src/NSwag.Commands/NSwagDocumentBase.cs:line 275
at NSwag.Commands.NSwagDocument.ExecuteAsync() in /_/src/NSwag.Commands/NSwagDocument.cs:line 81
at NSwag.Commands.Document.ExecuteDocumentCommand.ExecuteDocumentAsync(IConsoleHost host, String filePath) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 85
at NSwag.Commands.Document.ExecuteDocumentCommand.RunAsync(CommandLineProcessor processor, IConsoleHost host) in /_/src/NSwag.Commands/Commands/Document/ExecuteDocumentCommand.cs:line 32
at NConsole.CommandLineProcessor.ProcessSingleAsync(String[] args, Object input)
at NConsole.CommandLineProcessor.ProcessAsync(String[] args, Object input)
at NSwag.Commands.NSwagCommandProcessor.ProcessAsync(String[] args) in /_/src/NSwag.Commands/NSwagCommandProcessor.cs:line 61

Related

PlatformNotSupportedException thrown in MAUI on macOS when connecting Azure IoT Hub

I am exploring MAUI on macOS. I am porting a WPF application to evaluate the functionalities. The application is connecting to an Azure IoT Hub instance.
Here is the section of code that seems problematic:
var iotHubConnectionStringBuilder = IotHubConnectionStringBuilder.Create("HostName=<iotHubConnectionString>");
var registryManager = RegistryManager.CreateFromConnectionString(iotHubConnectionStringBuilder.ToString());
When calling CreateFromConnectionString, the following exception is thrown:
Unhandled Exception:
System.PlatformNotSupportedException: Operation is not supported on this platform.
at System.Net.Http.NSUrlSessionHandler.set_SslProtocols(SslProtocols value)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
--- End of stack trace from previous location ---
at System.Net.Http.HttpClientHandler.InvokeNativeHandlerMethod(String name, Object[] parameters)
at System.Net.Http.HttpClientHandler.SetSslProtocols(SslProtocols value)
at System.Net.Http.HttpClientHandler.set_SslProtocols(SslProtocols value)
at Microsoft.Azure.Devices.Client.Transport.HttpClientHelper..ctor(Uri baseAddress, IAuthorizationProvider authenticationHeaderProvider, IDictionary`2 defaultErrorMapping, TimeSpan timeout, Action`1 preRequestActionForAllRequests, X509Certificate2 clientCert, HttpClientHandler httpClientHandler, ProductInfo productInfo, IWebProxy proxy, Boolean isClientPrimaryTransportHandler)
at Microsoft.Azure.Devices.Client.Transport.HttpTransportHandler..ctor(IPipelineContext context, IotHubConnectionString iotHubConnectionString, Http1TransportSettings transportSettings, HttpClientHandler httpClientHandler, Boolean isClientPrimaryTransportHandler)
at Microsoft.Azure.Devices.Client.InternalClient..ctor(IotHubConnectionString iotHubConnectionString, ITransportSettings[] transportSettings, IDeviceClientPipelineBuilder pipelineBuilder, ClientOptions options)
at Microsoft.Azure.Devices.Client.ClientFactory.CreateFromConnectionString(String connectionString, IAuthenticationMethod authenticationMethod, ITransportSettings[] transportSettings, IDeviceClientPipelineBuilder pipelineBuilder, ClientOptions options)
at Microsoft.Azure.Devices.Client.ClientFactory.CreateFromConnectionString(String connectionString, IAuthenticationMethod authenticationMethod, TransportType transportType, IDeviceClientPipelineBuilder pipelineBuilder, ClientOptions options)
at Microsoft.Azure.Devices.Client.ClientFactory.CreateFromConnectionString(String connectionString, TransportType transportType, ClientOptions options)
at Microsoft.Azure.Devices.Client.ClientFactory.CreateFromConnectionString(String connectionString, ClientOptions options)
at Microsoft.Azure.Devices.Client.DeviceClient.<>c__DisplayClass8_0.<CreateFromConnectionString>b__0()
at Microsoft.Azure.Devices.Client.DeviceClient.Create(Func`1 internalClientCreator)
at Microsoft.Azure.Devices.Client.DeviceClient.CreateFromConnectionString(String connectionString, ClientOptions options)
[..]
I have played with the different HttpClient implementation without any positive outcome. And, surprinsingly enough, it exhibits the same callstack, with NSUrlSessionHandler.set_SslProtocols on top of it:
Question
Why is this error thrown and how can it be fixed?
I was using Visual Studio 2022 for Mac version 17.3 Preview 1. After updating to Visual Studio 2022 for Mac v17.3 Preview 1.1 as well as the .net MAUI workload, it worked.
I let the HttpClient implementation to NSUrlSession.
I am not sure the exact reason why it works now but I assume these issues are bound to happen when using preview products.

Memory Leak with EF Core Logging

I have a small Digital Ocean droplet (1GB of RAM) running the most current Ubuntu LTS. I created a small DotNet core 3.1 MVC web app (+ DotNet Core identity) that eventually hits a task limit and then throws (erroneous) OOM exceptions.
Representative Error messages from journalctl:
Microsoft.AspNetCore.Server.Kestrel[13] Connection id "0HM1CRI33JJJE", Request id "0HM1CRI33JJJE:0000043E": An unhandled exception was thrown by the application. System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at System.Threading.Thread.StartInternal()
at Microsoft.Extensions.Logging.Console.ConsoleLoggerProvider..ctor(IOptionsMonitor`1 options)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor, Boolean wrapExceptions)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at ... (etc)
Service status on fresh start:
Site.service - Description here
Loaded: loaded (/etc/systemd/system/Site.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-07-22 17:08:51 UTC; 48s ago
Main PID: 656469 (Site)
Tasks: 21 (limit: 1075)
Memory: 103.4M
CGroup: /system.slice/Site.service
Status output with problem active:
Site.service - Description here
Loaded: loaded (/etc/systemd/system/Site.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2020-07-22 17:08:51 UTC; 11min ago
Main PID: 656469 (Site)
Tasks: 1075 (limit: 1075)
Memory: 176.1M
CGroup: /system.slice/Site.service
As indicated in the EF Core logging documentation, a memory leak can be introduced if a new logging factory is created for each context.
Bad code:
options.UseSqlite(SqliteDbContext.DataSource)
.UseLoggerFactory(LoggerFactory.Create(x => x.AddConsole())); // log SQL to console
Correct code:
options.UseSqlite(SqliteDbContext.DataSource)
.UseLoggerFactory(_loggerFactory) // _loggerFactory is now a static property
Added on behalf of the question author.
from https://learn.microsoft.com/en-us/ef/core/logging-events-diagnostics/extensions-logging?tabs=v3
public static readonly ILoggerFactory MyLoggerFactory
= LoggerFactory.Create(builder => { builder.AddConsole(); });
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLoggerFactory(MyLoggerFactory)
.UseSqlServer(#"Server=(localdb)\mssqllocaldb;Database=EFLogging;ConnectRetryCount=0");

Simple Injector - difficulty with ASP.NET 5 Identity and RavenDB

I am attempting to use SimpleInjector with ASP.NET 5 on an MVC application, and am running into a major problem getting it wired up right.
I run a RavenDB database, and as such I have methods for instantiating instances to it, which is what I use when registering the interfaces, like this;
private void InitializeContainer(IApplicationBuilder app) {
container.CrossWire<IUserStore<AppUser>>(app);
container.CrossWire<UserManager<AppUser>>(app);
container.CrossWire<SignInManager<AppUser>>(app);
container.CrossWire<ILoggerFactory>(app);
container.Register<IDocumentStore>(RavenDatabase.OpenDatabase);
container.Register<IDocumentSession>(RavenDatabase.OpenSession);
container.Register<IAsyncDocumentSession>(RavenDatabase.OpenAsyncSession);
container.Register<ILookupNormalizer>(() => new LowerInvariantLookupNormalizer());
container.Register<IPasswordHasher<AppUser>>(() => new PasswordHasher<AppUser>());
}
The problem seems to be with IUserStore. When I try to load up the application, I get this exception..
Unable to resolve service for type 'Raven.Client.IAsyncDocumentSession' while attempting to activate 'App.Identity.UserStore`1[App.Identity.AppUser]'.
I'm really uncertain why this is, though. I've registered IAsyncDocumentSession, so why can't it inject it? I've also tried it like this...
container.Register<IUserStore<AppUser>>(RavenDatabase.UserStore);
With a method defined as such...
public static UserStore<AppUser> UserStore() {
// check to see if we even have a session factory to get a session from
if (documentStore == null)
OpenDatabase();
return new UserStore<AppUser>(documentStore.OpenAsyncSession());
}
But I still continue to get the exception. I'm at a loss, here. This is my first time using Simple Injector.
Stack Trace
System.InvalidOperationException
Unable to resolve service for type 'Raven.Client.IAsyncDocumentSession' while attempting to activate 'App.Identity.UserStore`1[App.Identity.AppUser]'.
at Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet<Type> callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.CreateCallSite(ServiceProvider provider, ISet<Type> callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetResolveCallSite(IService service, ISet<Type> callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetServiceCallSite(Type serviceType, ISet<Type> callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.PopulateCallSites(ServiceProvider provider, ISet<Type> callSiteChain, ParameterInfo[] parameters, Boolean throwIfCallSiteNotFound)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.Service.CreateCallSite(ServiceProvider provider, ISet<Type> callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetResolveCallSite(IService service, ISet<Type> callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetServiceCallSite(Type serviceType, ISet<Type> callSiteChain)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.CreateServiceAccessor(Type serviceType, ServiceProvider serviceProvider)
at System.Collections.Concurrent.ConcurrentDictionaryExtensions.GetOrAdd<TKey, TValue, TArg>(ConcurrentDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TArg, TValue> valueFactory, TArg arg)
at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderExtensions.GetRequiredService<T>(IServiceProvider provider)
.lambda_method(Closure )
at SimpleInjector.InstanceProducer.BuildAndReplaceInstanceCreatorAndCreateFirstInstance()
at SimpleInjector.InstanceProducer.GetInstance()
SimpleInjector.ActivationException
Unable to resolve service for type 'Raven.Client.IAsyncDocumentSession' while attempting to activate 'App.Identity.UserStore`1[App.Identity.AppUser]'.
at SimpleInjector.InstanceProducer.GetInstance()
at SimpleInjector.InstanceProducer.VerifyInstanceCreation()
System.InvalidOperationException
The configuration is invalid. Creating the instance for type LoginController failed. Unable to resolve service for type 'Raven.Client.IAsyncDocumentSession' while attempting to activate 'App.Identity.UserStore`1[App.Identity.AppUser]'.
System.Reflection.TargetInvocationException
Exception has been thrown by the target of an invocation.
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Microsoft.AspNet.Hosting.Startup.ConfigureBuilder.Invoke(Object instance, IApplicationBuilder builder)
at Microsoft.AspNet.Hosting.Startup.ConfigureBuilder.<>c__DisplayClass4_0.<Build>b__0(IApplicationBuilder builder)
at Microsoft.AspNet.Hosting.Internal.AutoRequestServicesStartupFilter.<>c__DisplayClass0_0.<Configure>b__0(IApplicationBuilder builder)
at Microsoft.AspNet.Hosting.Internal.HostingEngine.BuildApplication()
As far as I can see, this problem is not related to Simple Injector. From your registrations, and the exception information I see the following is the case:
You are resolving a LoginController from Simple Injector.
This LoginController depends on Raven.Client.IAsyncDocumentSession.
IAsyncDocumentSession is cross-wired from the ASP.NET configuration system to Simple Injector using CrossWire<IAsyncDocumentSession>.
IAsyncDocumentSession is registered in the ASP.NET configuration system.
The implementation of IAsyncDocumentSession that is registered in ASP.NET depends on UserStore<AppUser>.
The ASP.NET configuration system is unable to resolve that IAsyncDocumentSession registration and throws the exception stating:
Unable to resolve service for type 'Raven.Client.IAsyncDocumentSession' while attempting to activate 'App.Identity.UserStore`1[App.Identity.AppUser]'.
In other words, you would get the same exception when you would either resolve LoginController or IAsyncDocumentSession from the ASP.NET configuration system. Just call one of the following methods and you will see the same error:
app.ApplicationServices.GetRequiredService<LoginController>();
// or
app.ApplicationServices.GetRequiredService<IAsyncDocumentSession>();
I think that the IAsyncDocumentSession implementation depends on UserStore<T> or IUserStore<T>, but you haven't registered it in the ASP.NET configuration system.

add migration failed when DbContext in sperate project

I have a project with different layers: web, services, model, data each one has a different project in the same solution. The application, compiles and runs OK. But when I tried to implement migration I got the following error
dnx . ef migration add MigrationFile
System.InvalidOperationException: No DbContext was found. Ensure that you're using the correct assembly and that the type is neither abstract nor generic.
at Microsoft.Data.Entity.Commands.ContextTool.SelectType(IEnumerable`1 types, String name)
at Microsoft.Data.Entity.Commands.MigrationTool.GetContextType(String name)
at Microsoft.Data.Entity.Commands.MigrationTool.AddMigration(String migrationName, String contextTypeName, String startupAssemblyName, String rootNamespace,String projectDir)
at Microsoft.Data.Entity.Commands.Program.<>c__DisplayClass12_0.<AddMigration>b__0()
at Microsoft.Data.Entity.Commands.Program.Execute(String startupProject, Func`1 invoke)
at Microsoft.Framework.Runtime.Common.CommandLine.CommandLineApplication.Execute(String[] args)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Framework.Runtime.Common.EntryPointExecutor.Execute(Assembly assembly, String[] args, IServiceProvider serviceProvider)
at Microsoft.Framework.ApplicationHost.Program.ExecuteMain(DefaultHost host,String applicationName, String[] args)
at Microsoft.Framework.ApplicationHost.Program.Main(String[] args)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at Microsoft.Framework.Runtime.Common.EntryPointExecutor.Execute(Assembly assembly, String[] args, IServiceProvider serviceProvider)
at dnx.host.Bootstrapper.RunAsync(List`1 args, IRuntimeEnvironment env, FrameworkName targetFramework)
at dnx.host.RuntimeBootstrapper.ExecuteAsync(String[] args, FrameworkName targetFramework)
at dnx.host.RuntimeBootstrapper.Execute(String[] args, FrameworkName targetFramework)
I'm using this answer as a reference.
Maybe your project has more than one DbContext or you have not turned on the migrations.
If you have more than one Context, you will want to enable and add migrations for each Context separately:
add-migration -ConfigurationTypeName MyProject.MigrationsFolder.Configuration "migrationName"
This code will add a new Migration based on your Context and using the Configuration class associated to it. The following code will update the database associated with the Configuration class.
update-database -ConfigurationTypeName MyProject.MigrationsFolder.Configuration
the commands must be like this
- dnu restore
cd the project which contain the context path
dnx . ef migration add -c ContextName - s StartupProjectName
try it and if this work let me know, thnx ^^

StructureMap Exception Code: 202 No Default Instance defined for PluginFamily

I'm new to StuctureMap and I am writing a WCF service. In the existing code the previous developer used SturctureMap.
I get this error:
StructureMap Exception Code: 202
No Default Instance defined for PluginFamily MyCompany.SMS.Data.DataEntitys, MyCompany.SMS.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
Here is the Code:
class a
{ method aa
{
var db = ObjectFactory.GetInstance<nsclaimsEntities>();
}
}
When we are calling this code from an aspx.cs file it is working fine without any error, but I tried to wrap this code in a WCF webservice and it is throwing this exception.
Here is the stack trace:
at StructureMap.BuildSession.<.ctor>b__0(Type t)
at StructureMap.Util.Cache`2.get_Item(KEY key)
at StructureMap.BuildSession.CreateInstance(Type pluginType)
at StructureMap.Container.GetInstance(Type pluginType)
at StructureMap.Container.GetInstance[T]()
at StructureMap.ObjectFactory.GetInstance[PLUGINTYPE]()
at NicorNational.SMS.CustDemographic.GetByAccountNumber(String acctNum) in C:\\Projects\\NicorNational.SMS\\CustDemographic.cs:line 105
at NicorNational.Services.eCommerce.EligibilityService.GetEligibilityById(String accountId) in C:\\Projects\\Solutions\\NicorNational.Services.eCommerce\\EligibiltyService.svc.cs:line 23
at SyncInvokeGetEligibilityById(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)"
Why do I get this exception?
As you've already found out, the problem migrating straight from a web application to a WCF service is where to place the bootstrapping code.
I just wanted to point out that you should move away from the service location behaviour and introduce dependency injection instead to have loose coupling and make your service easier to maintain/change.
Jimmy Bogard has written an excellent blog entry on how to bootstrap a WCF service using Structure Map. He uses a custom ServiceHostFactory instead of a static constructor to bootstrap the registry.

Categories