Base solution for your next web application
Open Closed

use different connectionString in development and deployment #2729


User avatar
0
fguo created

I am trying "ASP.NET Core & Angular 2.x" v3.3.0. It runs fine on localhost. I am going to deploy it on IIS in our Production server, but I couldn't find instructions in document how to change database on different environment.

On my other projects, I usually list all connectionStrings in appSettings.json, e.g. "connectionStrings": { "developmentConnectionString": "Server=(localdb)\mssqllocaldb;Database=ProjectDB;Trusted_Connection=True;", "productionConnectionString": "Server=ProductionSQL;Database=ProjectDB1;Trusted_Connection=True;" } and use Environment Variable to automatically inject a proper connectionString for development on localhost or production server.

Can you advise me how to implement the similar (or better) way in ASP.NET Zero solution? :?:

Also, on "Getting Started" guide, Database Migrations section, it states: AspNet Zero solution includes a .Migrator (like Acme.PhoneBook.Migrator) project in the solution. You can run this tool for database migrations on development and production(see <ins>development guide</ins> for more information).

I am confused how to "run this tool". I followed the link to "development guide", but couldn't find the section to "run this tool". Can you give me a clue to get more detail instruction? :?:

On my development machine, I use "Entity Framework Migration Command" to create the database and seed it. I wonder how to use it on production environment. :?:

Thanks,


25 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    You can add another configuration file, let's say "appsettings.production.json" and use it here <a class="postlink" href="https://github.com/aspnetzero/aspnet-zero-core/blob/master/aspnet-core/src/MyCompanyName.AbpZeroTemplate.Core/Configuration/AppConfigurations.cs#L28">https://github.com/aspnetzero/aspnet-ze ... ons.cs#L28</a> conditionally for development and production.

    In order to run migration tool, set the connection string in it's config file and just run it as you do for any other console application. You can use migration tool for your production as well. It's just a console app, you can run it locally if you have access to DB from your computer or you can run it on the server where SQL database is located.

  • User Avatar
    0
    fguo created

    The link does not work. I got 404 error while clicking on it. Can you correct it?

    Thanks,

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    This is a private repository, please share your github username and we will invite you.

    Thanks.

  • User Avatar
    0
    fguo created

    I use my email <a href="mailto:[email protected]">[email protected]</a> to sign up my github. Is this what you need?

    Thanks,

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Actually I need username. For example this is my profile page on github <a class="postlink" href="https://github.com/ismcagdas">https://github.com/ismcagdas</a>. You can send the link for your profile page, it contains your username at the end.

    Thanks.

  • User Avatar
    0
    fguo created

    Got it. It is "fgaonet".

    Thanks,

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    You are invited on github. If you don't receive an invitation email from github, please visit this address to accept invitation <a class="postlink" href="https://github.com/orgs/aspnetzero">https://github.com/orgs/aspnetzero</a>.

    Thanks.

  • User Avatar
    0
    fguo created

    Thank you! Now I can see the code file you mentioned. I want to make sure if my appsettings files correct.

    My original *.Web.Host\asssettings.json has 5 items: ConnectionStrings, Abp, App, Authentication, Recaptcha. The first 3 items are: "ConnectionStrings": { "Default": "Server=(localdb)\mssqllocaldb; Database=MyProjectDb; Trusted_Connection=True;" }, "Abp": { "RedisCache": { "ConnectionString": "localhost", "DatabaseId": -1 } }, "App": { "WebSiteRootAddress": "http://localhost:4200/", "CorsOrigins": "http://localhost:4200" },

    Let's say my production host server is named "WebServer", database server is "SqlServer", and url is "http://production.myDomain.com". I will make a *.Web.Host\asssettings.Production.json with these values as: "ConnectionStrings": { "Default": "Server=SqlServer; Database=ProductionDb; Trusted_Connection=True;" }, "Abp": { "RedisCache": { "ConnectionString": "WebServer", "DatabaseId": -1 } }, "App": { "WebSiteRootAddress": "http://production.myDomain.com/", "CorsOrigins": "http://production.myDomain.com" },

    The value of Authentication and Recaptcha will keep same. Is that correct? :?: I am not confident especially for "Abp" setting.

    As for migration, my production database can only be connected from production host server, so I cannot run migration command in my development machine. I am going to run it in the production host server as you suggested. However, in my development machine, I need to run the command in the folder of \aspnet-core\src*.EntityFramework. After I publish the whole projects to production host server, all code files are compressed as .dll, and no such folder exists. Can you advise me how to migrate in this scenario? :?:

    Thanks again!

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    The value of Authentication and Recaptcha will keep same. Is that correct?

    Recaptcha might chage if you are using a different url for your different environments. I understand your point, if you are not happy with that, you can create a 3. setting file for common values but I wouldn't do that because it makes settings more complicatead but it's your choice and since you have source code you can do it however you like.

    I am not confident especially for "Abp" setting.

    If you are not using redis cache, you can delete this setting.

    I need to run the command in the folder of \aspnet-core\src*.EntityFramework

    No, Migrator tool is a console application. You need to copy it's output (files in the bin folder) to your producttion server, configure connection string in appsettings.json and run it anywhere in the production server you like.

    Please continue if I understand you wrong.

    Thanks.

  • User Avatar
    0
    fguo created

    Before publish to IIS, I tried to migrate the database on our producftion SQL server. To keep things simple, I temporarily connect my local machine to the SQL server, and changed the "Default" connectionString on appsettings.json to point our SQL server. And then, I run command "dotnet ef database update" in my local machine under *.EntityFramework folder.

    I found there are 2 appsettings.json files which contains ConnectionString setting. One is under *.Migrator folder, and another is under *.Web.Host folder.

    At the first try, I only changed ConnectionString in *.Migrator\appsettings.json, and run the command. It runs without error, but the database was not created on server.

    At the second try, I changed ConnectionString in *.Web.Host\appsettings.json, and run the command. It runs, and the database was successfully created on server.

    So, may question is why we store duplicated ConnectionString in different projects/folders? :?: The *.Migrator\appsettings.json does not contain other configuration info, except the ConnectionString. Since that it does not affect migration, shall I just delete this file? :?:

    Thanks,

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Actually, the Migrator project uses it's own setting file. Since *.Host and *.Migrator projects can be run seperately, they have different setting files.

    So, don't delete the setting file for Migrator project, otherwise it will not work.

    I think You need to make a rebuild after changing Migrator project's setting file. I assume it didn't work because of that in the first try.

  • User Avatar
    0
    fguo created

    Thank you for your explanation. I will keep both files, and may test again later. Now, I am trying to deploy it onto production server, but got some bumpers:

    As first try, I followed all steps on the instruction on /Documents/Merge-Angular-Client-Server, and publish the *.Web.Host in VS2017 by "Web Deploy". It failed with two errors:

    This error popped up during the publishing: The project system has encountered an error. Value cannot be null. Parameter name: key

    This error showed after publishing stopped: Could not locate \aspnet-core\src*.Web.Core\packages.config. Ensure that this project has Microsoft.Bcl.Build installed and packages.config is located next to the project file.

    I double checked *.Web.Core. There is no such config files.

    As second try, I followed instruction on section "Deployment" on /Documents/Development-Guide-Angular: change assets/appconfig.json file, build by "ng build -prod", and copy the whole dist folder and web.config file onto the root of my web site on server. When I open the url, I got "500 - Internal server error."

    What did I miss? Can you advise me a step-by-step instruction about deployment? I am using IIS on Windows Server 2012 R2.

    Thanks,

  • User Avatar
    0
    fguo created

    Never mind my second try above. I should copy all files under the folder dist, instead of coping the folder. I corrected it, and it seems working now. It still shows error, but that is because I have not published the "core" part. I still need some help to publish the "core" part.

    Thanks,

  • User Avatar
    0
    fguo created

    I tried again to publish Core part. This time, I used VS2017 Publish to Local Folders. Here are the steps I did:

    1. Select “Release” on top menu bar in VS2017, and build the whole solution again.
    2. Publish each project to local folder. As VS2017 default, target location is bin\Release\PublishOutput.
    3. As result, the projects of .Application, .Core, and .Web.Core generated a *.nupkg under bin\Release\PublishOutput. The .EntityFramework, .Migrator, and .Web.Host generated several files under bin\Release\PublishOutput.
    4. Manually copied all files in \aspnet-core\src*.Web.Host\bin\Release\PublishOutput onto the root folder of web site on the IIS of my production server.
    5. Open the url of the web site. I got error: An error occurred while starting the application. See attached screen shot. :cry:

    BTW, our IIS was installed on server by following Microsoft's instruction, and it works fine for our other ASP.NET Core applications.

    Please advise what I missed on publishing the Core part.

    Thanks,

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    I think there is a missunderstanding, you don't have to publish all projects. You just need to publish the project *.Host using VS 2017 and copy it's published content to your website.

    Then you need to configure it's appsettings.json file for

    • connection string
    • website root address
    • CorsOrigins

    After that, if you are still seeing an error page, you can check the Logs.txt file for error message in your published website.

    Please let us know if it does not help you. We will try to help you as soon as possible.

    Thanks.

  • User Avatar
    0
    fguo created

    Although I published all projects, I only copied the publish files on *.Host to my web site root folder. I double checked the appsettings.json as you pointed out. It is correct, I think. But the same error still pops up. :(

    Let's say my production host server is named "WebServer", database server is "SqlServer", the Core part url is "http://Core.myDomain.com", and the Client part url is "http://UI.myDomain.com". The values are: "ConnectionStrings": { "Default": "Server=SqlServer; Database=ProductionDb; Trusted_Connection=True;" }, "Abp": { "RedisCache": { "ConnectionString": "WebServer", "DatabaseId": -1 } }, "App": { "WebSiteRootAddress": "http://Core.myDomain.com/", "CorsOrigins": "http://UI.myDomain.com" },

    I have tried removing the "Abp" settings, but still no luck.

    I searched the whole solution, and found there are still some "localhost" in other code files, such as Startup.cs, LaunchSetting.json, WebCoreModule.cs, and WebUrlService.cs. I didn't touch these files. Do I need to change the "localhose" in these files? :?:

    Thanks,

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    Since you have spent lots of time on this issue, we can try to help you via TeamViewer. We are available between 08:00 to 17:00 (UTC +03:00), is this good for you ?

    If so please send an email to <a href="mailto:[email protected]">[email protected]</a> and we will arrange a meeting.

    Thanks.

  • User Avatar
    0
    fguo created

    I've sent an email to you. Thanks again!

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    We didn't get the email, can you send it again ? Did you sent it from ecag***@bc*****.com ?

  • User Avatar
    0
    fguo created

    I sent it from [email protected]. The "ecag..." is for payment. He is not for development. Can you change it from your record?

    Thanks,

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    I received your email now. Also, I have changed contact email with yours.

    Thanks.

  • User Avatar
    0
    fguo created

    I dug out the error from logs and solved this issue. It is about the remote database security settings.

    When I run the .Host on my localhost and connect the remote database, it is no problem, because I am a domain user which is accepted by the database. When I deploy the .Host on to our web server and first run it, it tries to connect the remote database with a username as "domain\machine$", which is not recognized by the database, and then the connection is denied :!: . As a test, I simply added the "domain\machine$" as a database user. It works now. :D

    On our other web applications, at the user sends the first request with a blank credential, the server simply responses an index page with login form on it, and does not bother database connection. This way ensures the database is always connected with the current user's credential. In case of the database is busy or crash, the server at least can response something (e.g. a public page). Is it possible and easy to modify your code to work this way? :?: It is not a big deal for now, but it keeps the code portable without "domain\machine$", I think.

    Thanks again for your prompt support!

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    There is no setting for this I think but I didn't understand why database is not reached.

  • User Avatar
    0
    fguo created

    Never mind. I will figure out by myself later. It is still acceptable if can't be modified.

    Our web-server and sql-server are physically on different machines. On my issue, the database was reached but denied access due to its security settings.

    Sorry for my long questions! :oops: It solved now, and this topic can be closed.

    Thanks again for your support! :D

  • User Avatar
    0
    ismcagdas created
    Support Team

    I'm glad that your problem is totaly solved :)