How to disable HttpHandlers for production server - c#

My website is using the MSCaptcha library for captcha functionality. The implementation requires handlers to be defined in the web.config file, a web/httphandler for older IIS and the development server, and a webServer/handler for IIS7+.
Now, every time I publish my project to the production server (which runs IIS7), I get an internal server error message because http handlers have been defined in the config file. Once removed, the website runs perfectly. However, when I am testing locally I need to have http handlers defined as the dev server doesn't seem to read webServer/handlers.
Obviously one solution is to simply remove the httphandlers temporarily every time I publish my website to the production server, but since I do this pretty often it is a bit cumbersome. Is there any way to specify when the http handlers should and should not be included in the config file?

Use configuration file transforms and build names to accomplish this. Create web.config that has the dev/local setup, then create a transform for release mode that removes your entry and creates the proper IIS7+ one.
Then whenever you deploy release mode it'll be right for your release environment!
This functionality is built into VS, but for non-web apps it won't work without using something like SlowCheetah.
Examples:
http://msdn.microsoft.com/en-us/library/dd465326.aspx

Related

How can I validate my web.config before I publish according to the publishing profile?

I have a few different publishing profiles, for publishing to either our test sites or to our live sites. We also have various 'test' versions of our databases for when we're adding new features. At the moment, I manually modify the web.config before publishing depending on where I'm publishing to. It's never happened, but it's conceivable that I could forget and publish to the live site with a connection string to our 'test' database (this would be very bad).
Is there any way that I can run some sort of routine immediately before publishing that just checks the web.config connection string, and if I'm publishing to live and the connection string is not to the live databases, then it'll refuse to publish?
That would give me a lot of peace of mind, that I've made it impossible for me to do something very stupid.
You can setup web.config transformations:
https://msdn.microsoft.com/en-us/library/dd465318(v=vs.100).aspx
When you configure the transformation files, the web.config will be transformed automatically at publish time based on the Solution Configuration chosen for the deployment.
So, for instance, the production connection string from the Web.Release.config would be placed in the resulting web.config which is eventually deployed.

Easiest way to make web.config transforms for deployment?

Anyone have a preferred method for making web.config transforms? I am curious as to what others have done for this. I hate having to continuously update the web.config every time I update or republish.
A few years ago Scott Hanselman gave a solution using pre-build events and batch files:
http://www.hanselman.com/blog/ManagingMultipleConfigurationFileEnvironmentsWithPreBuildEvents.aspx
Basically you maintain a separate different configuration for each build and run the batch script pre-build to copy over the Web.Config. The obvious disadvantage is that if you have thirty different build configurations you need thirty different configs, but I find it's nice for projects where you only have two or three configs (like hobby projects, or tools you'll only ever be publishing to internal servers). Plus, it's nice knowing that if you want to you can take extra control of the build process if you want to.
The easiest way to use VS built in support:
You have versions of web.config, for your build versions, (by default Debug and Release)
In the release version you can define transforms what are applied during build. The effective web.config will be the result.
Look into the nuget package for slow cheetah: https://www.nuget.org/packages/SlowCheetah/ This does what you are looking for quite nicely. Be aware that it is for publish transformations only, switching to a different config for local debugging will have no affect.
Create a build configuration for each server you want to deploy to
Example
-Dev Server "copy from debug"-
-Prod Server Debug "copy from debug"-
-Prod Server Release "copy from release"-
Then right click your web.config and select "add config transforms"
You will get new transforms for each configuration you added above.
Now configure your web config transforms for each environment.
Now when you publish you can just select the configuration "Dev, Prod Debug, or Prod Release" and out it goes, no need to update them after that.
Now, the base web.config should always be configured for your local environment, so if you set up in IIS locally it will use web.config without any transforms. Your transforms should transform your local settings in the base web.config to w/e they need to be.

Cannot deploy MVC 4 to server

My web application is just a simple web application made in VS 2010 MVC 4 without any code from outside. It's just default application of VS 2010. I have Deluxe Windows Hosting with Plesk. I've never changed any feature in my account. I copy all my files to "//Root Directory". Beside my files I see various folderssuch as: ", plesk, erro-docs, cgi-bin, logs" - I do not have permissions to delete them.
All my projects are "Release" configuration. I've tried all ways which I met in the Internet:
1.I copied three libraries to bin directory:
System.Web.Mvc, System.Web.Routing, System.Web.Abstractions
These dll's I copied from GAC(C:\WINDOWS\Microsoft.NET\assembly\GAC_MSIL). I putted such strings in web.config: < trust level="Medium"/>. I used local deployment(to directory) in VS2010 by button "Publish". No result.
2.I copied 9 libraries to bin directory:
System.Web.Abstractions.dll
System.Web.Helpers.dll
System.Web.Mvc.dll
System.Web.Optimization.dll
System.Web.Razor.dll
System.Web.Routing.dll
System.Web.WebPages.Deployment.dll
System.Web.WebPages.dll
System.Web.WebPages.Razor.dll.
These dll's I copied from GAC(C:\WINDOWS\Microsoft.NET\assembly\GAC_MSIL). I used local deployment(to directory) in VS2010 by button "Publish". I putted such strings: < trust level="Medium"/>. No result.
3.I copied three libraries to bin directory: System.Web.Mvc, System.Web.Routing, System.Web.Abstractions - these dll's I copied from GAC(C:\WINDOWS\Microsoft.NET\assembly\GAC_MSIL). I putted such strings: < trust level="Medium"/>. I used deployment via ftp option in VS2010 by button "Publish". No result.
4.I copied three libraries to bin directory:
System.Web.Abstractions.dll
System.Web.Helpers.dll
System.Web.Mvc.dll
System.Web.Optimization.dll
System.Web.Razor.dll
System.Web.Routing.dll
System.Web.WebPages.Deployment.dll
System.Web.WebPages.dll
System.Web.WebPages.Razor.dll - these dll's I copied from GAC(C:\WINDOWS\Microsoft.NET\assembly\GAC_MSIL). I putted such strings: < trust level="Medium"/>. I used deployment via ftp in VS2010 by button "Publish" No result.
5.I've tried to upload files via filezzilla. < trust level="Medium"/>. However it was an idle attempt.
6.I've tried to upload files via browsers. However it was an idle attempt.
7.I've tried to upload zip-files via browser and extract them at godaddy server. < trust level="Medium"/>. However it was an idle attempt.
All above-listed attempts result the word on the screen: "nup.com My site is launching soon."
Nothing changes.
I have a question.
What I do wrong?
I've read all articles by Phil Haack http://haacked.com/archive/2008/11/03/bin-deploy-aspnetmvc.aspx. Any help will be gratefully appreciated!:)
Ok - you have a lot of questions inside your single question. I am going to try and take these one at a time as well as some of your commentary so that we can a) understand the build/publish process of an MVC app and b) hopefully get your project running over at GoDaddy.
1.If I change in web.config , then should I recompile my project and upload again?
No, unless you change the web.config locally and you need to upload those changes. If you FTP/connect to the web.config on the actual web server, IIS will automatically restart (reload) your application so that it can apply the web.config changes. After a web.config change, you will notice the first request will take 10-20 seconds. This is IIS restarting your application. If you change the web.config locally, then yes, you should rebuild/reupload.
2.Is it correct to copy a project to root of directory?
The way you have phrased this question makes me think that yes, you are doing it wrong. When you create a project in Visual Studio, you get a solution folder on your actual hard drive. If you are compiling that project, then copying the entire solution folder to your web server, then yes, this is not the correct way to do it. What you want to do is create a Publishing Profile. You can either deploy your application via Web Deploy (unsure if GoDaddy supports this), FTP, or File System. By going through the Visual Studio publishing process, the compiler a) compiles your application per your settings (Debug or Release), b) applies the proper Web.Config transformations and c) only outputs the files necessary to run your application. The third part is important. All of your .cs files (controllers, models, etc) get compiled into a .dll and that is what needs to be deployed, not the actual source code files. The publishing process does this for you.
I would recommend you create a folder on your dev machine somewhere, and then create a publishing profile that publishes your application to that folder. It is the contents of that folder that you want to FTP to your web server. To create a publishing profile, right click your MVC project and select Publish. This will bring up the wizard for you to set things up.
3.What I do wrong?
Kind of hard to say at this point. It could be that you are not compiling your application correctly. FTP sounds bonked, but that is not an MVC/Visual Studio issue. For FTP issues with Plesk on GoDaddy (and other items), check this help link here.
4.how can I see the errors? Should I write a message or what should I do to know more about errors?
You should be able to control this in your web.config. Open your web.config file up and check for a couple of lines. You want to turn off custom errors and set the compilation to debug mode. This does two things. One, the error you get back from the server will be way more detailed and being in debug mode allows IIS/.NET to actually show you the line of code that is causing the problem.
<system.web>
<compilation debug="true" targetFramework="4.5" />
<customErrors mode="Off"></customErrors>
</system.web>
Be aware that if you do have a web.config transformation, this could actually turn these setting off. Ensure that your publishing profile is set to deploy the Debug configuration while you test deploying your site. Once you are happy with your results, set it back to Release configuration so that your site runs faster as well as does not display code lines to potentially bad people if an error does occur.
5.I copied 9 libraries to bin directory...
Ok, this could also be a problem. You do not need to copy anything to your bin directory. If you want to include referenced assemblies in your published project, all you need to do is open the References folder under your project. From there, right click any assembly that you want to include in your project when you publish and select Properties. Inside of the properties pane, you will see the option to Copy Local. Set this to true. This tells the compiler to copy that assembly to the output folder during the publishing process (see, that publishing thing does lots of good stuff for you!) I would do this for all assemblies in your project that are MVC related. You can experiment with this (like one at a time) until you find the right combination of assemblies that you need to include in your project to make it run on the GoDaddy server. I have not used GoDaddy hosting in quite a while, so I do not know what their current capabilities are.
Last thoughts, I think MVC 4 is .NET 4 or higher. Ensure that GoDaddy supports .NET 4 or higher or else you really won't be able to host this on that server (even using bin deploy) and will need to find additional hosting. Azure has some really great deals right now and Gearhost is very reliable but a little pricey (though they are completely simple to use).
EDIT
Just a little more info on GoDaddy - ensure that you set your site up correctly before you try any of this. You need to have Windows hosting (most likely) and it should be setup to use the Integrated App pool (else, it would appear you never uploaded anything since there is no 'default document'). At this point, I wonder if your hosting account was provisioned correctly for what you want to do. http://support.godaddy.com/help/article/6639/do-your-hosting-accounts-support-mvc3-applications (Yes, I know it says MVC 3, but the setup applies equally to MVC 4)
Have you tried bin deploying MVC4?
http://haacked.com/archive/2011/05/25/bin-deploying-asp-net-mvc-3.aspx/
or
http://forums.asp.net/t/1884928.aspx
To answer your question:
Changes to web.config should not require the project to be recompiled.
Hope this helps...
Depends what you've changed, some changes might at least require an application pool reset.
Root of what directory? It should generally be inside inetpub/YOURWEBSITEFOLDERHERE
You have assumed that GoDaddy supports MVC 4, I could only find references to them supporting MVC 3 Support
There are rumours that if you deploy the bin and mvc dll there is a way around this but I couldn't find any details.
Have a read of the MVC 3 deploy instructions
EDIT: In answer to comment below:
Editing could have a knock on effect and so i would advise towards a recompile, e.g. change to medium trust might have an affect if DLLs don't work in partial trust mode, and recompilation might well highlight these issues.
Sounds ok, test by putting a html file up with some text and try and get to it in your browser.
I've seen people talking about it, mostly saying it's not supported, try the MVC deploy instructions above to bin deploy MVC 4; it works with 3, it might work with 4.
I had the same problem with a MVC4 I had running on hosting on Godaddy using Plesk. Suddenly, without any changes, site began to display "Site Launching Soon" Page. At first I thought it was hacked. After calling godaddy support, the agent told me that the site must need at least one html file as a start point (index.html, index.aspx, default.aspx - source: http://support.godaddy.com/help/article/60/what-file-displays-when-someone-browses-to-my-domain-name?locale=en&ci=46061), which seemed odd because it was working fine all the time.
Then, after some trial - error stuff, I could solve my problem by going to the Plesk hosting management, and navigate to:
Websites & Domains > [domain name] > Web Server Settings for domain. And there, change the Default Document setting to "Default".
We never touched that setting, not sure really why it suddenly changed.
Hope that helps!
Hope this helps . . .
Global.asax should be your default index . . . in godaddy server settings.
I had a similar problem and was able to solve it.
I have two other mvc application sites hosted on godaddy, but not with their new plesk hosting.
After calling tech support and not having any luck there I did some reading on their hosting.
Their plesk hosting must have an index.
So, a few hours later it dawned on me to point their start point to my Global.asax in their server settings.
And, viola! my site was up and running.
I've done all actions to deploy correctly but I copied all files to a wrong folder. The problem was that I just copied all my files to a wrong directory. I called to godaddy support and they said that I copied my files to wrong directory.
When I copied all files to "httpdocs" directory then my mvc 4 application start working!:).
Thank you a lot, guys. Good luck.
I was having the same issue until I set customErrors to off (first line). then I started seeing security policy issues which was remedied (second line).
(I'm using Godaddy)

What's the best way to deploy an executable process on a web server?

The original question:
The title of this question might be a bit clumsily phrased, but here's the situation:
I have a .NET web project deployed on my server. It's still in beta, so there's a lot of releasing and re-releasing happening.
I have also written a C# executable in the same VS solution (call it "admin.exe") that runs in the background on the server, periodically performing certain business rule integrity checks and making appropriate insertions to a warning table in the DB.
Question is: what's the best way to deploy this app so that it gets updated whenever I make a new release? It should be running all the time in between releases, so ideally I'd like some sort of setup whereby the shutdown-deploy-startup process involves the minimum possible number of steps.
Thanks!
Edit - Bounty started
The answers given thus far have been helpful and interesting, but haven't provided me with a clear, concise and elegant solution. Please do not assume I have extensive knowledge of deployment projects, because I don't. Bounty goes to the person who can provide a solution that does the following:
Publish the latest version of the web site;
Shut down any instances of admin.exe that are running on the server;
Update admin.exe;
Launch admin.exe;
All of the above should be done preferably in one step, or as few steps as possible, seeing as it will be done repeatedly throughout the life of the product; and
All of the above should be done preferably without requiring installation of any 3rd party software.
Thank you for your help!
Minor edit - clarification
I think a lot of the solutions offered thus far have overestimated the complexity of the problem, so let me clarify: everything that is to be deployed, only has to be deployed on one computer, which also happily has Visual Studio available with all source code. I only need to (1) publish the web site to the web folder, and (2) shut down, reinstall and restart admin.exe on the same server. Isn't there a simple way of doing this in one step? Can it be done with a VS Deployment project?
The "correct" way is probably to set up deployment scripts and installers, but being able to just click publish in Visual Studio and skip going in with remote desktop is a lot more convenient during development.
I have an admin web app that acts as a front end to a command line app - slightly different from what you are doing, but the same solution should work.
Simply add a reference to the console project in the admin web app. Even though you don't call any methods in the console project, the reference will cause the console app to be rebuilt and uploaded when you publish the admin website.
A simple start/stop page added to the web app takes care of steps 2 & 4 - Mine calls Process.Start()/Process.Kill(), though you obviously have the option of a cleaner shutdown depending on the setup of admin.exe.
Below is the code from my start/stop page - I have them set up as web service methods (to facilitate some monitoring stuff you probably won't need), but they should work just as well called from a simple button click method. Note that the service account will need permission to run/stop the process - on a dev box the simplest option is to set up iis to run as an admin user rather than the default service account.
private void KillProcess(string name)
{
var binpath = Server.MapPath("~/bin");
var pp2 = Process.GetProcesses();
var pp = from p in pp2 where p.ProcessName.Contains(name) && !p.ProcessName.Contains("vshost") select p;
foreach (var p in pp)
{
p.Kill();
}
}
[WebMethod]
public void StartQueueRunner()
{
var binpath = Server.MapPath("~/bin");
System.Diagnostics.Process.Start(Path.Combine(binpath, "TwoNeeds.QueueRunner.exe"));
}
[WebMethod]
public void StartQueueRunner()
{
var binpath = Server.MapPath("~/bin");
System.Diagnostics.Process.Start(Path.Combine(binpath, "TwoNeeds.QueueRunner.exe"));
}
It sounds like you need to take a look at a custom MSBuild script for deployment.
MSBuild does much more than just build solutions. You can also use it to copy files and update them, too. A good resource for tasks to do this is the MSBuild Community Tasks here.
You can then include the deployment of your background process alongside the deployment of the Web site deployment.
An alternative approach might be to use Windows Powershell with something like PSExec to remotely execute copy and update commands.
Both these kinds of approach can be automated very well with continuous integration servers such as Hudson. I have a build process that automatically monitors my source code repository, builds the program, deploys to a staging server, runs acceptance tests, then deploys to a preview box. I have another (manual) job that with one click deploys this preview version to live, minimising downtime and (usually) reducing errors from mistiped commands.
There is probably a much cleaner way but maybe install it as a windows service then script the install / uninstall commands using installutil.exe. Then just update the folder where the service sits and re-run the script for each update?
Great service tutorial here
Hope this helps
I would recommend writing a script that you could run on your PC, that would do the deployment over the network (so that you don't have to log in to the target machine every time). I have done it using msbuild, but you can really just go for a batch file.
I assume your admin process is running a windows service (anyway, it makes sense to run it as a service), so you would deploy it like this (this is part of the msbuild script - you can delete the bits with username and password if you don't need it):
<ItemGroup>
<ReleaseFiles Include="localPath\bin\*.dll"/>
<ReleaseFiles Include="localPath\bin\*.exe"/>
<ReleaseFiles Include="localPath\bin\*.pdb"/>
<ReleaseFiles Include="localPath\bin\*.config"/>
</ItemGroup>
<Target Name="Release">
<Message Text="Installing Admin on $(DeploymentMachine) as user $(User)"/>
<Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) stop "Admin"" />
<Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) delete "Admin"" />
<Delete ContinueOnError="true" Files="\\$(DeploymentMachine)\C$\path-to-admin\*.*"/>
<MakeDir Directories="\\$(DeploymentMachine)\C$\path-to-admin"/>
<Copy SourceFiles="#(ReleaseFiles)" DestinationFiles="#(ReleaseFiles->'\\$(DeploymentMachine)\C$\path-to-admin\%(RecursiveDir)%(Filename)%(Extension)')" />
<Exec Command="sc.exe \\$(DeploymentMachine) create "Admin" binpath= "C:\path-to-admin\admin.exe" start= auto obj= $(User) password= $(Password)" />
<Exec ContinueOnError="true" Command="sc.exe \\$(DeploymentMachine) start "Admin"" />
</Target>
Deploying IIS web sites is usually a bit more pain, but if you have everything set up on the target machine then possibly it would work to just copy the files over the network (again using the \DeploymentMachine\share or \DeploymentMachine\C$\path addressing).
Unfortunately deployment is never nice nor elegant :(
Please let me know if you need clarification on anything
Here's a nasty thought. If you're admin.exe isn't doing anything too hard core, why not throw into IIS? To write a C# Web Service, you probably won't need to change much.
To ensure it gets called repeatedly, you could use any variety of methods, like Windows Scheduler to run wget once a minute. Keep concurrent copies from running with a file lock, should it ever take MORE than one minute to complete.
This would make your deployment as simple as a file copy (FTP). I don't even think you need to reboot IIS when pushing a C# DLL. If you do, you can script that up over SSH.
To me, your problem sounds a lot like the deployment problem SharePoint solves through their Timer service running in each WFE, stsadm enqueuing admin tasks, that service dequeuing and running them etc.
What I would do is to
write a service running in each WFE
write a small custom "stsadm" tool so you can enqueue tasks, specify when they need to run, etc.
Another approach: what about using the plain vanilla Windows Task Scheduler? Look here, you can easily enqueue tasks remotely for ex.
I would write a command-line application that would do all of that.
Here is a rough example:
Site.api.publish();
admin.api.shutdown();
while(shell.status("admin.exe") == true) {}; //still running
file.replace("admin.exe", "path-to-compile\admin.exe");
shell.run("admin.exe");
You probably get the point. If you want it to do it automatically just use the Task Schedular to call it every day, or however often you want it.
Store on the server/web the most recent version of the project that is online. eg: in a version.txt the value "2.1.0", or query the database if you have access too.
Your application running on clients, will periodically read the contents of the version.txt file, then compared against the inbuilt(self) version number.
If a patch or minor release is detected eg 2.1.123, spins out a second app(updater.exe) that will quietly
do the upgrade,
it shall download the updated(preferred zipped) project from server/web.
Stop any running instances.
Unzipping the content.
Backup existing files(rename)
copy/install the new version of the project,
Start the application (when the app is restarted successfully it will delete its own backup file).
if a major release is detected eg: 3.0.0
notifies the user there is a major upgrade
if user accepts, download the installer
runs a full installer update
Does this help?
VS Deployment project for a web app is not that easy to master and somewhat not reliable. What I'd suggest:
Modify your Admin.exe into a .NET Windows service. Seebelow why would you need to do it.
Use sc.exe, InstallUtil.exe or installer-building services like installer.codeeffects.com to reinstall your service fast on every deployment. Btw, if I remember correctly, at installer.codeeffects.com you can download a VS example code of how to build a .NET Windows service if you're new to services.
Deployment could be done like this (assuming that your needs in automation is minimal and you're fine deploying almost manually):
Run either of the above mentioned tools to reinstall your service first. The sc.exe and InstalUtil.exe tools support command line. Therefore, if your web app, VS and the service is running on the same machine (your development computer, I assume?), you can right-click the web project in VS, select Properties and set pre- or post-build commands in the Build Events tab there. This way your VS can automatically rebuild and reinstall your service before you publish your web app. This is the main reason why the exe program is not good in your case, a Windows service would serve you better.
Then deploy your web app (assuming it's been build as discussed above). No biggies here, just use the Publish command from your VS or move all files of your web app except for the .cs files, /Properties/ and /obj/ folders. Or, if running from the project's folder, just right click the main page and select "View in Browser" - this will start the run time through VS without starting the debugger.
Sorry for such a lengthy post. Did I understand your question and clarifications correctly? :)
What about making admin.exe a click once deployment. Then in your admin.exe, before you check the integrity of business rules, check if an update is available. If it is, update and then continue on with your checks.
In order to make things simple and make sure I would be able to roll back everything, I would create a PowerShell Script that performed the following actions:
Stop the Application Pool.
Copy the current web app to the
"history folder" so you can rollback
to that version if required
Deploy the new web app
Stop the current admin.exe from
services
Uninstall the admin.exe, by
executing the Uninstall.bat (this is
quite common for Windows Services)
Copy the current admin.exe app to
the history folder (see 2)
Copy the new admin.exe to the
correct location and run install.bat
Start the new service
Start the application Pool
You can automate all of that in a Powershell script (the only thing I'm not sure is about the app pool, but I'm pretty sure that you can do this).
More info on PowerShell can be found here: http://arstechnica.com/business/news/2005/10/msh.ars/2

Correct way to Switch between Dev, Test and Prodcution Services in Builds

I have a client side app (WPF) that hits my web services.
When I am running in dev I want to hit the Dev version of these web services. When I am running in the Test environment I want to hit the test version of the services. Like wise for production.
Since these values are in my app.config file what is the best way to switch between them?
Another single config file way would be to do something along the lines of:
<add key="Service-DEV" value="serviceUrl"/>
<add key="Service-UAT" value="serviceUrl"/>
<add key="Service-PROD" value="serviceUrl"/>
If your app knows which environment it's running in you could then just pull which one you need.
Up to you though. I've also used the multiple config approach with deployment scripts that deploy the correct file to the requested deployable environment.
Are you wanting to switch when you build the app? NAnt may be a way to handle this, or using options within Visual Studio possibly as there is a debug and release build modes.
For the few times I've had to do something similar, I prefer tweaking the hosts file on the client machine so that I can use the same DNS for dev,test and production. I'm not sure if that is practical or not in your case.
I typically maintain 3 separate config files and manually switch them when I install. Scott Hanselman has an article on how to use the build modes along with pre-build events to automatically switch between various configurations. Investigating this as an alternative is on my list of things to do so I can't tell you how well it works in practice.

Categories

Resources