Azure Web Role Startup Action - visual-studio-2012

Okay, the Startup Action option in Azure project in VS2012 is located in the WebRole Properties.
But where is it saved? Is is nowhere in the solution file. After changing the file does not appear modified.
I have to occasionally change these settings after merge, and once changed they are persistent (until the next merge/ modification outside the IDE).
Does someone know where it is saved? I can't find it. no files modified after changing this setting.

If there are no file changes in any of your projects, check if there is a user settings file. This will be in the same directory as the project file (.csproj,
.ccproj) but will have am extension with a U in it (I'm not at a machine I can check this on).

it is in the service definition file (the .CSDEF)
This should be added in the file:
<Startup>
<Task commandLine="" executionContext="elevated" taskType="simple" />
</Startup>

Related

Where do logs go when running ASP.NET Core on IIS 7.5?

I'm posting this and answering it, because this left me stumped for a very long time. I have the following line in my web.config:
<aspNetCore processPath="dotnet" arguments=".\XXX.Server.dll" stdoutLogEnabled="true" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false" />
So apparently, this should be logging to logs\stdout, but when I look, there's nothing there. I went on a wild goose chase, searching the whole disk for anything named 'log' (that returned too much) or 'stdout' (that returned nothing), and still couldn't figure it out.
You could probably check the Event Viewer on your machine -> Application to see if there are any errors logged, which could explain why your log files aren't being generated.
However, the most probable reason is that IIS doesn't have a permission to write to that log folder.
Right click on the folder -> Security
Ensure that IIS_IUSRS user has the following permissions: read and execute, list, write (potentially write is missing by default)
You must make sure the log folder exists! IIS won't make it for you. Such a simple solution to this infuriating problem.
Update - Nov 2022
The Microsoft documentation on Setting up logging for Asp.Net Core on IIS now specifically lists creating the 'Logs' folder as one of the steps. This implies that IIS will not create the folder if it doesn't exist.
This issue was raised in the Asp Net Core Module's repo on GitHub: Issue #30 - Logs are not created if the log folder does not exist. Their suggested workaround is to include a dummy '.log' file in the log directory, so that the log folder is created when you publish the site.
I created the logs folder but still, nothing was logged. I found out that you can use an existing folder under home/logfiles and make it work without creating a folder. This solution worked for me as is:
1) Open the web.config file that is created in the root folder of the published application.
2) Set stdoutlogEnabled to true and stdoutLogFile to \?\%home%\LogFiles\stdout like this:
<aspNetCore processPath="dotnet" arguments=".\SellCarsHereV2.dll" stdoutLogEnabled="true" stdoutLogFile="\\?\%home%\LogFiles\stdout" />
Then you can either go to that path and download the files or use the Azure Portal (if it's hosted in Azure). If you are using the Azure Portal:
1) Go to the app service.
2) Go to Advanced Tools which takes you to https://{your app service}.scm.azurewebsites.net/
3) Click on Debug Console menu --> CMD
4) Click on LogFiles
5) You'll see a file called stdout_*.log and you can click on the pencil to view it. You can also download the file if you want.
According to the provided stdoutLogFile=".\logs\stdout" in your web.config file, the logs directory should be created next to the web.config, inside the publish directory.
To create the logs subdirectory you can use the approach described in the ASP.NET Core directory structure.
Just paste this at the end of your published project's *.csproj file
<Project>
...
<Target Name="CreateLogsFolder" AfterTargets="Publish">
<MakeDir Directories="$(PublishDir)logs"
Condition="!Exists('$(PublishDir)logs')" />
</Target>
</Project>
During the publish process after this change the logs directory should be created if it does not exist in the output directory.
If you run for example:
dotnet publish --output <path_to_your_publish_folder> you should find the logs directory inside the <path_to_your_publish_folder>
I did the following steps in order to get logs:
Create a folder logs and give write access to IIS_IUSRS as described above
Set absolute path in web.config: stdoutLogFile="C:\xxx\xxx\logs"
Recycle the the application pool
Stop, Start the Website
Edit
Step 2 works with relative path too stdoutLogFile=".\logs\stdout"
Check the event viewer. If you're like me you will see an entry in the Application\Event log "Could not create stdoutLogFile c:....logs\stdout_....". You have to create the logs folder there yourself. Once I created the "logs" folder stdout_.... files began to dump into it. Of course also be sure stdoutLogEnabled="true". The location of the expected folder location will be shown in the event viewer log. This is important because it may not be where you think it should be located.
I noticed that the logs are not created immediately when you hit the website. I allowed write access for IIS_IUSRS, created 'logs' folder, restarted app_pool and after few minutes logs were there.

NLog and the include file option

Ok, this has been doing my head in all day. In my UAT setup I have the following in my web.config
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance>
<include file="d:\logs\nlog.config"/>
</nlog>
This pulls in all my rules and targets and has been working fine. That was until I published to our prod server. Same setup but it fails to find the nlog.config file.
At first I thought it was NTFS permissions, but Nlog can write to the same folder location as where this config file resides. I used the internal logging to get an idea what was happening. Nlogs internal log just says that the file doesn't exist. I can't seem to identify why the same setup works in one system but not on another. I've added all relevant NTFS permissions (triple checked) and even went as far as granting 'everyone' read rights as a test, still no joy.
I'm guessing there's something going on within IIS that is stopping the app from reading outside of the root web folder on prod? Which would be odd given it can write to the same place.
It's ok, I was being a donut, well sort of. I created a text file and named it nlog.config not realising that .txt had been stuck on the end. Now the problem makes sense! It never clicked because the .txt was hidden and showing the name as nlog.config in explorer. :o)

What is the name of the web role .config file with SDK 2.2

I have a web role in which I have extended the RoleEntryPoint to do some work that is outside of the scope of the web site. As part of the RoleEntryPoint.Run() my code is required to read from the .config using ConfigurationManager.
While this is a little unusual, using SDK 1.8 I was able to make this work by ensuring that my package included a [The name of my project].dll.config file.
Now that I have upgraded to SDK 2.2 when I try to use .AppSettings or .GetSection() the values are always null, which leads me to believe it is unable to find my file.
I have tried deploying a Worker Role and the .config file still follows the same name pattern that I'm currently using.
I have also tried naming the file WaIISHost.exe.config.
I am aware that ideally this configuration should be included in the .csfg file, but my questions is does anyone know what I should be calling my config file?
UPDATE:
With the help of this question, I now know that the name of the config file it is reading from is E:\base\x64\WaIISHost.exe.Config, but I don't know why this has changed or what I can to overide this.
After much investigation and trial an error I finally have a solution.
The name of the file is still required to be [The name of my project].dll.config, but you need to make sure that this file is in your approot\bin\ directory of your package.
I believe my initial problem was caused by the Copy to Output Directory property being changed to Do Not Copy, although I'm unsure how this happened. If you find yourself in a similar situation you can just add a file with the correct name to your project and set the Copy to Output Directory to be Copy Always.
Once I'd done that however I realised I had another problem. I needed the .config file to have had the config transformations run over it, which this didn't do. To fix this I updated the .ccproj file to have the following:
<PropertyGroup>
<!-- The first two of these targets are what is defined in the base SDK 2.2 targets file. When we upgrade we may need to look reassess this. -->
<CopyRoleFilesDependsOn>
CopyWebRoleFiles;
CopyWorkerRoleFiles;
CopyWebConfigToBin;
</CopyRoleFilesDependsOn>
</PropertyGroup>
<Target Name="CopyWebConfigToBin">
<!-- We need to copy the transformed Web.config to the bin directory so that the RoleEntryPoint has access to the config settings.-->
<Message Text="Copy %(WebRoleReferences.OutputDir)Web.config tp %(WebRoleReferences.OutputDir)\bin\BackOffice.UI.dll.config" Importance="high" />
<Copy SourceFiles="%(WebRoleReferences.OutputDir)Web.config" DestinationFiles="%(WebRoleReferences.OutputDir)bin\[Name of project].dll.config" />
</Target>
This adds an extra target which waits until all of the other files have been copied to the appropriate directory and then picks up the web.config and puts a copy in the bin directory with the correct name.
Are you able to put the config values into the Azure config file (the .cscfg) rather than using the .config file? You can read the values from the cscfg via the RoleEnvironment.GetConfigurationSettingValue static method.
This page explained why it's called WaIISHost.exe.Config and where you can put it in your project.
http://azure.microsoft.com/blog/2010/12/02/new-full-iis-capabilities-differences-from-hosted-web-core/
Like knightpfhor mentioned, you can also use [AssemblyName].dll.config to put these configuration too. It depends on the assembly name of your project, you can check property of your web role project.

AjaxMin not working on Azure site

I am using Microsoft's AjaxMin to minify javascript on my website, which is hosted by Azure. I am using a BuildTask to automatically minify javascript at run time. This build task is specified in the .csproj file.
The process is working on my local environment, however, it does not work when I deploy to my Azure site. The azure site throws 404: file not found errors, when i try to reference the minified version of .js files.
Is it possible to use build tasks on an Azure site? Is there anything I am missing? I have made sure not to include the .min.js files in source control as this (http://www.asp.net/ajaxlibrary/AjaxMinQuickStart.ashx) tutorial suggests, but I am wondering if there is anything specific to Azure that I need to set up.
Thanks!
I've got this working properly in my projects. I'll tell you how I did it, though this may not be the simplest or most straightforward way.
Before we get started, it's helpful to be able to check if your minified files are included in the Azure deployment package without actually deploying. It's pretty easy to do. The .cspkg file is actually a zip-formatted file, so you can open it with any zip archiver. (I like to use 7Zip for this because the right-click -> Open Archive command doesn't require you to rename the file, but you could use Windows Explorer, WinRAR, etc.) Inside the .cspkg you'll see another large file with a .cssx extension. That's a zip file too. Inside of the .cssx you'll find a sitesroot folder with a subdirectory for each website you're deploying, which will contain all your actual website files. So you can poke around in there and see what files are being deployed to Azure.
First, try editing the project file for your web project (the one that contains all the Javascript/CSS files). You can use Notepad, or in Visual Studio right-click the project, select "Unload Project", then right-click again and select "Edit ". Inside the project file, insert a section like this:
<ItemGroup>
<!-- Copy over all the minified CSS & JS to the output directory-->
<Content Include="**\*.min.css" />
<Content Include="**\*.min.js" />
</ItemGroup>
Then reload the project, repackage it, and see if your files are included in the .cspkg file. If they are, then you're done.
If not, there are a couple other things to check. Your minification might not be running at the right build stage. My minification target looks like this:
<Target Name="PrepWebApp" Condition="$(Configuration)=='Release'" AfterTargets="AfterBuild">
If that's still not working and your Web Role has multiple Sites and/or Virtual Applications in it, it's possible that the packaging steps are not running for all of the sites. So when you go to package your project for deployment to Azure, it may still not be running the minification step (along with the web.config transformations, and some other things). If that's the case, see this blog post for a way to fix it.
Just in case that blog post goes away, I'll copy the most relevant bit here. You would put this in the .ccproj file for your web role (with appropriate bits changed to match your project structure):
<PropertyGroup>
<!-- Inject the publication of "secondary" sites into the Windows Azure build/project packaging process. -->
<CoreBuildDependsOn>
CleanSecondarySites;
PublishSecondarySites;
$(CoreBuildDependsOn)
</CoreBuildDependsOn>
<!-- This is the directory within the web application project directory to which the project will be "published" for later packaging by the Azure project. -->
<SecondarySitePublishDir>azure.publish\</SecondarySitePublishDir>
</PropertyGroup>
<!-- These SecondarySite items represent the collection of sites (other than the web application associated with the role) that need special packaging. -->
<ItemGroup>
<SecondarySite Include="..\WebApplication1\WebApplication1.csproj" />
<SecondarySite Include="..\WebApplication2\WebApplication2.csproj" />
</ItemGroup>
<Target Name="CleanSecondarySites">
<RemoveDir Directories="%(SecondarySite.RootDir)%(Directory)$(SecondarySitePublishDir)" />
</Target>
<Target Name="PublishSecondarySites" Condition="'$(PackageForComputeEmulator)' == 'true'
Or '$(IsExecutingPublishTarget)' == 'true' ">
<!--
Execute the Build (and more importantly the _WPPCopyWebApplication) target to "publish" each secondary web application project.
Note the setting of the WebProjectOutputDir property; this is where the project will be published to be later picked up by CSPack.
-->
<MSBuild Projects="%(SecondarySite.Identity)" Targets="Build;_WPPCopyWebApplication" Properties="Configuration=$(Configuration);Platform=$(Platform);WebProjectOutputDir=$(SecondarySitePublishDir)" />
The build task will run in Visual Studio when you build the project. You need to make sure that the minified files are also being deployed to Azure.
I'm guessing that perhaps because the item is being generated at build-time that it's not part of the project itself, and is this ignored by the deployment step.
Please check that the deployment system being used will include all the script files and not just the ones that are in the project itself.

configure common.logging in Azure

I'm developing an app. using Common.Logging (http://netcommon.sourceforge.net/index.html).
A simplified logging configuration (which is done in web.config) is as follows:
<configuration>
...
<arg key="configType" value="FILE" />
<arg key="configFile" value="NLog.config" />
...
</configuration>
As you can see here, the configuration points another configuration file (here, NLog.config) of a backend logging framework.
My question is: when deploying in Azure, what path should I specify here (on dev, NLog.config is copied when building the solution, and placed in the bin directory). In other words, what would be the SAFEST way to get the physical place where the app is deployed in Azure?
Thanks in advance!
In code you can find the current path to the application using Server.MapPath("/"). Now, you can simply make sure that the NLog.config file gets deployed to the application folder:
Add NLog.config to your project (in the root of your web application)
Change the Build Action to Content
In order to test this you can right click on your Azure project an choose Package. In the bin\Release|Debug\app.publish folder of your Azure project you'll find a *.cspkg file. Add a .zip extension to this file and open the file with WinRAR/ZIP/7zip/... Then you'll see a file like this one: SomeWebRole_1a91f39a-49b7-4ece-873f-862172a2fa06.cssx. Here again, add the .zip extension to this file and open it.
If you navigate to the sitesroot\0 folder you'll see the files of the web application in IIS, including the NLog.config file. This way, you' can simply reference the NLog.config file in the Common.Logging settings:

Resources