Protect IIS folder from being deleted by WebDeploy - asp.net

I have a folder on my web application which is used to store user uploads, i.e. profile pictures, that sort of thing.
When I use WebDeploy, there is an option for "Leave extra files (Do not delete)" which when ticked makes sure that the profile pictures are not deleted.
What I am seeking is a way to ensure that even if that is unticked, a certain folder is safe from deletion. The reason for this being that I don't want another developer to accidentally disable the feature in future. Or me for that matter.
Any ideas? I have seen a few similar questions on here but nothing seems to be relevant to Visual Studio 2010, which is what I am using.

(I assume you're using publish profiles as per Visual Studio 2010 w/ the Azure SDK or Visual Studio 2012 RTM. If you're not, create an MSBuild file called ProjectName.wpp.targets in the project root and put content in that instead)
You can disable all forms of deletes by setting <SkipExtraFilesOnServer>true</SkipExtraFilesOnServer> in your publish profile (equivalent to the checkbox you mentioned).
To skip a particular directory, a comment on this question implies you can use the following syntax:
<ItemGroup>
<ExcludeFoldersFromDeployment Include="FolderName" />
</ItemGroup>
But I've never seen that before and haven't tested it. Failing that, you can specify an explicit skip rule. "FolderName" is being skipped here - keep in mind that AbsolutePath is a regex:
<MsDeploySkipRules Include="SkipFolderName">
<SkipAction>Delete</SkipAction>
<ObjectName>dirPath</ObjectName>
<AbsolutePath>FolderName$</AbsolutePath>
</MsDeploySkipRules>
NOTE: There are some scenarios in which skip rules don't work when using Visual Studio unless you also set UseMsDeployExe to true

You can set specific rules on the target machines using the msdeploy.exe.configsettings file, there is also a msdeploy.exe.configsettings.example file in the same folder. The file is located in %program files%\IIS\Microsoft Web Deploy - folder see Web Deploy Rules
You can set Rules and skipDirectives here and enable whether they are defaulted so you get your expected default behaviour.

Related

exclude folder in project.json

in the new asp.net 5 template there's a project.json in which you can exclude certain directories.
"exclude": [
"wwwroot",
"node_modules",
"bower_components",
"dist",
".tmp"
]
As you can see, I added a few folders like 'dist' and '.tmp', but they are still included in the solution explorer. There's not much documentation about this. How to exculde files/folders from your project in vs 2015?
The "exclude" property does not hide the folder from visual studio, it will not make the folder "disappear" from the solution explorer.
The "exclude" property removes the folder from the compilation search path. It is an instruction to the compiler (Roslyn) not the IDE. As a more comprehensive answer "project.json" is intentionally IDE agnostic. That is why there is both a projecname.xspoj and a project.json which both contain project configuration information. This is necessary to allow for more robust cross IDE and cross platform development.
You can verify this behavior yourself with a simple excercise.
Add a new class file (buildfail.cs) to your existing project (or
create a new project) in the root project folder.
Ensure buildfail.cs has the same namespace as the other source files in the
project, contains compilation errors, and is in the root directory.
You should see build errors in VS. If you don't manually build.
Create a new folder (excludeme) off the project root and move
buildfail.cs to that folder. You should still have build errors.
Add excludeme to the exclude property in project.json. The build errors should be removed because builfail.cs is no longer in the build search path.
You may be wondering what is VS using to know to hide the node_packages folder from the Solution Explorer display. I am unsure and it may not be user configurable but it isn' the exclude property. Comment out node_packages in project.json and you will get build errors (package restore failure) but the folder will still be hidden from Solution Explorer. Since this is IDE specific behavior one would assume that maybe it is defined in projectname.xproj but I found no such property so at this time it would appear to be black box magic by VS.
As of Asp.Net 5 beta-8 and complementary tooling update to Visual Studio 2015, you are now able to exclude/hide folders from being displayed in solution explorer. More information about this, and other changes are outlined in the announcement post. To hide a file or folder, right-click to bring up a context menu and select Hide from solution explorer. This creates an entry in the .xproj file:
<ItemGroup>
<DnxInvisibleContent Include="myhiddenfile.txt" />
</ItemGroup>
Note also that there has been a change to where bower packages are installed by default. Previously, the Asp.Net 5 templates in Visual Studio would install bower packages to a folder called bower_components, a practice familiar to web developers who do not use Visual Studio. However, apparently due to developer confusion, this has been changed to wwwroot/lib. This can be changed by editing the bowerrc file. As such, the bower_components folder does not exist in the new beta-8 templates. Please see this post by Scott Hanselman for more information.
It may not be ideal, but I was able to hide a folder from the solution explorer in an Asp.net 5 project by marking the folder as hidden in the windows explorer properties dialog. I had the .idea folder used by WebStorm showing up so it being hidden was not too big a deal. WebStorm doesn't mind.
It seems like the folder will not be hidden if it is already in the solution explorer. Mark it and it's contents hidden and move it temporarily out of the project folder. Make sure it disappears from the solution explorer before moving it back. It should not show back up. A restart of Visual Studio may also work, I didn't test that.
Rightly or wrongly, here's what I did to get bower_components and .sass-cache out of the way. In my case, node_modules was already excluded from my project somehow, even though it's at the same level with gruntfile.js. I still don't understand why it is treated differently. Anyone know?
First, I set my location like this in the .bowerrc file:
{
"directory": "../../artifacts/bower_components"
}
Then I adjusted my paths as necessary in my gruntfile.js
Also, To get the sass-cache folder out of the way, since I was using grunt-contrib-compass, I configured my compass task with this option:
cacheDir: '../../artifacts/.sass-cache',
There are other ways to do this if you are using other sass / compass tools.
RESULT:
I can now search my entire project for text and not get hits in my libraries.
bower_components and .sass-cache are out of reach of source control.
With the latest Visual Studio you just need to right-click the folder/file and chose "Hide from Solution Explorer".
That will change the "xproj" this way:
<ItemGroup>
<DnxInvisibleFolder Include="wwwroot\" />
</ItemGroup>
Looking at the state of asp.net 5 with visual studio 2015 I can only say that they made it much more difficult and inconvenient to work with task runners like gulp or grunt. Since I'm using Web API 2 to manage my data I switched to Visual Studio Code with bower, gulp and browsersync and this has proven a to be LOT easier and faster with much less clutter.
To make a startup template: https://github.com/Swiip/generator-gulp-angular
Now you can use any editor and you get a clear separation of front end and back end development. Plus you get to know gulp and bower and the (minimal) command line stuff which VS2015 tries to do for you (and fails to do so many times).
Oh yes: you don't have to exclude folders anymore, since the template has a much more sensible folder structure

Use Visual Studio web.config transform for debugging [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can I use Web.debug.config in the built-in visual studio debugger server?
I want to use the Web.config transformation that works fine for publish also for debugging.
When I publish a web app, Visual Studio automatically transforms the Web.config based on my currenctbuild configuration.
How can I tell Visual Studio to do the same when I start debugging?
On debug start it simply uses the default Web.config without transformation.
Any idea?
OK, with the understanding that web.debug.config & web.release.config are for package/publish only. I have come up with a way in which to enable what you are trying to do. I've blogged about it at https://devblogs.microsoft.com/aspnet/asp-net-web-projects-web-debug-config-web-release-config/.
Here is the summary.
Now let’s see how we can enable what the question asker wants to do.
To recap, when he builds on a particular configuration he wants a specific transform to be applied to web.config. So obviously you do not want to maintain a web.config file, because it is going to be overwritten.
So what we need to do is to create a new file web.template.config, which is just a copy of web.config. Then just delete web.config by using Windows Explorer (don’t delete using Visual Studio because we do not want to delete it from the project).
Note: If you are using a source control provider which is integrated into Visual Studio then you probably want to delete web.config from source control.
Also with this we do not want to use web.debug.config or web.release.config because these already have a well defined role in the Web Publishing Pipeline so we do not want to disturb that. So instead we will create two new files, in the same folder as the project and web.template.config, web.dev.debug.config and web.dev.release.config.
The idea is that these will be the transforms applied when you debug, or run, your application from Visual Studio. Now we need to hook into the build/package/publish process to get this all wired up. With Web Application Projects (WAP) there is an extensibility point that you can create a project file in the same folder with the name {ProjectName}.wpp.targets where {ProjectName} is the name of the project. If this file is on disk in the same folder as the WAP then it will automatically be imported into the project file. So I have created this file. And I have placed the following content:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<!-- Make sure web.config will be there even for package/publish -->
<Target Name="CopyWebTemplateConfig" BeforeTargets="Build">
<Copy SourceFiles="web.template.config"
DestinationFiles="web.config"/>
</Target>
<PropertyGroup>
<PrepareForRunDependsOn>
$(PrepareForRunDependsOn);
UpdateWebConfigBeforeRun;
</PrepareForRunDependsOn>
</PropertyGroup>
<!-- This target will run right before you run your app in Visual Studio -->
<Target Name="UpdateWebConfigBeforeRun">
<Message Text="Configuration: $(Configuration): web.dev.$(Configuration).config"/>
<TransformXml Source="web.template.config"
Transform="web.dev.$(Configuration).config"
Destination="web.config" />
</Target>
<!-- Exclude the config template files from the created package -->
<Target Name="ExcludeCustomConfigTransformFiles" BeforeTargets="ExcludeFilesFromPackage">
<ItemGroup>
<ExcludeFromPackageFiles Include="web.template.config;web.dev.*.config"/>
</ItemGroup>
<Message Text="ExcludeFromPackageFiles: #(ExcludeFromPackageFiles)" Importance="high"/>
</Target>
</Project>
Let me explain this a bit. I have created the CopyWebTemplateConfig target which will always copy web.template.config to web.config on build, even if you are not debugging your application in Visual Studio.
This is needed because we still need to support the package/publish process of Visual Studio. Then I extended the property PrepareForRunDependsOn to include the UpdateWebConfigBeforeRun target. This property is used to identify the list of targets which needs to be executed before any managed project is run from Visual Studio.
In this target I am using the TransformXml task to transform web.template.config, using the correct web.dev.***.config file. After that your app starts up using the correct web.config based on your build configuration.
After that I have another target ExcludeCustomConfigTransformsFiles, which I inject into the package/publish process via the attribute BeforeTargets=”ExcludeFilesFromPackage”. This is needed because we do not want these files to be included when the application is packaged or published.
So that is really all there is to it.
To explain the package/publish process a bit more for this scenario. When you package/publish web.debug.config or web.release.config, depending on build configuration, will still be used. But ultimately the file that it is transforming is web.template.config, so you may have to adjust depending on what you have in that file. Questions/Comments?
Andrew is on the right path. When you are using this feature here is how it was designed to be used.
web.config
This is the config file which developers should use locally. Ideally you should get this to be standardized. For instance you could use localhost for DB strings, and what not. You should strive for this to work on dev machines without changes.
web.debug.config
This is the transform that is applied when you publish your application to the development staging environment. This would make changes to the web.config which are required for the target environment.
web.release.config
This is the transform that is applied when you publish your application to the "production" environment. Obviously you'll have to be careful with passwords depending on your application/team.
The problem with transforming the web.config that you are currently running is that a transform can perform destructive actions to the web.config. For example it may delete a attributes, delete elements, etc.
You could just use the 'default' web.config as your development/debugging version, and then the web.release.config would of course continue to be the release version, since its transforms are applied when you publish.
In your debug configuration, add a post-build step, and use it to replace/transform your web.config
Although I agree that the simplest approach is usually the best, I can easily imagine a circumstance where for some period of time you want to connect your IDE to a test database instead of your development database. Although you can specify the development connect strings in your default web.config file, it would be really nice to have a Web.Test.config file so that when you swap your build configuration to "Test", you would automatically get the new settings while still in your IDE.
The historical alternative is commenting out one set of connection strings for another, but these new config transforms held out the hope of finally putting a stake in the heart of that ugly practice. Although one default file for development and a transform for release may work much of the time, adding a post-build step to transform the web.config file is the more complete answer in my opinion.

How to get Visual Studio 'Publish' functionality to include files from post build event?

I am currently attempting to use Visual Studio 2010 'Publish' and MSDeploy functionality to handle my web deployment needs but have run into a roadblock with regards to customizing the package depending on my build configuration.
I develop in a 32bit environment but need to create a release package for a 64bit environment, so in the 'Release' configuration I have a post build event that copies the 64bit version of a third-party dll into the bin directory overwriting the 32bit version. When I use the 'Publish' functionality, even though the correct 64bit dll is being copied to the bin directory, it doesn't get included in the package.
Is there a way to get the 'Publish' to include files that have been copied into the bin directory during a post build event?
I answered a similar but different question at How do you include additional files using VS2010 web deployment packages?.
In your scenario you are using post build event, I would recommend dropping the post build event and implement your actions using your own MSBuild targets instead of post build event. Below you'll find the text of the other answer.
From: How do you include additional files using VS2010 web deployment packages?
Great question. I just posted a very detailed blog entry about this at Web Deployment Tool (MSDeploy) : Build Package including extra files or excluding specific files.
Here is the synopsis. After including files, I show how to exclude files as well.
Including Extra Files
Including extra files into the package is a bit harder but still no bigee if you are comfortable with MSBuild, and if you are not then read this. In order to do this we need to hook into the part of the process that collects the files for packaging. The target we need to extend is called CopyAllFilesToSingleFolder. This target has a dependency property, PipelinePreDeployCopyAllFilesToOneFolderDependsOn, that we can tap into and inject our own target. So we will create a target named CustomCollectFiles and inject that into the process. We achieve this with the following (remember after the import statement).
<PropertyGroup>
<CopyAllFilesToSingleFolderForPackageDependsOn>
CustomCollectFiles;
$(CopyAllFilesToSingleFolderForPackageDependsOn);
</CopyAllFilesToSingleFolderForPackageDependsOn>
</PropertyGroup>
This will add our target to the process, now we need to define the target itself. Let’s assume that you have a folder named Extra Files that sits 1 level above your web project. You want to include all of those files. Here is the CustomCollectFiles target and we discuss after that.
<Target Name="CustomCollectFiles">
<ItemGroup>
<_CustomFiles Include="..\Extra Files\**\*" />
<FilesForPackagingFromProject Include="%(_CustomFiles.Identity)">
<DestinationRelativePath>Extra Files\%(RecursiveDir)%(Filename)%(Extension)</DestinationRelativePath>
</FilesForPackagingFromProject>
</ItemGroup>
</Target>
Here what I did was create the item _CustomFiles and in the Include attribute told it to pick up all the files in that folder and any folder underneath it. Then I use this item to populate the FilesForPackagingFromProject item. This is the item that MSDeploy actually uses to add extra files. Also notice that I declared the metadata DestinationRelativePath value. This will determine the relative path that it will be placed in the package. I used the statement Extra Files%(RecursiveDir)%(Filename)%(Extension) here. What that is saying is to place it in the same relative location in the package as it is under the Extra Files folder.
Excluding files
If you open the project file of a web application created with VS 2010 towards the bottom of it you will find a line with.
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />
BTW you can open the project file inside of VS. Right click on the project pick Unload Project. Then right click on the unloaded project and select Edit Project.
This statement will include all the targets and tasks that we need. Most of our customizations should be after that import, if you are not sure put if after! So if you have files to exclude there is an item name, ExcludeFromPackageFiles, that can be used to do so. For example let’s say that you have file named Sample.Debug.js which included in your web application but you want that file to be excluded from the created packages. You can place the snippet below after that import statement.
<ItemGroup>
<ExcludeFromPackageFiles Include="Sample.Debug.xml">
<FromTarget>Project</FromTarget>
</ExcludeFromPackageFiles>
</ItemGroup>
By declaring populating this item the files will automatically be excluded. Note the usage of the FromTarget metadata here. I will not get into that here, but you should know to always specify that.
I found a workaround for the problem by using the ExcludeFilesFromDeployment element within the project file. I got the idea from Web Deployment: Excluding Files and Folders
So if you need to package project files as they exist in your project directory after a successful build and associated post build steps then do the following.
Edit "Package/Publish Web" project settings and
select Items to deploy to be "All files in this project folder"
Unload the project
Right click on the unloaded project and select to edit the project config
Locate the PropertyGroup element associated to the configuration setting e.g. "Release"
Within the PropertyGroup element add in the following elements and exclude files and folders you don't want in the package
<ExcludeFilesFromDeployment>*.cs;**\.svn\**\*.*;Web.*.config;*.csproj*</ExcludeFilesFromDeployment>
<ExcludeFoldersFromDeployment>.svn;Controllers;BootstrapperTasks;Properties</ExcludeFoldersFromDeployment>
Save and reload your project
This solves my problem for the time being but if there is a better solution then please let me know, as this is not ideal due to the hackery involved, but then again perhaps this is an uncommon deployment scenario?
Select your files or folders and Change Build action as Content from Properties Window.
I know its a old question but none of these worked for me .
In 2017 VS I just right clicked on the extra folder to be published and select publish it worked.
Example:
Adding the bin folder (and it's contents) to the project caused the files to be copied to the publish output directory.
For me, my issue was that I needed to place a proprietary software license file in the bin/ folder, but did not want to copy it manually each deployment.
This was using Visual Studio 2015 Professional
I know this is an old conversation but I came upon it while trying to do the same thing and I thought it would be helpful to add what I found here.
Nearly all the articles about including extra files in your publication use this method of adding the CopyAllFilesToSingleFolderForPackageDependsOn or CopyAllFilesToSingleFolderForMSDeployDependsOn items in the PropertyGroup and they all same something like "I added this to the end of the file ..."
This is what I did and spent an afternoon trying to find why nothing was happening until I realised there was already a PropertyGroup section at the top of the file. When I put my CopyAllFilesToSingleFolderForPackageDependsOn into that section it worked fine.
Hope this saves someone time some day

Best practices for storing an ASP.NET web site in Subversion?

I'm currently working on an ASP.NET project with multiple developers using Subversion for code distribution, but it's quite frankly totally messed up at the moment. The person who set up the Subversion repository have included config files specific to their computer, bin\* directories, and other such things.
I, being the guy who has to check out this repository and get it to run on my computer, am pretty frustrated by this since it's taken me a while to sort it all out to get it to compile at all. Now I'm thinking about writing a document for Subversion guidelines to send to the technical leader at my company so that we can get the process standardized and avoid these kinds of problems.
What I'm looking for is input on the guidelines. Here's the start for them, and hopefully we can make something good out of it:
The file structure should be set up to have third-party libraries checked in outside the build output directories (since they won't be included in the repository.) The name of this directory should be "Libraries".
No machine-specific files should be included in Subversion. Therefore, only a template of Web.config is checked in, which is customized by the developers to suit their machine. This behavior is included in Visual Studio 2010 by default and the individual configuration files (Web.Local.config) automatically have the template (Web.config) applied. The local configuration file still shouldn't be included in Subversion though, so long as it applies for a specific machine.
Solution and project files must not contain any absolute paths.
An ignore list should be set up. Start with:
'
*.user
obj
'
Example file structure for an ASP.NET 2.0 web site with a class library specific to the web site and a third-party library:
'
/trunk/
Libraries/
ThirdParty.dll
MyClassLibrary/
bin/ [Ignore]
obj/ [Ignore]
Properties/
AssemblyInfo.cs
SomeClass.cs
MyClassLibrary.csproj
- Holds references to third-party libraries. For example:
../Libraries/ThirdParty.dll
MyWebApplication/
bin/
ThirdParty.dll [Ignore; copied by build process]
ThirdParty.dll.refresh
- Contains "../Libraries/ThirdParty.dll"
Default.aspx
Default.aspx.cs
Web.config [Ignore]
Web.config.template
MySolution.sln
- Holds list of projects.
- Has reference information for projects.
'
An alternative to using Web.config.template would be to include a Local.config file from Web.config, but this might be less flexible.
When using a Web Application project rather than a Web Site project, the references will be stored in the project file instead of in .refresh files, so the bin/ folder will be ignored.
Can someone see errors in the above suggestions? Is something missing? Does anyone have suggestions for the ignore list? I just started with a couple of entries for now.
I think that you are a good step on the way. But why not put an ignore on the entire bin folder in /MyWebApplication, instead of the files? You wouldn't add your build output to subversion would you? I would definately consider that a bad practice.
Also, if possible, you could add the web.config file to subversion, but in the element reference a new file with appSettings: for example
<appSettings file="local.config">
Then have the local.config file be ignored by svn. That is how I always operate.
But of course that only works if every configurable parameter is in the appSettings (one of the reasons why I dislike the provider model, because all the providers need to get connection strings from a connectionString element, and you cannot reconfigure them to take a connection string from appSettings)
Edit: troethom enlightened me and pointed out, that you can also override the connectionString configuration settings in a separate file
<connectionStrings configSource="ConnectionStrings.config"/>.
So the thing that I would do is place the actual web.config file under subversion control, but let those other files that override the settings locally be ignored by svn.
You should add the .refresh files; not the real DLLs.
The Visual Studio project system sends a list of files that should be added to source control to SCC Providers. AnkhSVN is a Subversion SCC provider that uses this information to suggest adding these files (and not the other files).
VisualSVN and other Subversion clients that only look at file extensions don't get this information from ASP.Net.
(Note: if you remove the .refresh file, Visual Studio will add the DLL to the list of files that should be committed)

ASP.NET Projects with Subversion (VisualSVN Client) - What files should I ignore?

I've just started using Subversion with ASP.NET web applications via the VisualSVN IDE plugin. There are a bunch of files which Visual Studio automatically generates so I don't want to version control these since they're not really part of the codebase and not required to build.
Does anyone have a definitive list of the main files that should be ignored when commiting to Subversion from an ASP.NET Web Application? and how would I go about ignoring these files. If possible I'd like to set it globally so that I don't have to keep doing the same thing for every ASP.NET Web Application that I write and create a new repository for.
Answers
A list of files to ignore as submitted in the answers below,
bin
obj
*.exe
*.pdb
*.suo
_ReSharper.*
*.user
General concensus seems to be that these should be ignored on a per project basis at the creation of the repository. They will then be ignored by all users using the repository.
Not really 'definitive', but I always ignore .suo and .user files and the bin/ and obj/ directories
Here's my ignore list from TortoiseSVN. VisualSVN requires TortoiseSVN and uses its settings.
bin obj *.exe *.pdb *.suo _ReSharper.* *.user
I haven't committed any unwanted (or not committed any wanted) files with this setting.
If you have any WCF service references then you only need to include the files Reference.cs and Reference.svcmap for each service reference.
The AnkhSVN plugin for Visual Studio has a list of files to ignore automatically and will only commits the files needed.
At least that's how I find it. It's taken me a few attempts at setting up the repository correctly but with AnkhSVN only commits a subset of he files that TortoiseSVn wants to commit. If ignores files recompiled on every Build for example.
Depending on your situation, you might want to keep the Web.config out of revision control as well. Different developers might require different configuration files for a website.
I'd recommend setting up a separate directory in your repository with a reference configuration file for the website and ignoring *.config on the actual project directory.
Additionally, to cover case sensitivity issues with "bin", I had to add [Bb]in to mine. So I have:
[Bb]in obj *.exe *.pdb *.suo _ReSharper.* *.user
Also, this link explains how to handle project specific excludes as well so that others get the same exclusion behavior only for the same project when they check it out:
http://svnbook.red-bean.com/en/1.1/ch07s02.html
I used the svn:ignore property on a particular directory to exclude a certain set of files that were copied into there (but I still wanted the directory itself in svn).
Use VisualSVN to do the initial "Add files to repository" and it automagically ignores the stuff you don't want-such as suo files and the bin/obj folders.

Resources