Switching from ASP.NET development server (Cassini) to IIS with MVC applications
Start developing new applications on IIS already is probably good idea, since it is IIS where you application is finally landed to. Working with Cassini is great, cause it fast, requires no maintenance, very easy to start. But it could hide some issues that would surprise you during deployment.
Recently I’ve decided to switch my current Asp.net MVC application from Cassini to IIS. It is done very easy, just go to project, Web tab -> Use local IIS Web Server. Select the option and then click on “Create a virtual directory”, to create a virtual directory for application.
But after I started, application just failed. I’ll share the problems I met and how I fix them.
IIS identity impersonation and path credentials
To make sure your SQL database works fine, you have to configure identity impersonation for application pool and path credentials for folder.
Go to ISS Management, Application Pools, DefaulAppPool, (you could you another app pool for you application), Advanced Settings, Process Model, Identity and set it for your account (you should have admin permissions on this machine).
Go to Virtual folder, Basic Setting, Connect As…, use you credentials.
JavaScript references from Master page
On my master page I’ve referenced number of javascript files, as jQuery, jPost etc. I did it like that,
<script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.blockUI.js" type="text/javascript"></script>
<script src="/Scripts/json2.js" type="text/javascript"></script>
<script src="/Scripts/jquery.postJson.js" type="text/javascript"></script>
* This source code was highlighted with Source Code Highlighter.
That worked fine on Cassini, because virtual is “/”, but as on IIS if you use code like that, it would have some unexpected behavior. Namely, on each view that uses this Master script reference will be mapped differently. For http://localhost/Tracky/Home, it would be be searching for javascript by such URL http://localhost/Tracky/Home/Scripts/jquery-1.4.1.min. And failed to load that. Fortunately there is a way to fix that. Instead of,
<script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
Use
<script src="<%: Url.Content("~/Scripts/jquery-1.4.1.min.js") %>" type="text/javascript"></script>
Url.Content method will properly create a absolute path to script file.
Please make sure, that your Master page is inherited from System.Web.Mvc.ViewMasterPage.
namespace Web.Areas.Public
{
[CoverageExcludeAttribute]
public partial class Public : System.Web.Mvc.ViewMasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
* This source code was highlighted with Source Code Highlighter.
I’ve spend some time, trying to understand why Url.Content does not work for me, thanks to erikzaadi.
All redirected URL have to prefixed with ~/
If you have Redirection somewhere, make sure that redirect URL is prefixed with ~/ (except you explicitly mean it). If you do Redirect("/Pubic/Home")
from /Public/Registration, for instance, absolute URL will be http://localhost/Tracky/Public/Registration/Public/Home, something not expected. With ~/ it will be correctly redirected to http://localhost/Tracky/Public/Home.
Use absolute path for AJAX posts
If you somewhere have a javascript code like this:
$.post('/GetAllTasks/' + userId, null, callback, 'json');
It won’t work either, you have to provide absolute path for resource.
$.post(api + '/GetAllTasks/' + userId, null, callback, 'json');
I receive the API folder from a hidden input on page, initialized with a value from ViewData, which in its turn intialized in controller, using VirtualPathUtility
class.
Conclusions
These are just some issues I met during my switching after I done all above application started to work fine. If you had some other issues during transition to IIS, please make you comments.
You can review changes I did for my project in this commit.
Start developing new applications on IIS already is probably good idea, since it is IIS where you application is finally landed to. Working with Cassini is great, cause it fast, requires no maintenance, very easy to start. But it could hide some issues that would surprise you during deployment.
Recently I’ve decided to switch my current Asp.net MVC application from Cassini to IIS. It is done very easy, just go to project, Web tab -> Use local IIS Web Server. Select the option and then click on “Create a virtual directory”, to create a virtual directory for application.
But after I started, application just failed. I’ll share the problems I met and how I fix them.
IIS identity impersonation and path credentials
To make sure your SQL database works fine, you have to configure identity impersonation for application pool and path credentials for folder.
Go to ISS Management, Application Pools, DefaulAppPool, (you could you another app pool for you application), Advanced Settings, Process Model, Identity and set it for your account (you should have admin permissions on this machine).
Go to Virtual folder, Basic Setting, Connect As…, use you credentials.
JavaScript references from Master page
On my master page I’ve referenced number of javascript files, as jQuery, jPost etc. I did it like that,
<script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="/Scripts/jquery.blockUI.js" type="text/javascript"></script>
<script src="/Scripts/json2.js" type="text/javascript"></script>
<script src="/Scripts/jquery.postJson.js" type="text/javascript"></script>
* This source code was highlighted with Source Code Highlighter.
That worked fine on Cassini, because virtual is “/”, but as on IIS if you use code like that, it would have some unexpected behavior. Namely, on each view that uses this Master script reference will be mapped differently. For http://localhost/Tracky/Home, it would be be searching for javascript by such URL http://localhost/Tracky/Home/Scripts/jquery-1.4.1.min. And failed to load that. Fortunately there is a way to fix that. Instead of,
<script src="/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
Use
<script src="<%: Url.Content("~/Scripts/jquery-1.4.1.min.js") %>" type="text/javascript"></script>
Url.Content method will properly create a absolute path to script file.
Please make sure, that your Master page is inherited from System.Web.Mvc.ViewMasterPage.
namespace Web.Areas.Public
{
[CoverageExcludeAttribute]
public partial class Public : System.Web.Mvc.ViewMasterPage
{
protected void Page_Load(object sender, EventArgs e)
{
}
}
}
* This source code was highlighted with Source Code Highlighter.
I’ve spend some time, trying to understand why Url.Content does not work for me, thanks to erikzaadi.
All redirected URL have to prefixed with ~/
If you have Redirection somewhere, make sure that redirect URL is prefixed with ~/ (except you explicitly mean it). If you do Redirect("/Pubic/Home")
from /Public/Registration, for instance, absolute URL will be http://localhost/Tracky/Public/Registration/Public/Home, something not expected. With ~/ it will be correctly redirected to http://localhost/Tracky/Public/Home.
Use absolute path for AJAX posts
If you somewhere have a javascript code like this:
$.post('/GetAllTasks/' + userId, null, callback, 'json');
It won’t work either, you have to provide absolute path for resource.
$.post(api + '/GetAllTasks/' + userId, null, callback, 'json');
I receive the API folder from a hidden input on page, initialized with a value from ViewData, which in its turn intialized in controller, using VirtualPathUtility
class.
Conclusions
These are just some issues I met during my switching after I done all above application started to work fine. If you had some other issues during transition to IIS, please make you comments.
You can review changes I did for my project in this commit.