IIS Session Lost on Publish Web - c#

Previously with my Web project in Visual Studio 2012 I was able to hit the 'Publish Web' button and as long as I did not make any changes to any .config or .cs files most of the time my session data would persist so I wouldn't have to log in again every time I make a small change to a .css or .html file.
After messing around with some settings in order to get debugging functioning with w3wp.exe now the session data is lost every single time I click Publish Web, even if I made absolutely no changes between publishes.
I don't know what I did to change this but I really need to be able to make changes to static files without having so sign in every single time. How do I stop the session from being killed?

It depends on what you're publishing. Even if you didn't make any changes knowingly, the app domain will unload if:
web.config was copied again (contents don't matter)
bin folder was modified (again, same dlls with newer timestamps are considered modification)
AFAIK, Publish always updates web.config. One thing I'm not sure is whether it updates web.config if you don't have any transforms (.debug.config or .release.config) or not.
There are couple of things you can try:
Set web.config's Build Action to "None". That'd prevent it being copied to output altogether.
Define a new Build Configuration, say "Static Content". Using this Build Configuration, define a new publish profile, say "Static Content". Add these lines to your .csproj file
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
...
<OutputPath>bin\</OutputPath>
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
<ExcludeFilesFromDeployment>web.config</ExcludeFilesFromDeployment>
<ExcludeFoldersFromDeployment>bin</ExcludeFoldersFromDeployment>
</PropertyGroup>
This would prevent these 2 folders from being deployed so your app domain won't unload and session won't be lost. And you can still use the other profile to do a full release when needed.
In your Publish > Settings > File Publish Options, ensure you have "Delete all existing files..." option unchecked.
Hopefully, one or all of these workarounds will resolve your issue.
Update: Based on the comments, here's a simple AfterBuild Target that recursively copies only changed files to publish folder. Simply copy the following code into your .csproj file and tweak the paths appropriately.
<!-- define static content to be copied over -->
<ItemGroup>
<SourceFiles Include="CSS\**\*.css" />
<SourceFiles Include="Scripts\**\*.js" />
</ItemGroup>
<!-- The target that gets executed after build finishes and copies files recursively -->
<Target Name="AfterBuild">
<Copy
SourceFiles="#(SourceFiles)"
DestinationFolder="C:\Publish\YourApp\%(RecursiveDir)"
SkipUnchangedFiles="True"
/>
</Target>
Now when you build, you should see the static content getting published to your publish folder.
Notes:
%(RecursiveDir) copies files recursively, which helps in rebuilding the folder tree. Helpful if you have nested folders such as css\fonts and css\images.
Copy task has several other attributes (such as ContinueOnError, OverwriteReadOnlyFiles) that you may want to tinker with.
You can also use standard VS macros in the destination path (e.g. $(SolutionRoot), $(OutputDir) etc.).

Do you mean asp.net session? If yes then it is restored each time when the application pool is restarted . It could be caused by:
web config change
bin folder content change
IIS app pool recycle
Generally it is a wrong practice to rely on session data. You have to always check for the data existence and restore if not exit without forcing the user to log in.
But you can keep the session alive if you run it in SateServer or SqlServer mode:
Session-State Modes

Solution 1:
Setup a new site in IIS to hold all of your static files. E.g.
-Make sure it uses a different Application Pool than your other site
NewSite/Css/.css
NewSite/Scripts/.js
NewSite/JQuery
NewSite/BootStrap
(don't actually create this structure, you can manage it with a new vs project)
etc
Give it a localhost host header (MachineName and Port) internal access only.
Now Create a new Project in the Solution with your existing project, move said files to it matching a structure like above.
Setup a new publish profile to deploy your css, scripts, etc etc to the New site you made http://{machinename}:port
Call the Profile something like Dev_PublishStatics or Prod_PublishStatics (w/e you want)
Now you can make changes to CSS/Scripts in Project 2 and publish them with resetting Site A
-Lastly
In your Main site, Create virtual directories that point to the directories for Css, Scripts etc etc in the site you made above.
--Notes
You can also move ASPX files etc etc to the new Site and map them via virtual directories too if you want, but the dlls would need to be in both sites Bin folders. But it works, just remember that if you changed code you need to publish to both sites.

Solution 2:
Change the app pool settings,
IIS Manager
-> Application Pools
->-> Select Site Application Pool
->->-> Advanced Settings on the actions menu
Now set Disable Recycle for Configuration Changes to True, this will prevent the site from resetting on configuration changes. You will need to remember to reset it yourself when new code needs loaded.
I also recommend setting
Start Mode = Always Running
Disable Overlapped Recycle = true

Related

WPF Clickonce publish with Microsoft.Net.Sdk

I can successfully build a WPF application with the new csproj format using the Sdk="Microsoft.Net.Sdk".
However, it is a bit of a challenge to publish the said app. The option is definitely not available from the IDE. But what I find a bit puzzling is that the Publish target doesn't seem to be available when you call msbuild directly.
These are some of the top-level properties I set:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
<LanguageTargets>$(MSBuildExtensionsPath)\$(VisualStudioVersion)\Bin\Microsoft.CSharp.targets</LanguageTargets>
<OutputType>WinExe</OutputType>
<PlatformTarget>x86</PlatformTarget>
<Prefer32Bit>false</Prefer32Bit>
<!--<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>-->
</PropertyGroup></Project>
I also set the typical ones associated with the ClickOnce eg PublishUrl, etc. What can I do to get at/expose the Publish target the same way the LanguageTarget above enables "CoreBuild" for the other legacy C# build tasks outside Console, Web and plain libraries.
Further Thoughts:
So, it turns out that on further inspection, there is actually a Publish target. But it does a simple folder/xcopy deployment to a subfolder called Publish rather than creating an app.publish folder and doing the ClickOnce thing.
How does one work around this?
You can manually publish ClickOnce using the Mage.exe (command line) or MageUI.exe (gui) tools. It's not very convenient but it does seem to work if you get everything right. I'll outline what worked for me using MageUI.exe.
Choose the correct version of the utility for the .NET version you're using from:
C:\Program Files (x86)\Microsoft SDKs\Windows\
First publish your application files to a folder. Normally this would be something like:
\\server\share\MyApplication\Application Files\MyApplication_1_0_0_25\
NOTE: I had issues with the space in Application Files, where it would be converted to %20, but I don't think UNC paths support that value. I had to remove the space and renamed the folder to ApplicationFiles. (This will probably break previously published versions though.)
Then use MageUI.exe to create a new application manifest:
On the Name page, give it a name, version, and choose a processor architecture (x86).
On the Files page, enter the directory you published the files to, and then hit populate. It should load all the program files into the DataGridView below.
On the Permissions Required page, I was not able to get it working with anything less than FullTrust. Without FullTrust, when the application was run, nothing happened.
Save the manifest file as MyApplication.exe.manifest to the application folder. (You will be able to sign the manifest when you save it.)
Now create a new Deployment manifest:
On the Name page, enter the same name and version and choose the right processor architecture.
On the Description page, enter Publisher and Product.
On the Deployment Options page, I chose Online Only. I did not include a Start Location.
On the Application Reference page, choose Select Manifest and browse to the application manifest file you previously created.
Save the deployment manifest as \\server\share\MyApplication\MyApplication.application; (you can sign it when you save.)
NOTE: A glitch here seems to be that it will have inferred the wrong relative path when you select the application manifest file. After you've saved the deployment manifest the first time, go select the application manifest file again, and it will now infer the correct relative path. Then hit save again and you should be ok.
There are a lot of things that can go wrong and a lot of ways that the procedure can differ, but these are the steps that worked for me.
(Another thing I had to do during these steps was clear my ClickOnce Application Cache, by deleting the contents of c:\users\username\AppData\Local\Apps\2.0\. But that was probably just because of all the mistakes I made. I would only do this if you get stuck.)
Microsoft is finally adding ClickOnce functionality to SDK Style Winforms and WPF projects in .NET 5.
I was able to put ClickOnce in a WPF net48 project with new SDK style as before of moving to the new SDK.
It was necessary just to put this block in the end of my .csproj file:
<PropertyGroup>
<PublishProtocol>ClickOnce</PublishProtocol>
</PropertyGroup>
<Import Sdk="Microsoft.NET.Sdk.WindowsDesktop" Project="Sdk.props" />
<Import Sdk="Microsoft.NET.Sdk.WindowsDesktop" Project="Sdk.targets" />
<Target Name="ComputeAndCopyFilesToPublishDirectory" />
It does the following:
set SDK to not skip the import of Microsoft.NET.ClickOnce.targets. That is achieved by setting <PublishProtocol>ClickOnce</PublishProtocol>
set SDK to avoid bin/debug/**/* files to be copied to publish directory.
That is achieved by skipping the "ComputeAndCopyFilesToPublishDirectory" target execution. To do so, we've overriden it to an empty implementation.

Prevent Config File From Publishing With Click-Once Deployment

I'm trying to use Click-Once publishing, trouble is, it's publishing also the Config file, which has the connection strings that I use on my development computer, not the correct ones I use in the production environment. How can I prevent the Config file from being published more than the first time? I tried in properties to not include it in the publishing list, but there is no option to do that.
Config files are part of Deployment since they store all the necessary settings which are used inside Addin.
If I understand the problem correctly then, you want to use some setting, say HOSTURL=http://example.com when Addin is in production environment and HOSTURL=http://localhost when you are developing the Addin and you are expecting all this to automatically without human involvement.
Then, you may try one of these:
[1] Try find the ClickOnceLocation and use settings depending upon value the ClickOnceLocation.
Assuming ClickOnceLocation contains "Debug" while you are developing/debugging the Addin.
//CodeBase is the location of the ClickOnce deployment files
Uri uriCodeBase = new Uri(assemblyInfo.CodeBase);
string ClickOnceLocation = Path.GetDirectoryName(uriCodeBase.LocalPath.ToString());
if(ClickOnceLocation.Contains("Debug"))
{
URL = "http://localhost";
}
else
{
URL = //from app.config
}
[2] Updating the app.config by using build configurations
There are some tricks you could use so that a different file with the values to the production server get picked up during publish.
You can have two separate config files one for local deployment/debugging and one for a real published or production version of the application. The debugging config file could point to the localhost server whereas the real published config file could point to the real server. You can then configure the build configurations such that the appropriate config file is picked up depending on the Active build configuration.
To add two different app.config files to the project, you can update the reference to app.config in your project file. The app.config is defined in the project file (vbproj or csproj) with the following xml:
<ItemGroup>
…
<None Include=”app.config” />
</ItemGroup>
There may be other nodes in the ItemGroup along with the app.config node. Delete the just app.config from this ItemGroup node and create a new ItemGroup under the node with the following xml:
<ItemGroup Condition=” ‘$(Configuration)|$(Platform)’ == ‘Debug|AnyCPU’ “>
<None Include=”app.config” />
</ItemGroup>
<ItemGroup Condition=” ‘$(Configuration)|$(Platform)’ == ‘Release|AnyCPU’ “>
<None Include=”publishedapp.config” />
</ItemGroup>
This basically means that the regular app.config file will be used when the Active configuration is set to Debug and the modified app.config with the real production variables stored in the “published” subfolder of the project is used when the active configuration is set to “Release”.
You can change the ItemGroup conditions to match other build configurations that you may have defined. One possibility is to have a separate “Publish” configuration defined based on the “Release” configuration but only used when you are actually going to publish an application.
An additional disclaimer with this process is that the VS project system itself and the designers are not aware of the additional app.config file; Visual Studio is only aware of the original file. The modified app.config with values for a production environment is only used by the msbuild process. So if you update the main app.config through the Settings Designer, the modified app.config will not be updated and you have to manually update the file.
Once you have configured your project appropriately you can simply switch between the different build configurations to change the config file and publish the application from Visual Studio without having to go through the update and re-sign process.

Make config files backup at product uninstall - WIX, .NET, C#

I want to make backup of my application config files. This files are in specified directory. All i want to do is make subdirectory of this directory, and move there this config files on uninstall.
I know that this is possible with WiX custom action, but i think, that there is the simpler way.
I can do this scenario with CopyFile WIX element, but i don't know how to fire it at uninstalling only.
A common way to do this is have the application make a copy of the config file when it first runs, and the copied file is updated and used by the application. The uninstall doesn't remove it (because it didn't install it) but it can be optionally removed with a RemoveFile element or a custom action (and removing with a CA is more straightforward than copying).
One of the reasons this technique is used is that individual config files might be required for each user. In these cases the template installed file is copied by the app to per user locations. Another reason is upgrades and patches. Careless patches and updates can overwrite the original file (because REINSTALLMODE=vamus is used). Also upgrades can be used to deliver updated config files without jumping through hoops figuring out how to preserve the existing config file and yet deliver the new one at install time - the older unchanged template config file can be replaced without impacting current app settings.
Here. Custom action which triggered only on ununstall.
<Custom Action='CREATE_BACKUP' Before='...'>REMOVE="ALL"</Custom>

Azure Web Deploy publishing old version of MVC sites .dll

I deploy my MVC site via a web publish within VS 2013 to an Azure location. I have published many times without issue from the same machine and IP address, but yesterday it stopped working.
The publish is placing an old version of my projects .dll in the bin folder on the site. This version no longer exists on my machine, it isn't the projects current Git state (and has never been the current Git state) and is not the version in my Release, Debug or Demo compiled folder. I don't know where it's coming from.
So when I publish, I get errors relating to the database changes because the model behind my context has changed since this old version.
So currently when I publish I have to FTP into my site and replace the WebPortal.dll file with the one in my machines bin folder, and the the site works fine.
What could be causing it to revert to this old .dll and where is it coming from? Have I somehow excluded my changes past a certain point from the publish?
Note - My views are publishing absolutely fine, it is just the .dll that should contain the current compilation of Models, Controllers etc., but instead contains an old version missing loads of stuff.
JK
There might be an old version of your dll on the server that is not being overwritten during publish. Have you tried checking "Remove additional files at destination" the the settings section of the Publish dialog. That should remove all the files from your target location except the one you publish.
If you are still having a problem after that try publishing to your local file system so you can see exactly what publish is sending to your server.
Update:
Steps to publish web application to file system.
right click on your project in the solution explorer menu and select Publish.
In the profile section of the Publish Web menu select Custom publish type, click next.
Select file system in the Publish method drop-down. You should see the target location text box where you can specify your folder.
Continue with the rest of the publish steps with you usual settings and click publish.
Double check that your Build (Menu) > Configuration Manager > Build Configuration for Release has the tick next to Build for the WebPortal.DLL. If it isn't set to build then it would use an older version.
I had the same problem. Goodness knows where the old dll is coming from but in the end I up-versioned the library to a higher number and it seemed to cure it. I suspect the GAC or temporary files might be part of the problem although I can't find my library there.

ClickOnce configuration deployment - configuration files

I'm deploying an application using ClickOnce, the problem is that the configuration file (xxx.exe.config) is not embedded in the package and there is no option to include it. Another problem with the config is that When I'm trying to manually write it to the directory where it is delopyed (Environment.CurrentDirectory) I'm getting an exception - I have no permissions to do that.
Any ideas on how to deploy the app along with the configuration file? (and to make it writable, because the applications during ti's runtime alters the config values.)
Thanks in advance
You can also change build action for files that you want to include in ClickOnce deploy: Properties for a file → Build Action → set to "Content", this will add the file to the list of Application files in Publish project options.
If you need to publish a file from a referenced project, I didn't find a better solution rather than to Add → Existing Item → On "Add" button, select "Add as Link", then set action to Content and check the list of published files.
The config file should get published automatically; if not, ensure that it is configured to copy to output, and (if that fails) check the publish files (project properties -> publish -> application files; the config file should be marked as "include (auto)" or "include").
You shouldn't attempt to update anything in the app install directory. That is a bad idea generally (since you can't assume you can update "program files" unless you're an admin), but the same holds true for ClickOnce too.
Just create a settings file with some user settings; these will be saved in the user's profile, so can be updated reliably. You can't edit the files deployed via ClickOnce; even if you had access, it would (by default) break the hashing function, and it will refuse to load them. You can turn off the hashing, but... this still isn't a great idea.
When you click on the Properties of your project and go to the Publish tab of the project's properties, click Application Files... then check the 'Show All Files' checkbox. You should see an option to choose your applications config file from there.
In my experience the <*>.exe.config file is usually set to include automatically however.

Categories