way to set connection string for database migration in web.config - asp.net-mvc

I have an ASP MVC 5 app with code first migrations enabled. Whenever I publish it to a server, it adds an extra connection string to the Web.Config file along with a "parameter" element, and it breaks the site until I replace it. It looks like:
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
<contexts>
<context type="MyApp.DataLayer.MyContext, MyApp">
<databaseInitializer type="System.Data.Entity.MigrateDatabaseToLatestVersion`2[[MyApp.DataLayer.MyContext, MyApp], [MyApp.Migrations.Configuration, MyApp]], EntityFramework, PublicKeyToken=b77a5c561934e089">
<parameters>
<parameter value="MyContext_DatabasePublish" />
</parameters>
</databaseInitializer>
</context>
</contexts>
</entityFramework>
<connectionStrings>
<add name="MyContext" connectionString="Data Source=SQLServerName;Initial Catalog=MyDB;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
<add name="MyContext_DatabasePublish" connectionString="MyContext_DatabasePublish.ConnetionString" providerName="System.Data.SqlClient" />
</connectionStrings>
I presume that extra connection string is for the database migrations, is that right? All I have to do to get things working is replace the connection string with the one above it, so replace MyContext_DatabasePublish.ConnetionString with Data Source=SQLServerName;Initial Catalog=MyDB;Integrated Security=SSPI for example.
First, is that connection string even needed? This is all in dev, and my migrations were all done from my local machine.
If it is needed, is there a way to keep it from coming in as MyContext_DatabasePublish.ConnetionString and instead come in as the connection string that works so I don't have to manually replace it every time I publish an update?
Thank you in advance for any information and advice!

See post here:
https://blogs.msdn.microsoft.com/aspnetue/2012/06/12/deployment-in-visual-studio-2012-rc-using-entity-framework-code-first-migrations/
This occurs when you setup code first migrations so that you can define a privileged account to run your migrations without having to elevate the privileges of your normal context user.

Related

Is there a way to check debug=true in startup.auth in ASP.NET MVC

I see that we can use HttpContext.Current.IsDebuggingEnabled in controllers to check if debug=true is enabled in web.config. How can I check the same in startup.auth? I need to set different app Ids for my local and production environments for fb authentication using this condition. Please suggest if there is a better way to do this.
I would recommend creating a web.config entry for whatever dynamic data you need to set and then use web.config transforms to change the data depending on environment. This is very commonly used with connection strings to set different source databases depending on what environment youre in (local vs test vs prod).
See the example below:
local Web.config:
<connectionStrings>
<add name="myConnection" connectionString="Data Source=localhost;Initial Catalog=myDatabase;Integrated Security=True;" providerName="System.Data.SqlClient" />
</connectionStrings>
Web.Debug.Config:
<connectionStrings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" name="myConnection" connectionString="Data Source=myTestSqlServer;Initial Catalog=myTestDb;User Id=myTestUserId;Password=myTestPassword;" providerName="System.Data.SqlClient" />
</connectionStrings>
Web.Release.Config:
<connectionStrings>
<add xdt:Transform="SetAttributes" xdt:Locator="Match(name)" name="myConnection" connectionString="Data Source=myProdSqlServer;Initial Catalog=myProdDb;User Id=myProdUserName;Password=myProdPassword;" providerName="System.Data.SqlClient" />
</connectionStrings>

Create user database via code first ASP.NET MVC

I'm trying to use a MySQL database with asp.net MVC via a code first approach and I don't know how to create the tables, I thought it would create by itself.
I get the message : "Table 'XXX.aspnetusers' doesn't exist"
Do I need to run migrations or something like that?
Thanks
I got a little further by using update-database. You must have change your connection string and your provider to correspond to your MySql
Example :
<add name="DefaultConnection" connectionString="server=127.0.0.1;User Id=root;password=;database=myDB" providerName="MySql.Data.MySqlClient" />
Provider :
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
<providers>
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.9.9.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"></provider>
</providers>
</entityFramework>
You should also put this on your dbContext :
[DbConfigurationType(typeof(MySql.Data.Entity.MySqlEFConfiguration))]
Thanks

Error Unable connect to SQL Server when add <roleManager enabled="true">

When I add
<roleManager enabled="true"></roleManager>
to my web.config, I get an error
Unable to connect to SQL Server database
occurs on this line of code:
System.Web.Security.Roles.AddUserToRole(m.UserName, "admin");
I added this to the web.config and it solved my problem:
<system.web>
<roleManager enabled="true" defaultProvider="CustomizedRoleProvider">
<providers>
<add name="CustomizedRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="DefaultConnection" />
</providers>
</roleManager>
</system.web>
I had the exact same error when I had enabled believing I was enabling ASP.NET Identity 2. They are not the same! The enabled an old version of identity management which uses a different table structure to ASP.NET Identity 2 (which doesn't need "enabling" by the way - it's just there).
check the connection String.
If you are intentionally using the old role-manager and still getting the error you might be looking at the default localdb instead of your database, in which case you can modify to point at any connection string you want:
<roleManager
enabled="true"
cacheRolesInCookie="true"
defaultProvider="OurSqlRoleProvider"
>
<providers>
<add
connectionStringName="DefaultConnection"
applicationName="/"
name="OurSqlRoleProvider"
type="System.Web.Security.SqlRoleProvider" />
</providers>
</roleManager>
If you are are after using ASP.NET Identity 2, here's an article on it:
http://johnatten.com/2014/04/20/asp-net-mvc-and-identity-2-0-understanding-the-basics/

How do I setup ASP.NET Identity to use my own connection string?

I have an MVC5 app that's using EF. I would like to add ASP.NET Identity and I've noticed that the connection string for ASP.NET identity is using "DefaultConnection". What Do I need to do so that ASP.NET Identity tables are created in my already existing db (source=DILS-S1301;initial catalog=MVC5;) as specified in MVC5Entities and NOT DefaultConnection => (LocalDb)\v11.0??
thanks
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-MySuperAwesomeMVCApp-20131105011429.mdf;Initial Catalog=aspnet-MySuperAwesomeMVCApp-20131105011429;Integrated Security=True" providerName="System.Data.SqlClient" />
<add name="MVC5Entities" connectionString="metadata=res://*/Models.Mvc5Model.csdl|res://*/Models.Mvc5Model.ssdl|res://*/Models.Mvc5Model.msl;provider=System.Data.SqlClient;provider connection string="data source=DILS-S1301;initial catalog=MVC5;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
I tried modifying "DefaultConnection" like so:
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=DILS-S1301;AttachDbFilename=|DataDirectory|\MVC5.mdf;Initial Catalog=MVC5;Integrated Security=True" providerName="System.Data.SqlClient" />
<add name="MVC5Entities" connectionString="metadata=res://*/Models.Mvc5Model.csdl|res://*/Models.Mvc5Model.ssdl|res://*/Models.Mvc5Model.msl;provider=System.Data.SqlClient;provider connection string="data source=DILS-S1301;initial catalog=MVC5;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
but now i get an error:
Database 'C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\DATA\MVC5.mdf' already exists. Choose a different database name.
Cannot attach the file 'C:\Users\blah\Documents\Visual Studio 2013\Projects\MySuperAwesomeMVCApp\MySuperAwesomeMVCApp\App_Data\MVC5.mdf' as database 'MVC5'.
The actual question shall be "How do I setup ASP.NET Identity to use my own connection string?"
If above is the correct summary of your question, below is the answer.
ASP.NET Identity uses EntityFramework for database related tasks. So you can use following option as suitable.
Option 1: EntityFramework's default connection string can be setup using following code snippet in web.config
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework">
<parameters>
<parameter value="Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
Option 2: Programatically, you can also pass ConnectionString name to the DbContext's constructor. like new ApplicationDbContext(MyConnectionString)
Actually all you have to do is change the DefaultConnection connectionString to be your desired connection string. If you used the normal settings for a new MVC 5 project, and the identity tables do not exist in the new DB they will be created there automatically.
You do not have to edit the portion of the connection string and you do not have to edit the DbContext constructor unless you want to change the conntectionString name and are not OK with replacing the default connection string.
If you are OK with replacing the default connection string, you should be able to just replace it... this worked for me.
I found this article helpful as well:
http://www.typecastexception.com/post/2013/10/27/Configuring-Db-Connection-and-Code-First-Migration-for-Identity-Accounts-in-ASPNET-MVC-5-and-Visual-Studio-2013.aspx

Microsoft Unit Testing with ASP.NET membership provider

Is anyone else frustrated with the built in ASP.NET unit testing framework? The problem I am having is connecting and testing against the Membership provider for ASP.NET in a MVC3 application. It looks like the database connection has not been established or that there is a different set of rules in place then when I run the application normally. Here are the two scenarios.
1) Attempting to find an existing user by name:
Unit Test -
[TestMethod]
public void RegisterTest()
{
AccountController target = new AccountController();
RegisterModel model = new RegisterModel() { UserName = "existinguser", Email = "email#test.com", Password = "Password", ConfirmPassword = "Password" };
actual = target.Register(model);
}
Code chunk from the AccountController -
MembershipCreateStatus createStatus;
MembershipUserCollection members = Membership.FindUsersByName(model.UserName);
MembershipUser user = null;
if (members.Count > 0)
createStatus = MembershipCreateStatus.DuplicateUserName;
Result -
When I step into this code the members array is empty even though I know this user to be in the system. Is there some trick to establishing a connection to the membership store in the unit testing application? I have attempted using the datasource attribute with no success.
2) Attempting to create a new membership account:
The unit test is the same as above however I am passing a new user that is not already in the system. When I step into the controller and get to the following line it gives me a membershipCreateStatus of 'InvalidQuestion'. This seems odd since when running this live I don't have that problem and can create accounts with the line as it is.
user = Membership.CreateUser(model.UserName, model.Password, model.Email, string.Empty, string.Empty, true, null, out createStatus);
Thanks in advance for your help. I am really trying to do this test first method but it's making it harder using the built in testing framework. Certainly there is a way to connect to the DB for all the unit tests (not providing a connection for each test) and simulate the same actions I would through a browser.
When you run your unit tests it will effectively run as a new application and will therefore use its own config file - in other words not web.config that your MVC app uses. So what I would guess you are missing without more information is an entry in the app.config file in your test project, for the connection string to the database that holds your membership information (you may also be missing app.config).
If you are trying to take a TDD approach you should be writing unit tests and if you need to connect to a database for the unit tests to run, they are probably integration tests rather than unit tests. Because the Membership classes use static methods this makes things difficult. What I would recommend is wrapping the membership functionality up in it's own service with a corresponding interface (IMembershipService for example) which can then be injected by your IoC container. For the purposes of your unit tests, you can then simply mock the IMembershipService interface that you created with no need to connect to your database.
I had the same problem. And yes it looks like my unit tests are more like integration tests but I just needed to test the controllers and speed wasn't a concern at this point in the project. I basically added all the sql memberbership config and connection string from the MVC 3 project's web.config to test project's app.config and the membership provider worked when the unit tests ran. Below is my test project's app.config in it's entiriety.
<?xml version="1.0" encoding="utf-8"?>
<!--
Note: Add entries to the App.config file for configuration settings
that apply only to the Test project.
-->
<configuration>
<appSettings></appSettings>
<connectionStrings>
<add name="ApplicationServices" connectionString="mySqlServer;initial catalog=mySqlMembershipDB;persist security info=True;user id=mySqlUser;password=mySqlPassword;" providerName="System.Data.SqlClient" />
</connectionStrings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.5.0" newVersion="4.0.5.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.web>
<membership defaultProvider="AspNetSqlMembershipProvider">
<providers>
<clear />
<add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
</providers>
</membership>
<profile defaultProvider="AspNetSqlProfileProvider">
<providers>
<clear />
<add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</profile>
<roleManager enabled="false" defaultProvider="AspNetSqlRoleProvider">
<providers>
<clear />
<add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
</providers>
</roleManager>
</system.web>
</configuration>

Resources