Vanilla build server is a concept that says that the build server should have as few dependencies as possible. It should be like vanilla ice cream without any raisins (I have raisins in ice cream). Let me cite the classic (from: Continuous Integration in .NET):
“It’s strongly suggested that you dedicate a separate machine to act as the CI server. Why? Because a correctly created CI process should have as few dependencies as possible. This means your machine should be as vanilla as possible. For a .NET setup, it’s best to have only the operating system, the .NET framework, and probably the source control client. Some CI servers also need IIS or SharePoint Services to extend their functionality. We recommend that you not install any additional applications on the build server unless they’re taking part in the build process.”
I was recently preparing a talk for a conference and setting up a brand new CI server on Windows Server 2012. My ASP.NET MVC project build ended up of course with following error:
error MSB4019: The imported project "C:\Program Files
was not found. Confirm that the path in the <Import>
declaration is correct, and that the file exists on disk.
Well of course. I have a vanilla machine without any MSBuild targets for ASP.NET MVC. I was going to solve it like usual. Create a tools directory, copy the needed targets into the repository and configure the MSBuild paths to take the targets provided with the repository. It worked like a charm in the past and it would work now. But something (call it intuition) made check over at NuGet and to my joy I found this little gem:
“MSBuild targets for Web and WebApplications that come with Visual Studio. Useful for build servers that do not have Visual Studio installed.” Exactly!
I quickly installed it. Configured the MSBuild on the build server to use it like this:
It is a command line parameter I’ve added to the build arguments.
Problem: We have a set of WCF services working on a server. We have an ordinary ASP.NET page that calls one of the services to display its state. When we call that page we is supposed to look like this:
Green page indicates everything works fine.
At a customers we’ve installed the services.
The message was: There was no endpoint listening at http://…/Services/BasicDataService.svc/DeliverServiceState that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.
We quickly discovered that there was nothing wrong with the services. Our app worked fine and we were able to call the “.svc” endpoint in the browser.
But why do we get this exception?
A quick call to the service on the server reviled no response (“This page can’t be displayed”). Ping to the domain reviled “Request timed out.”. Oh, we are getting nearer. Our status page calls the services from the inside of the customers network (both website and services are in the same site on IIS). It looks like we are in NAT. The requests coming to the company router from outside are correctly routed to the server working inside the the company network. The domain name is translated with help of DNS to the global IP address and the company router routes the communication to the server which works with his local IP address. But if we are connecting from inside we are hitting wrong side of the router and it is not able to translate the global IP to the local IP correctly. We are not landing where we supposed to.
Reconfiguration on the company router should do the trick (NAT-Loopback). We informed the company admin to do the change and proceed with a quick workaround. We changed the hosts file to fix it right away.
Hosts is a text file located in C:\Windows\System32\drivers\etc used by the system to locally route the addresses to IPs. We can add the server local IP address and match it with the domain name.
That solved the problem. But soon we got another one.
We added a second binding to the site and our information page wen red once again. This one was actually easy to solve. We called the ”.svc” service directly and got:
This collection already contains an address with scheme http. There can be at most one address per scheme in this collection. If your service is being hosted in IIS you can fix the problem by setting ‘system.serviceModel/serviceHostingEnvironment/multipleSiteBindingsEnabled’ to true or specifying ‘system.serviceModel/serviceHostingEnvironment/baseAddressPrefixFilters’.
Parameter name: item
Yep, multiple bindings present but WCF configured to work with only one. We had to change the:
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
in the services web.config.
We added the second address to the hosts file and voila!