Entity Framework connection string from .DSN file

772 views Asked by At

I have a problem, so I thought I would come to the brightest minds on the web.

I have written an ASP.NET MVC application that interfaces with a web service provided by another application. My app basically just adds some features to the other web application.

Both applications have a database. I am trying to limit the configuration for my application by using the other applications SQL Server credentials. This is so that if they decide to change the password for the other application, mine will just start working.

These credentials are saved in a .DSN file that my application can reach. How can I get my application, which uses Entity Framework, to use a connection string that is created from the details read in the .DSN file?

I can figure out the code to read the .DSN file, so if you wish to provide some code examples you can base them around setting the connection string for EF.

I am also open to other solutions, or even reasons why I shouldn't do this.

Thanks in advance.

PS. As I was writing this, I came up with a little concept. I am going to test it out now to see how it goes. But here is the basics:

  1. On start up, read the needed details into static properties.
  2. public MyContext() : base(getConnectionString()) { }

3.

private SomeObjectTypeHere getConnectionString()
{
   //read static properties
   //return .....something..... not sure yet....
}

Thoughts on that maybe?

EDIT I have created a method that reads the .DSN file and gets the server, the user id and the password. I now have these stored in static properties. In my context, how can I set my connection string now that i have the required details.

1

There are 1 answers

0
spovelec On BEST ANSWER

So, the biggest issue that I was really having was how to set my connection string in Entity Framework. But I was also hoping that maybe someone else had worked with .DSN files.

Anyway, here was my solution. Still looking for problems that might arise from this, so if you can see any issues, let me know!

First, I created a method that was run on startup. This method ran through the .DSN file and picked out the gems.

Keep in mind that I have never worked with .DSN files, and the section that gets the password is unique to my situation.

            var DSNFileContents = File.ReadAllLines(WebConfigurationManager.AppSettings["AppPath"] + @"\App.DSN");//reads DSN into a string array

            //get UID
            string uid = DSNFileContents.Where(line => line.StartsWith("UID")).First().Substring(4);//get UID from array
            //test if uid has quotes around it
            if (uid[0] == '"' && uid[uid.Length - 1] == '"')
            {
                //if to starts with a quote AND ends with a quote, remove the quotes at both ends
                uid = uid.Substring(1, uid.Length - 2);
            }

            //get server
            string server = DSNFileContents.Where(line => line.StartsWith("SERVER")).First().Substring(7);//get the server from the array
            //test if server has quotes around it
            if (server[0] == '"' && server[server.Length - 1] == '"')
            {
                //if to starts with a quote AND ends with a quote, remove the quotes at both ends
                server = server.Substring(1, server.Length - 2);
            }

            //THIS WON'T WORK 100% FOR ANYONE ELSE. WILL NEED TO BE ADAPTED
            //test if PWD is encoded
            string password = "";
            if (DSNFileContents.Where(line => line.StartsWith("PWD")).First().StartsWith("PWD=/Crypto:"))
            {
                string secretkey = "<secret>";
                string IV = "<alsoSecret>";
                byte[] encoded = Convert.FromBase64String(DSNFileContents.Where(line => line.StartsWith("PWD")).First().Substring(12));
                //THIS LINE IN PARTICULAR WILL NOT WORK AS DecodeSQLPassword is a private method I wrote to break the other applications encryption
                password = DecodeSQLPassword(encoded, secretkey, IV);
            }
            else
            {
                //password was not encrypted
                password = DSNFileContents.Where(line => line.StartsWith("PWD")).First().Substring(4);
            }

            //build connection string
            SqlConnectionStringBuilder cString = new SqlConnectionStringBuilder();
            cString.UserID = uid;
            cString.Password = password;
            cString.InitialCatalog = "mydatabase";
            cString.DataSource = server;
            cString.ConnectTimeout = 30;
            //statProps is a static class that I have created to hold some variables that are used globally so that I don't have to I/O too much.
            statProps.ConnectionString = cString.ConnectionString;

Now that I have the connection string saved, I just have my database Context use it as below,

public class myContext : DbContext
{
    public myContext() : base(statProps.ConnectionString) { }

    //all my DbSets e.g.
    public DbSet<Person> Persons{ get; set; }


}

This is simple, yes, but I hoping that it can provide some information to anyone that was looking to do something similar but was not sure about how it should be handled.

Again, let me know if you like or dislike this solution and if you dislike it, what is your solution and why.

Thanks again!