dotnet ef database update on ASP.NETCORE2.1 project with MSSQLSERVER - Format of the initialization string does not conform to specification ..index 0 - sql-server

As the title says, I am trying to use dotnet ef database update from the command line and getting the error Format of the initialization string does not conform to specification starting at index 0.
From searching around this site and the internet, everything points to the connection string being wrong, but the connection string is working fine to compile and run the application. I am trying to add Identity to the project so I can have users with passwords, and am trying to follow the Deep Dive tutorial on pluralsight, but when it gets to this part, the code fails.
My connection string in appsettings.json is
"ConnectionStrings": {
"DefaultConnection": "Server=PTI-VWS12-002;Database=EPDM_TestVault;Trusted_Connection=true;MultipleActiveResultSets=true;"
},
The code in my Startup.cs is:
var migrationAssembly = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), sql=> sql.MigrationsAssembly(migrationAssembly)));
though i've also tried it without the migration assembly as well. I'm really not sure what could be wrong with my connection string.
EDIT: My constructor:
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration) { Configuration = configuration; }
And my constructor has the default for ASP.NET CORE 2.1
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>();
EDIT 2: Solved.
I'm still not sure what I did wrong in my project, but i got the Identity tables to generate using the official Asp.NET sample project library over here https://github.com/aspnet/Docs. Using the exact migration file from the IdentityDemo, and plopping in my connection string from above, I was able to create the Identity tables in my database.

You first need to configure IConfiguration using IConfigurationBuilder in Constructor of startup or in Program.cs before Kestrel Server startup.
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
_configuration = builder.Build();

I'm still not sure what I did wrong in my project, but i got the Identity tables to generate using the official Asp.NET sample project library over here https://github.com/aspnet/Docs. Using the exact migration file from the IdentityDemo, and plopping in my connection string from above, I was able to create the Identity tables in my database.
EDIT: it still doesn't run in context of my program.

Related

Connection String not found Azure Data Studio to VS2022 - Mac

I am trying to setup my uni work (which is windows based) onto my mac. I have a docker container running with AzureSQLEdge, which I have connected to my Azure Data Studio and can run queries no problem. However in VS2022 trying to set up the connection to the database in Azure Data Studio.
At the moment I am just trying to get some IDs printed to the page (we are using #razor)
#using WebMatrix.Data
#{
ViewBag.Title = "About Us";
var db = Database.Open("AmazonOrders");
var select = "SELECT * FROM Customers";
var data = db.Query(select);
}
<h2 class="text-center">#ViewBag.Title</h2>
<h3>#ViewBag.Message</h3>
<p>Use this area to provide additional information</p>
#foreach (var row in data)
{
#row.customerID
}
My connection string in appsettings.json is:
"AllowedHosts": "*",
"ConnectionStrings": {
"AmazonOrders": "Server=tcp:127.0.0.1,1433;Database=AmazonOrders;User=sa;Password=SQLserver123!;"
}
However I am getting this error message when I load the page:
InvalidOperationException: Connection string "AmazonOrders" was not found.
Setting up the connection string is all the windows users have to do, they have a local version of the database in their project solution. Any help is appreciated, the resources online are more about creating db contexts which I would prefer to avoid if possible, and just connect directly to my database on docker/azure data studio.
edit
Here is the full appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"AmazonOrders": "Server=tcp:127.0.0.1,1433;Database=AmazonOrders;User=sa;Password=SQLserver123!;"
}
}
#using WebMatrix.Data
This is an old data access library intended solely for use with ASP.NET Web Pages, which is a pretty ancient (and virtually obsoleted) web development framework that targets the full .NET Framework. As such, it knows nothing about appsettings.json files which were introduced in .NET COre. The primary configuration mechanism for Web Pages is a web.config file and that's where this library looks for a connection string.
If I were you, I would remove WebMatrix.Data from your project (assuming it is actually a Razor Pages app, not Web Pages) and use Entity Framework Core instead. If it is a Web Pages app and that's the framework you want to work with, remove the appsettings.json file and add a connection string to the web.config file: https://www.connectionstrings.com/store-connection-string-in-webconfig/

Dapper: Cannot read/map Geometry type field in local SQL Server

I am running ASP.NET Core 2 application.
I have a local instance of SQL Server where I have a table with a column of type Geometry.
When I go to read this table I get the following errors:
Type Udt is not supported on this platform.
Error parsing column 4 (MyLocation)
However this issue only seems to occur in my API project which calls to a custom made Nuget package that handles the CRUD operations.
If I test the same code in the project that does the CRUD it reads and maps my object.
It is not a connection issue in the API for I can successfully read/write other tables that do not have a Geometry field in it.
What could I possible be missing?
Code:
MyController:
public async Task<IActionResult> Get(Guid Id)
{
var rec = await myRepo.Get<MyData>(id);
// then do stuff
}
*myRepo is injected into my controller.
public class MyData
{
public Guid Id {get;set;}
public IGeometry MyLocation {get;set;}
}
myRepo:
public async Task<TEntity> Get<TEntity>(object id)
where TEntity : class
{
_conn.Open();
return await _conn.GetAsync<TEntity>(id);
}
If this is .NET Core, then I suspect you could have significant issues using sqlgeography etc; UDTs essentially aren't yet implemented in .NET Core:
Additionally, the underlying types that you would want to load use native code; the geo/etc types are not, AFAIK, available in .NET Core.
If I'm wrong, I'm more than happy to try to make whatever changes we need to help make this work, but at the time of writing: I don't think this is going to work through any API (it is not specific to Dapper).
You might want to consider using ASP.NET Core on .NET Framework for today? reference .Net framework 4.5.2 from .Net Core 2.0 project
If this data does actually load from ADO.NET in .NET Core, then I'd be happy to fix whatever I've missed.

Read connection string from app.config in my DataAccess library project for dbContext

I am working on a VS2012 solution that has got an ASP.NET MVC 4.0 project and multiple class libraries like my Managers, providers and DataAccess projects. My dbContext class is defined inside the DataAccess project.
My aim is to restrict the connection string info in the DataAccess project's App.Config file. I am trying to avoid specifying the connectionString anywhere else in the project as it is my DataAccess classes that would interact with the DB.
Now if I specify my connection string the my dbContext class by hard coding it, my project works fine and is able to read data from DB.
public MyDbContext()
: base(#"Data Source=MYLAPTOP\SQL2012MAIN;Initial Catalog=MyDB;User ID=sa;Password=*****")
{
}
But if I specify the connection string in app.config file like this:
<connectionStrings>
<add name="MyDBConnection" connectionString="Data Source=MYLAPTOP\SQL2012MAIN;Initial Catalog=MyDB;User ID=sa;Password=*****;Connect Timeout=200; pooling='true" providerName="System.Data.SqlClient" />
</connectionStrings>
and use it in my dbContext classs as follows:
public MyDbContext()
: base("MyDBConnection")
{
}
It doesn't work. I tried using the same connection string in my MVC project's web.config file also, but then again I am getting the same error (attached image):
Can anybody please guide me...
Thanks Hari
I think your fault lies at the pooling, so try
Pooling=True also make sure to remove the single inverted comma that you have, '
There is one more point you might want to research on, I think that Pooling is by default enabled, so setting Pooling=True, while this is explicit, if I remember correctly, it has no effect, whereas Pooling=False does have a effect.
To make it work you can try calling the base constructor like this:
public MyDbContext()
: base("MyDBConnection", backend, metadataSource)
{
}
In this case, backend and metadataSource would be the fields in your MyDbContext class, which hold the configuration of the backend and the configuration of the mapping.
In the Creating OpenAccessContext article, you will find more details about the design of the context.

Build approach for creating ClickOnce packages for multiple environments

Here is my scenario:
I have a WPF application which I am delivering via ClickOnce. The application has multiple environments for multiple clients (currently 9 but expecting to double that in the near future).
The process I currently use is (basically):
Token replace parts of the app.config
Token replace parts of the WiX file used in the generation of the MSI installer (including the signing certificate and thumbprint)
Build the solution
Create a Client/Environment specific installer
Repeat for each client/environment combination
This has the benefit of meaning that to install the application it is a simple case of running the required installer. However, the downside is that if (when) I need to create a new environment, I have to re-run the whole build process with a new set of configuration parameters.
How can I make this all better?
My latest thought is that I split out my build process to just create the binaries. Then have a separate packaging process that that pulled in the appropriate binaries, patched configs, (re)signed manifests using MAGE etc.
This will have the continued benefit of "build once, deploy multiple times", whilst ensuring that if new environments were required they could be repackaged without rebuilding the binaries.
Does this sound like a sensible approach?
Does anyone have any guidance for such a scenario?
Thanks
We had a similar scenario, with a WPF ClickOnce application used in multiple environments, where the only thing in app.config is a connectionstring.
To get around the fact that you can not change the configuration file within the clickonce package without having a build process building one package for each client/environment we came up with a solution that lets you place an app.config file in the server deployment folder and let the application access that at runtime.
To do that, we created a static class that initializes in app.xaml.cs OnStartup event.
public static class DbConnectionString
{
public static string ConnectionString { get; private set; }
public static string ActivationPath { get; private set; }
public static void Init()
{
string dbContext = "myDbContext";
string configFile = "App.config";
ConnectionString = "";
ActivationPath = "";
ActivationArguments actArg = AppDomain.CurrentDomain.SetupInformation.ActivationArguments;
if (actArg != null)
{
if (actArg.ActivationData != null)
{
try
{
var actData = actArg.ActivationData[0];
var activationPath = Path.GetDirectoryName(new Uri(actData).LocalPath);
var map = new System.Configuration.ExeConfigurationFileMap();
map.ExeConfigFilename = Path.Combine(activationPath, configFile);
var config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
var connectionStringSection = config.ConnectionStrings;
ConnectionString = connectionStringSection.ConnectionStrings[dbContext].ConnectionString;
ActivationPath = activationPath;
}
catch (Exception)
{
ConnectionString = "";
ActivationPath = "";
}
}
}
}
}
In the Project settings under Publish/Options/Manifests tick the "Allow URL parameters to be passed to application"
I then use the ConnectionString property of the static class where I need a connection string. It will not be set unless you deploy the app as online only, so we default to the app.config within the package for dev/testing.
It is a bit convoluted, but works well, and you only have to publish your app once and provide an app.config for each installation that does not change between builds.
It also sets the property ActivationPath which is the path to the clickonce server install directory.
That sounds like a step in the right direction, and is similar to what I've been doing for a WPF application for a couple of years, and it has worked well.
We build the solution with Team City and then have multiple after build steps which handle the ClickOnce publishing, one step for each configuration. Each configuration involves kicking off an MSBuild file which uses Mage.exe. It copies the solution output files to a temporary directory and then performs numerous replacements on files such as the App.config and runs various custom MSBuild tasks.
The MSBuild project file contains base settings and environment overrides for things like the ClickOnce download URL. We also have to do some hacky replacements on the generated manifest itself (and then re-sign it) for things like marking particular files as data, or not.

How do I encrypt the connection string with EF 4.1 Code First?

I'm using the Code First RC to build a class library and I would like to be able to encrypt the connection string that I'm using. The consumers of the class library could be ASP.NET or Windows Forms apps, so I need an encryption method that works with both.
It appears that I can pass in a connection string to DbContext by name, but not by value, as shown here, so I don't think I can manually decrypt within my program before passing the string to DbContext. Could anyone point me in the right direction?
You can easily encrypt any .NET configuration section - not just in ASP.NET as many devs seem to think, but absolutely also in other apps.
Check out Jon Galloway's blog post on the topic - excellent read!
With this approach, you could encrypt the <connectionStrings> section - and to make it easier still, you could externalize that section into a separate file, too.
So in your app.config for your Winforms app, you'd have:
<connectionStrings configSource="ConnectionStrings.config" />
and the same would be in your web.config for your web application, and the file referenced would contain just the <connectionStrings> and that could be encrypted. Load the appropriate connection string from your config, and pass it into your DbContext constructor, and you should be fine.
You can pass a full connection string into DbContext:
http://blogs.msdn.com/b/adonet/archive/2011/01/27/using-dbcontext-in-ef-feature-ctp5-part-2-connections-and-models.aspx
Under "Other DbContext Constructor Options":
...
You can pass a full connection string to DbContext instead of just
the database or connection string
name. By default this connection
string is used with the
System.Data.SqlClient provider;
this can be changed by setting a
different implementation of
IConnectionFactory onto
context.Database.DefaultConnectionFactory.
You can use an existing DbConnection object by passing it
to a DbContext constructor. If the
connection object is an instance of
EntityConnection, then the model
specified in the connection will be
used in Database/Model First mode.
If the object is an instance of
some other type—for example,
SqlConnection—then the context will
use it for Code First mode.
...
If this is true, then you can use AES or some other encryption to encrypt the string in the .config file, then decrypt at runtime and feed it into the DbContext constructor.

Resources