Deploying a site as a role to Azure - DirectoryNotFoundException - approot / siteroot - asp.net-mvc

I've been examining the event logs for the WebApp I'm trying to automatically deploy and the only problem I can find is this (Azure event log):
An unhandled exception occurred. Type: System.IO.DirectoryNotFoundException Process ID: 1784
Process Name: WaIISHost
Thread ID: 1
AppDomain Unhandled Exception for role Website_IN_0
Exception: Could not find a part of the path 'E:\approot'.
So I have a poke and sure enough, nothing lives there and the directory doesn't even exist. However I then realise the site exists in E:\sitesroot.... so why is it looking in approot?
This is my service definition:
<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="WebsiteAzure" xmlns="etc">
<WebRole name="Website" vmsize="Small">
<Sites>
<Site name="Web">
<Bindings>
<Binding name="Endpoint1" endpointName="Endpoint1" />
</Bindings>
</Site>
</Sites>
<Endpoints>
<InputEndpoint name="Endpoint1" protocol="http" port="80" />
</Endpoints>
<Imports>
<Import moduleName="Diagnostics" />
</Imports>
</WebRole>
</ServiceDefinition>
Is that right?
For the record the deployment works fine with visual studio but i'm trying to automate with powershell which is where I'm getting the issue. I'm pretty sure it has all the .dlls it requires and the config and definition are correct so why is it choking on this directory?

I would suggest using New-AzureServiceProject and add-azure*webrole to scaffold the project locally, and using Publish-AzureServiceProject to package and publish to Azure.

Related

IIS Application Pool Identity permissions reset on every Visual Studio app Publish

Following the instructions in this questions I can successfully change the permissions for the application pool identity
However, after I publish the web app...
The application pool identity's has been reset to just Read
How can I give the application pool identity full permissions even after I re-publish the web app? The same behavior also occurs if I give IUSR full permissions.
As far as I know, if you use Web Deploy from Visual Studio, the publish will overwrite the ACLs on the server by clearing them to the inherited defaults of the parent.
To avoid update ACL each time when you publish your web application.
You could try to add below command in your PublishProfiles's pubxml.
<IncludeSetAclProviderOnDestination>False</IncludeSetAclProviderOnDestination>
Details publish profile as below:
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is used by the publish/package process of your Web project. You can customize the behavior of this process
by editing this MSBuild file. In order to learn more about this please visit https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<WebPublishMethod>MSDeploy</WebPublishMethod>
<LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
<LastUsedPlatform>Any CPU</LastUsedPlatform>
<SiteUrlToLaunchAfterPublish />
<LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
<ExcludeApp_Data>False</ExcludeApp_Data>
<MSDeployServiceURL>http://localhost:9825/</MSDeployServiceURL>
<DeployIisAppPath>WebFormApplication</DeployIisAppPath>
<RemoteSitePhysicalPath />
<SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>
<MSDeployPublishMethod>InProc</MSDeployPublishMethod>
<EnableMSDeployBackup>False</EnableMSDeployBackup>
<UserName />
<_SavePWD>False</_SavePWD>
<IncludeSetAclProviderOnDestination>False</IncludeSetAclProviderOnDestination>
<PublishDatabaseSettings>
<Objects xmlns="">
<ObjectGroup Name="DefaultConnection" Order="1" Enabled="False">
<Destination Path="" />
<Object Type="DbCodeFirst">
<Source Path="DBContext" DbContext="WebFromIdentityTest.Models.ApplicationDbContext, WebFromIdentityTest" Origin="Configuration" />
</Object>
</ObjectGroup>
</Objects>
</PublishDatabaseSettings>
</PropertyGroup>
<ItemGroup>
<MSDeployParameterValue Include="$(DeployParameterPrefix)DefaultConnection-Web.config Connection String" />
</ItemGroup>
</Project>
Then you will find the permission will not be changed after you publish the application.

WCF WebService Error

Error
Error: Cannot obtain Metadata from
localhost:81/WebServices/Legacy.svc If this is a Windows (R)
Communication Foundation service to which you have access, please
check that you have enabled metadata publishing at the specified
address. For help enabling metadata publishing, please refer to the
MSDN documentation at
http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange
Error URI: localhost:81/WebServices/Legacy.svc Metadata
contains a reference that cannot be resolved:
'localhost:81/WebServices/Legacy.svc'.
My Web.Config
<system.serviceModel>
<services>
<service name="Web.WebServices.Legacy" behaviorConfiguration="serviceBehaviorsZero">
<endpoint address=""
name="SspService"
binding="basicHttpBinding"
bindingConfiguration="basicHttpBindingZero"
contract="Web.WebServices.ILegacy" />
<endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange" />
</service>
</services>
<bindings>
<basicHttpBinding>
<binding name="basicHttpBindingZero">
<security mode="None">
</security>
</binding>
</basicHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="serviceBehaviorsZero">
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
Why I not able to access my webservices using WCF Test Client?
When I acess via URL localhost:81/WebServices/Legacy.svc in browser
I get this error
The filename, directory name, or volume label syntax is incorrect.
Update: My .svc file code
<%# ServiceHost Language="C#" Debug="true" Service="Web.WebServices.Legacy" CodeBehind="Legacy.svc.cs" %>
[ServiceBehavior(AddressFilterMode = AddressFilterMode.Any)]
public class Legacy : ILegacy
{
public string DoWork()
{
return "https";
}
}
Put just simple file on the web site directory (hello.html), and check if it is reachable (helloworld.html)
Hello World
Hello World!!!
If not working - check your binding settings on IIS, and whether the service and it's application pool is on.
On IIS configuration, choose 'features view', and go to 'directory browsing' + enable.
At the end of the svc put : ...svc?wsdl
First check on your own local environment. After everything fine, you can check from the web.
On Visual Studio, you shall do the basic by creating new web site (new folder), and copy result to the web site (including web.config) - there is a default source code. you can add new function to service (i.e helloworld, which returns a string, and refer it on iservices).
If svc file is not created (old VS versions) - you can create text file of your own, and do some copy+paste to fix the svc file ... on web site, there shall be app_code and app_data folders.
Hope that help.
Good luck!!!

Could not connect to net.tcp://localhost... TCP error code 10061

Referring to a video tutorial about WCF service in windows service,i have created a sample WCF service and hosted that Service with netTcpBinding in Windows Service.(since i want this WCF service to run as windows service)
Its a simple service which adds/deletes/loads employee details, and is consumed by a windows forms application.that worked fine,when i build the whole solution(consisting wcf service + windows service + client app), however when i wanted to verify that my client isn't directly referring to the project in the solution, so i excluded both the services(wcf+windows) from my solution. it stopped working throwing an error, reading:
Could not connect to net.tcp://localhost:8010/EmployeeService.Service1/. The connection attempt lasted for a time span of 00:00:02.0180000. TCP error code 10061: No connection could be made because the target machine actively refused it 127.0.0.1:8010.
Important point that might help to answer:
WCF service and windows service have identical app.config
Windows service is running as a service
this is my client app.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<netTcpBinding>
<binding name="netTcpEndPoint" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" transactionFlow="false"
transferMode="Buffered" transactionProtocol="OleTransactions"
hostNameComparisonMode="StrongWildcard" listenBacklog="10"
maxBufferPoolSize="524288" maxBufferSize="65536" maxConnections="10"
maxReceivedMessageSize="65536">
<readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
maxBytesPerRead="4096" maxNameTableCharCount="16384" />
<reliableSession ordered="true" inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Transport">
<transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
<message clientCredentialType="Windows" />
</security>
</binding>
</netTcpBinding>
</bindings>
<client>
<endpoint address="net.tcp://localhost:8010/EmployeeService.Service1/"
binding="netTcpBinding" bindingConfiguration="netTcpEndPoint"
contract="Service1.IService1" name="netTcpEndPoint">
<identity>
<userPrincipalName value="user#company.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>
any help would be greatly appreciated....
Found the answer myself, hope it helps other looking for it...
I found that event of worker_DoWork() is not triggered, so add worker.RunWorkerAsync(); as shown in the code below to your windows service
protected override void OnStart(string[] args)
{
worker = new BackgroundWorker();
worker.RunWorkerAsync();
worker.DoWork += new DoWorkEventHandler(worker_DoWork);
}
Delete the Service reference from client project, add it again, since it makes changes to your app.config file.
Just a quickie note that may help some folk:
This error came up between two computers that controlled a Perkin Elmer - Thermo Fisher Scientific Liquid Handling apparatus (robot).
McAfee Antivirus was interfering with their communication and uninstalling McAfee banished the error.
MS Security Essentials Antivirus did NOT interfere.

Log4Net works on Dev machine, fails when deployed to shared host (using same db/connstring)

I have log4net configured and working fine on my local machine, however when I deploy to my host (godaddy) it fails silently. I am using the same database/config file on my dev machine, and on the host. My log4net reference is set to copy local, and the log4net.dll, .pdb, and .xml exist in the bin on the host. This is an asp.net mvc app.
Edit: No exceptions are thrown, and the application runs as expected (minus the logging)
This is running on SQL Server 2005
The webhost is IIS 7
salient details of my config are:
<root>
<level value="DEBUG" />
<appender-ref ref="AdoNetAppender" />
</root>
<appender name="AdoNetAppender" type="log4net.Appender.AdoNetAppender">
<bufferSize value="1" />
<connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
Anybody have any ideas on things to check?
In my experience, log4net usually swallows any internal errors, simply resulting in log statements that do not produce any results.
What you may want to try is enable log4net's internal logging. You can do this by adding the following to your appSettings section:
<add key="log4net.Internal.Debug" value="true" />
This sets the property LogLog.InternalDebugging to true. log4net will now log to the standard output and error streams and to configured trace listeners.
You can use the following configuration to capture any messages logged to tracing:
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<add name="myListener"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="c:\TextWriterOutput.log" />
<remove name="Default" />
</listeners>
</trace>
</system.diagnostics>
All messages logged by log4net internally will appear in TextWriterOutput.log. If you get a SecurityException when you add the trace listener to your configuration, then very probably the apppool identity does not have sufficient rights to create a file at the specified location (in the example: c:\). Try another location or give the apppool identity sufficient rights.
I've just been able to resolve this problem by downloading and using the latest build of log4net (revision 1072765) from SVN repository http://svn.apache.org/viewvc/logging/log4net/trunk/
Apparently this problem has been fixed long time ago but who knows when log4net 1.2.11 is going to be released.

How to upload web.config file using WebDAV on IIS7?

I want to copy an ASP.NET MVC website to a remote IIS 7 server using WebDAV. I have created a site in IIS, enabled WebDAV and assigned a special application pool I have named "WebDAV Application Pool". Using a Windows 7 or Vista client I'm able to mount the remote site as a network drive. So far, so good.
However, I have problems uploading web.config files to the remote site. One problem is that as soon as a web.config has been uploaded it is used to configure the WebDAV site. The web.config file in a Views folder of a MVC project effectively blocks access to that folder.
To work around this problem I have configured the application pool in the applicationHost.config file:
<configuration>
<applicationPools>
<add name="WebDAV Application Pool"
autoStart="true"
enableConfigurationOverride="false" />
</applicationPools>
</configuration>
The interesting part is the 'enableConfigurationOverride` attribute:
When true, indicates that delegated settings in Web.config files will processed for applications within this application pool. When false, all settings in Web.config files will be ignored for this application pool.
Doing this makes it possible to upload a web.config file to the Views folder without breaking access to the folder.
However, I'm still unable to upload a web.config file to the root folder. I have the following settings in the applicationHost.config file to ensure that request filtering doesn't interfere with WebDAV:
<configuration>
<location path="webdav.mysite.tld">
<system.webServer>
<security>
<requestFiltering>
<fileExtensions applyToWebDAV="false" />
<verbs applyToWebDAV="false" />
<hiddenSegments applyToWebDAV="false" />
</requestFiltering>
</security>
</system.webServer>
</location>
</configuration>
In particular hiddenSegments will normally block access to web.config but setting the applyToWebDAV attribute to false should ensure that this file isn't blocked when using WebDAV.
Unfortunately, I'm still unable to copy my web.config file to the root folder of the site. Doing drag and drop in Windows Explorer to the mapped WebDAV network drive will result in the following error message:
Error 0x80070057: The parameter is incorrect.
On the wire it seems that the HTTP status 400 Bad Request is returned.
Is there anything I can do to configure WebDAV on IIS 7 to avoid this problem?
Followup
Currently I'm unable to reproduce the problem I described above. Perhaps I had to restart something or some other unknown factor fixed my problem. The bottom line is that I now can publish a web site using WebDAV.
1) Open up %windir%\system32\inetsrv\config\schema\WEBDAV_schema
2) Add the following inside of the configSchema section
<sectionSchema name="system.codedom">
<element name="compilers">
<collection addElement="compiler" removeElement="remove" clearElement"clear">
<attribute name="language" type="string" isCombinedKey="true"/>
<attribute name="extension" type="string" isCombinedKey="true"/>
<attribute name="type" type="string"/>
<attribute name="warningLevel" type="int"/>
<collection addElement="providerOption">
<attribute name="name" type="string" isUniqueKey="true"/>
<attribute name="value" type="string"/>
</collection>
</collection>
</element>
</sectionSchema>

Resources