Hello all
In this post I am going to give a brief description of how to deploy an XAF-based ASP.NET application to a third-party IIS server. Later, we will use this content to prepare a more complete article in the XAF help.
First of all, I want to specify my target:
1. I want to have an ASP.NET application with a "logon" window (it will show UserName and Password editors) that will allow me and my clients to register and review issues.
2. The application will be hosted on an IIS server.
3. The application's database will be located on an MS SQL Server.
4. IIS and SQL Server run on different machines.
I start from a new XAF solution and introduce the "Issue" class:
[DefaultClassOptions]
public class Issue : XPObject
{
private string subject;
private string description;
[Persistent]
private BasicUser createdBy;
public override void AfterConstruction(){
base.AfterConstruction();
createdBy = Session.GetObjectByKey<BasicUser>(((BasicUser)SecuritySystem.CurrentUser).Oid);
}
public Issue(Session session) : base(session) { }
[Size(255)]
public string Subject { get { return subject; } set { subject = value; } }
[Size(4096), Custom("RowCount", "10")]
public string Description { get { return description; } set { description = value; } }
[PersistentAlias("createdBy")]
public BasicUser CreatedBy { get { return createdBy; } }
}
Then I change the authentication strategy to AuthenticationStandard in the ASP.NET application designer and write few lines of code, which create an "Administrator" user in the Updater class of my platform independent module:
public class Updater : ModuleUpdater {
public Updater(Session session, Version currentDBVersion) : base(session, currentDBVersion) { }
public override void UpdateDatabaseAfterUpdateSchema() {
base.UpdateDatabaseAfterUpdateSchema();
BasicUser admin = Session.FindObject<BasicUser> (new BinaryOperator("UserName", "Admin"));
if(admin == null) {
admin = new BasicUser(Session);
admin.UserName = "Admin";
admin.Save();
}
}
}
This is how the application looks at this stage:

By default the Web Site project included in a new XAF solution is configured to run on the WebDev local server, while I need it to run on IIS. To move it to IIS, I open the context menu for the "c:\MyTracker...Web\" project in the solution tree, choose the "Publish Web Site" menu item and publish the site into the "c:\Inetpub\wwwrioot\MyTracker.Web" folder.
Now I open this folder to check what was published: there are all the necessary files except of the files, which are registered in the GAC on my machine. This is acceptable for now, but later I will have to create a full set of files.
Then I start Internet Explorer and try to browse to http://localhost/MyTracker.Web/Default.aspx.
The page shows this "Configuration Error" message:

This error occurs because I didn't register my published site as an IIS application in the IIS manager. So, I have to start the IIS manager and click the "Properties" context menu item for my site, click the "Create" button in the dialog ("Directory" tab, "Application Settings" group).
Then I try again to browse to http://localhost/MyTracker.Web/Default.aspx.... Yes! I see the "Logon" page, type Admin and click the "Log On" button.
A new "Login failed for use ":\IUSR:"." error occurs:

This is a native MS SQL Server error and it means that the connection cannot be established. This happens because I forgot to make the site security settings and the connection string consistent. In XAF, by default the connection string is prepared for "Windows authentication" (the "Integrated Security=SSPI" part of the connection string). This means that the connection to the database server will be established with the permissions of the running process, which is the IIS process and it is working under the 'VSCTPJULY\IUSR_TEAM-STUDIO' user. This user is a very restricted one.
There are two ways to solve this issue:
- configure the operating system, IIS and browser to use current user's system credentials.
- use a specific account to connect to the database server and include its credentials (username + password) in the connection string
The first approach requires that each customer has his/her own account in the local network. This could be acceptable for internal use (we are using an internal XAF-based tool in this way), where the whole application environment is in one hand: IIS, database server, network, Active Directory server and so on. To follow this approach I need to return to the IIS manager, open the "Properties" window, go to the "Directory Security" tab and click the "Edit" button. In the dialog I need to clear the "Anonymous access" check box. Then I need to change the XAF authentication to AuthenticationActiveDirectory to use user accounts.
The second approach is better in case you don't own the environment and you are going to host your application on a third party IIS and database server, Then most likely you also will receive one database account and will not have ability to control Windows Active Directory users.
I will prefer the second way and specify the UserName and Password in my connection string. For simplicity, I will not try to secure it in my application, though there are ways to make it secured. For details on this please see MSDN.
Now I return to Visual Studio and move the connection string from code into the Web Site's configuration file:
<connectionStrings>
<add name="ConnectionString" connectionString="User ID=sa;Password=1;Pooling=false;Data Source=(local);Initial Catalog=MyTracker"/>
and add a single line of code to read it:
protected void Session_Start(Object sender, EventArgs e) {
WebApplication.SetInstance(Session, new MyTrackerAspNetApplication());
WebApplication.Instance.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
WebApplication.Instance.Setup();
WebApplication.Instance.Start();
}
After this, I compile the Web Site and publish it again, start IE and browse to the http://localhost/MyTracker.Web/Default.aspx page.
Voila! It's working:

So, I have successfully started my locally deployed XAF ASP.NET Application.
The next step is to deploy it to a separate server and configure a database on another separate server (until now I didn't care about it because it was created automatically when I ran my application from Visual Studio).
Currently I have a working application on my local IIS with an existing database. The next step is to deploy it to a separate server.
First of all, I will collect all the necessary assemblies (all of them are enumerated in the <assemblies> section of my Web.config file).
About half of the list are System.XXX assemblies and the others are DevExpress.XXX assemblies. I will copy only the DevExpress.XXX assemblies into the "Bin" folder of my application:
<add assembly="DevExpress.ExpressApp.v7.3, Version=7.3..."/>
<add assembly="DevExpress.ExpressApp.Security.v7.3, Version=7.3..."/>
<add assembly="DevExpress.ExpressApp.Web.v7.3, Version=7.3..."/>
<add assembly="DevExpress.Persistent.Base.v7.3, Version=7.3..."/>
<add assembly="DevExpress.Persistent.BaseImpl.v7.3, Version=7.3..."/>
<add assembly="DevExpress.ExpressApp.Objects.v7.3, Version=7.3..."/>
<add assembly="DevExpress.ExpressApp.Validation.v7.3, Version=7.3..."/>
<add assembly="DevExpress.Xpo.v7.3, Version=7.3..."/>
<add assembly="DevExpress.Web.v7.3, Version=7.3..."/>
<add assembly="DevExpress.Data.v7.3, Version=7.3..."/>
<add assembly="DevExpress.ExpressApp.Images.v7.3, Version=7.3..."/>
<add assembly="DevExpress.Web.ASPxEditors.v7.3, Version=7.3..."/>
<add assembly="DevExpress.Web.ASPxGridView.v7.3, Version=7.3..."/>
All the DevExpress.ExpressApp.XXX assemblies are installed in the "c:\Program Files\Developer Express Inc\eXpressApp Framework v7.3\Sources\DevExpress.DLL" folder. The rest of the DevExpress.XXX assemblies are DXperience assemblies and they are installed in the
"c:\Program Files\Developer Express .NET v7.3\Sources\DevExpress.DLL" folder. Also all these assemblies are registered in GAC.
Now I copy my site (the "c:\Inetpub\wwwroot\MyTracker.Web" folder) to the other computer and adjust the site properties in the IIS manager. Then I change the server name from "(local)" to "SQLSERVER" in the connection string:
<add name="ConnectionString" connectionString="User ID=sa;Password=1;Pooling=false;Data Source=SQLSERVER;Initial Catalog=MyTracker"/>
There is not yet any MyTracker database on my new database server and I have to create it manually before I can start the application. The XAF distribution includes a tool to create databases in situations like this. It is called "DBUpdater" and it is placed in the "c:\Program Files\Developer Express Inc\eXpressApp Framework v7.3\Tools\DBUpdater" folder during installation. It accepts parameters on the command line:
Usage: DBUpdater.exe -silent <Path_to_app_config_file>
I copy it to the IIS computer and start it for my web application:
C:\Inetpub\wwwroot\MyTracker.Web\DBUpdater.v7.3.exe C:\Inetpub\wwwroot\MyTracker.Web\Web.Config
It fails. :-\
This is very strange. I move back to the local computer, drop the database and start the same command line: it's working, and the database is created successfully. I go to Internet Explorer and browse to "http://localhost/MyTracker.Web": the Logon page is shown. I type my user name and click the "Log On" button. The application seems to work: I see the Issue list and I can create a new issue as well.
It seems that I made a mistake while deploying my site. I go back to it and start debugging: and I see that a CLR exception occurs: "Could not load file or assembly 'DevExpress.ExpressApp.v7.3 :" Yes, of course. This assembly cannot be loaded because I have not installed it into the GAC and I have not placed it near the "DBUpdater.v7.3.exe". To solve this issue I move the "DBUpdater.v7.3.exe" into the Bin folder of my application, which contains all the necessary assemblies and I try to run it again:
C:\Inetpub\wwwroot\MyTracker.Web\bin\DBUpdater.v7.3.exe C:\Inetpub\wwwroot\MyTracker.Web\Web.Config
It is running and it finishes with this error:
>>>
Updating database via connection string:
User ID=sa;Password=1;Pooling=false;Data Source=SQLSERVER;Initial
Catalog=MyTracker
The database doesn't exist. It'll be created now.
The database can't be updated:
An error has occurred while establishing a connection to the server. When connecting to SQL Server 2005, this failure may be caused by the fact that under the default settings SQL Server does not allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server)
<<<
Right, I forgot to change the password in the connection string. I correct it now and start the tool again with this result:
>>>
Developer Express Inc (R) ExpressApp Framework Database Updater.
Version: 7.3.5.4080
Copyright (C) Developer Express Inc 2007. All rights reserved.
Updating database via connection string:
User ID=sa;Password=;Pooling=false;Data Source=SQLSERVER;Initial Catalog=MyTracker
The database doesn't exist. It'll be created now.
------------------------------------------------------------
Executing module update before the database schema update:
MyTrackerModule
MyTrackerAspNetModule
Executing database schema update
Executing module update after the database schema update:
MyTrackerModule
MyTrackerAspNetModule
Database update completed.
Please disconnect all connected users and press <Enter>.
<<<
The database is created: I see it in the SQL Server management studio. I start Internet Explorer and browse to the http://IISServer/MyTracker.Web/ page.
Yes! It's working and I have deployed my application.
As you can see I had to solve some problems related to SQL Server, IIS, operating system security configurations and to the assembly management in Visual Studio. XAF helps you create an application, but it doesn't yet fully automate complex ASP.NET applications deployment scenarios.
In this post, I have changed all computer names, login credentials and internet links. Of course you will have to use your own correct values if you want to follow the description step by step.
Thanks, Dan.
R&D, .NET Team Developer Express Inc.
PS. If you wish to receive direct assistance from our Support Team, use
Support Center at http://www.devexpress.com/Support/Center