How to Connect to Azure database using the standard dotnet web template - azure

I am super excited to start developing .NET on my Mac but getting frustrated trying to figure it all out. So I have a WebApplication created by calling yo aspnet and out of the box it works great. It comes with a connection to a local db stored in the project. Where I am having trouble is connecting it to a remote DB hosted in my azure portal.
My Connection string below directly from my azure portal. I have updated my appsettings.json "DefaultConnection" property to this value (with the username and password missing below) and I am getting errors like "ArgumentException: Keyword not supported: 'server'." I have tried several different connection strings and none are working.
Admittedly I am new to all of this so I am probably missing something simple but in searching online I have yet to find the solution.
Server=tcp:mydbserver.database.windows.net,1433;Initial Catalog=LH;Persist Security Info=False;User ID={your_username};Password={your_password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;
For reference here is my whole appsettings.json (without username & passwrod...)
{
"ConnectionStrings": {
//"DefaultConnection": "Data Source=LH.db"
"DefaultConnection": "Server=tcp:mydbserver.database.windows.net,1433;Initial Catalog=lighthouseFSQ;Persist Security Info=False;User ID={Username};Password={Password};MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}
Any help is greatly appreciated. FYI I did try this in Windows VS2015 and it worked fine.

By default, the dotnet new -t web tempalte uses SQLite database, so only changing the connection string is not sufficient to change the provider.
You also need to remove the Microsoft.EntityFrameworkCore.Sqlite package from project.json and replace it with Microsoft.EntityFramework.SqlServer (assuming you are using the SQLServer of Azure). Then in your Startup.cs you need to replace the
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
with
// Add framework services.
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
and change the namespaces if necessary.
Update
In project.json you just need to change the dependency with Sqlite.
"dependencies": {
...
"Microsoft.EntityFrameworkCore.Sqlite": "1.0.1",
...
}
}
to
"dependencies": {
...
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.1",
...
}
}
If there is also a Microsoft.EntityFrameworkCore.Sqlite.Design ch ange that too to Microsoft.EntityFrameworkCore.SqlServer.Design too, it's there for scaffolding etc.

Related

How to configure Serilog settings in Azure Function?

I’m in the process of creating my first production Azure Function and I’m trying to write log information to a local file and then eventually to Blob Storage. The local file is more for development troubleshooting and then ultimately I would like to have production information stored in Blob Storage. I’m not only new with Azure Functions but I’m also new with Serilog. I’ve used NLog in all my other applications but couldn’t get it to work with Azure Functions.
Currently I’m trying to get the local log working. I actually seem to have it working but I’m not understanding how I can tweak a couple things.
The first thing I’m trying to change is the amount of information that is getting logged. It seems to be logging a whole bunch of system type of information like Request info to the blob storage. There is so much stuff getting logged that what entry I'm adding in code gets lost. It looks like all the system entries are marked as Information which is why it’s probably showing up in my log. However, I would like to see if I could get it to only log data from when I specifically call the logger.Information(“some text”) in my code. Is there a way to suppress all of the Microsoft system information?
Second thing is how I can I make the Serilog configuration come from my local.settings.json file. Below is a sample of my file and I’m not sure if I would add the configuration information in the Values: property or if I would put it outside of that property into its own property? I’m assuming it would be in it’s own property but so far all my custom settings have been coming from the Values: property?
Do I need to add the Serilog.Settings.Configuration NuGet package? If so, then I’m not understanding how I configure my Startup.cs file to get the information from the local settings file instead of configuring the settings directly in code. Eventually, I would like to add it to Dependency Injection so I can use the logger in other classes as well.
Startup.cs
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddTransient<IDataManager, DataManager>();
ConfigureServices(builder.Services).BuildServiceProvider(true);
}
private IServiceCollection ConfigureServices(IServiceCollection services)
{
services
.AddLogging(loggingBuilder =>
loggingBuilder.AddSerilog(
new LoggerConfiguration()
.MinimumLevel.Information()
.WriteTo.Console()
.WriteTo.File(#"D:\logs\AzureFunction\log_.txt", rollingInterval: RollingInterval.Day)
.CreateLogger())
);
return services;
}
Local.settings.json
{
"IsEncrypted": false,
"Values": {
"ProcessLookBackDays": "90",
"SqlConnection": "connection info",
"StorageConnection": "connection info"
"AzureWebJobsStorage": "connection info"
"InputContainer": "test-files",
"InputFolder": "input",
"FUNCTIONS_WORKER_RUNTIME": "dotnet"
},
"Serilog": {
"Using": [ "Serilog.Sinks.File" ],
"MinimumLevel": {
"Default": "Information"
},
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "D:\\logs\\AzureFunction\\log_.log",
"rollingInterval": "Day",
"outputTemplate": "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {CorrelationId} {Level:u3}] {Username} {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
Setting up configuration in local-setting. Json will not reflect in the azure function app. local-setting as the name suggest is for local use only while with azure you need to use the app setting and read them.
Just add a new setting in the app setting and you can then use the below code to read the settings.
var appsettings = Environment.GetEnvironmentVariable("Name of the setting");
When you want to use the external configuration with serilog then you can use the Serilog.Settings.Configuration.
Now you can configure the minimum level of a log event so all the log event with less importance than the specified minimum level will not be logged.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.WriteTo.Console(restrictedToMinimumLevel: LogEventLevel.Information)
.CreateLogger();
Here we specify two things the .MinimumLevel.Debug() and restrictedToMinimumLevel this attribute dictates the minimum level for the that particular sink. A sink is just a place where you can log, they are configured using the Writeto tag. for e.g., in the above code the sink is a console. There are other sink too.
The minimum levels are verbose Debug, information, warning, error, fatal.
Reference:-
Read configuration from app setting by Ashish Patel
Use serilog to filter the logs
Serilog setting configuration

Updating databases in Entity Framework for development and production environments in ASP.NET Core

How do I apply EF migrations to multiple databases, referencing either a Development or Production environment as required?
TL;DR
I'm developing an ASP.NET Core MVC application using Entity Framework that references different databases for Development and Production. Both databases are hosted Azure SQL databases.
The application at the moment is running on IIS Express on my Development machine, but I will deploy Production to an Azure App Service. I'm using Entity Framework and migrations to update the database design.
I've applied this answer to use a different database connection string for either the Development or Production launch configurations, and this seems to be working. The connection strings are then stored in appsettings.Development.json or appsettings.Production.json.
When I select the DEV launch configuration, I am able to use the EF cli command dotnet ef database update in order to apply my migrations to the development database. Works fine.
However, I cannot work out how to tell Visual Studio to apply each migration to the production database when I run under the PROD launch configuration.
Running the command dotnet ef database update after changing the launch configuration continues referencing the development database, and nothing changes. I'm not surprised by this - I haven't told Visual Studio where to find the other database. But I also can't work out how to do this.
Is there a way to change the referenced database, based on the launch configuration or environment variables? Or some other convenient way?
launchSettings.json
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:57961",
"sslPort": 44320
}
},
"profiles": {
"IIS Express (dev)": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express (prod)": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
}
}
}
According to the documentation, you can specify the connection string as an extra parameter:
--connection: The connection string to the database. Defaults to the one specified in AddDbContext or OnConfiguring.
So this command will let you specify which database you are targeting:
dotnet ef database update --connection "<sql connection string>"

Implementing Application Insight to Azure Function App

Anyone know of any god guide for this?
First i created an Application Insight Resource and put:
APPINSIGHTS_INSTRUMENTATIONKEY = "INSTRUMENTATION KEY"
in the Function Apps Application Settings.
I have tried implementering the nuget package for the funtion app like this.
Createing a project.json file and pasting this:
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.ApplicationInsights": "2.1.0"
}
}
}
}
It installed the nuget package (i could see it in the log, everything went well).
After that i put these snippets in my code to use the telemetry.TrackException(exception) functionality:
First...
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.Extensibility;
Then:
var telemetry = new TelemetryClient(new TelemetryConfiguration("INSTRUMENTATION KEY"));
and in my catch:
telemetry.TrackException(e);
and when i try to save my Function app i get this error:
error CS1729: 'TelemetryConfiguration' does not contain a constructor that takes 1 arguments
You don't need to use reference the Application Insights library to use it with Functions. If you've already set the APPINSIGHTS_INSTRUMENTATIONKEY application setting, you can simply add the ILogger interface as a parameter to your function and it will automatically send the log data to your Application Insights instance.
Full documentation can be found here: https://learn.microsoft.com/en-us/azure/azure-functions/functions-monitoring
Addition to #ChrisGillum answer for .Net Core 3.1 Azure Function:
If you create a new Azure Function with Http trigger from Visual Studio the following line will exist in the example:
log.LogInformation("C# HTTP trigger function processed a request.");
Add "APPINSIGHTS_INSTRUMENTATIONKEY" to local.settings.json Values.
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"APPINSIGHTS_INSTRUMENTATIONKEY": "<YOUR_GUID>"
},
}
Note that the key must be in an app setting named APPINSIGHTS_INSTRUMENTATIONKEY and nothing else.
Logging is then added automatically:
Complete guide for hosted values:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-monitoring?tabs=cmd#enable-application-insights-integration

Deploy .netcore to iis

I have a .net core app and runs fine on kestrel server.
http://localhost:5000/mapapi/v1.0/branch
I have deployed the app to IIS using publish tool in visual studio 2017 and with in program.cs, I have this line of code
.UseIISIntegration()
when I run the app I get an error
An error occurred while starting the application.
Exception: Cannot read variable
It is not reading the variable from launchsettings.json. I also created a profile by the name "IIS"
"IIS": {
"commandName": "iis",
"launchBrowser": true,
"launchUrl": "mapapi/v1.0/Branch",
"environmentVariables": {
"ConnectionString": "myhiddenconnectionstring",
}
}
What am I doing wrong? what other places do I have to look and make sure the application reads the values appropriately. Anyone in the community who had experience .net core to IIS, please share you knowledge with the community. We would appreciate it.

Azure Web App error 500 on Connection String

I've a simple ASP.NET Core 1.0 application which seeds some data in to SQL Server in Azure. I've 2 databases, one is for development and other is for Production (Azure SQL), I'm using Identity. When I run my application on my local machine, it works fine, but when I deploy it I get the error 500 (Internal Server Error) with no further explanation here is my code.
if (CurrentEnvironment.IsDevelopment())
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
}
else if (CurrentEnvironment.IsStaging() || CurrentEnvironment.IsProduction())
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Environment.GetEnvironmentVariable("SQLCONNSTR_kConnectionString")));
}
If I change the environment setting from Production to Development using Azure Application Settings, it says that error is at Configuration.GetConnectionString("DefaultConnection") saying connection string cannot be null.
There is a special pattern to be used, when you want to set the Variables from Environmental Variables.
In Azure App Service you set up your connection string as "DefaultConnection" or "SQLCONNSTR_kConnectionString" respectively, but you need to use. So if your connection string is "DefaultConnection", your appsetting.json must look like this
"ConnectionStrings" : {
"DefaultConnection" : "..."
}
when you obtain it with Configuration.GetConnectionString("DefaultConnection") (alternatively you can get it via Configuration["ConnectionStrings:DefaultConnection"]).
If you load it from environmental variables, it's better to override the default connection string via
var builder = new ConfigurationBuilder()
.SetBasePath(hostEnv.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{hostEnv.EnvironmentName}.json", optional: true, reloadOnChange: true);
.AddEnvironmentVariables();
Then the environmental variables will automatically override your settings in the appsettings.json or appsettings.Production.json.
If you want to get it via Environment.GetEnvironmentVariable you need to make it Environment.GetEnvironmentVariable("ConnectionStrings__SQLCONNSTR_kConnectionString") on Linux and Environment.GetEnvironmentVariable("ConnectionStrings:SQLCONNSTR_kConnectionString") on Windows. It's on top of my head, but the convention was something similar to this
I might misunderstand what you meant by "Azure SQL", but if you're using hosted Azure DB, then the prefix for the environment variable will be SQLAZURECONNSTR_ instead of SQLCONNSTR_. The latter would be used, for example, if you have SQL on your own VM in Azure (IaaS).
Also, it may help you to break apart your combined line of:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Environment.GetEnvironmentVariable("SQLCONNSTR_kConnectionString")));
into separate lines, something like the following, then you might be able to diagnose the issue a bit easier.
var envConnectionString = Environment.GetEnvironmentVariable(...);
if (string.IsNullOrEmpty(envConnectionString))
{
// log error, throw exception, etc
}
else
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(envConnectionString)));
}
Thank for your respond, actually I resolved my issue. Since ASP.NET Core RC 2, we have to use
"publishOptions": {
"include": [
"wwwroot",
"Views",
"Areas/**/Views",
"appsettings.json",
"web.config"
] },
options in project.json in order work them. :)

Resources