I am in need of help with manipulating the web.config of a site programmatically via C#. The site in question hosts a Silverlight 5 application which communicates with the server runtime via WCF RIA services.
The code that I am writing is part of a bootloader for an automated build-deploy-test scenario aimed at testing the WCF Ria service stack. The issue at question is that in order to test the services properly the unit test code needs to be able to communicate with the Ria Services via a new soap endpoint.
To effectively make this work the site needs a copy of the Microsoft.ServiceModel.DomainServices.Hosting dll in it's bin folder, and a new soap endpoint which would make the domain services config section look like the following:
<system.serviceModel>
<domainServices>
<endpoints>
<add name="OData" .../>
***<add name="Soap" type="Microsoft.ServiceModel.DomainServices.Hosting.SoapXmlEndpointFactory, Microsoft.ServiceModel.DomainServices.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>***
</endpoints>
</domainServices>
</system.serviceModel>
While I do believe I could modify the web.config via the C# xml api, I was wondering if there is another way to do so via the ConfigurationManager?
I would do config manipulation as part of the build script.
I am currently using YDeliver as the build/deploy framework in my project and since it runs on top of Powershell, I manipulate XML using the xml api in posh.
Related
I have two servers on which the identical .net 2.0 WCF service code has been deployed. On both servers the code is running in a dedicated web application with a dedicated application pool assigned to it. Both the web applications and the application pools are configured, as near as I can tell from IIS, identically on both machines. Furthermore, both machines have the same exact versions of the .net framework installed.
On one server the SVC info page served up by IIS lists a fully qualified machine name but the other lists a non-fully qualified machine name. I've provided sample URLS to the info page and the results below:
://server1:1995/Service.svc yields:
You have created a service. To test this service, you will need to
create a client and use it to call the service. You can do this using
the svcutil.exe tool from the command line with the following syntax:
svcutil.exe ://server1.domain.com:1995/Service.svc?wsdl
://server2:1995/Service.svc yields:
You have created a service. To test this service, you will need to
create a client and use it to call the service. You can do this using
the svcutil.exe tool from the command line with the following syntax:
svcutil.exe ://server2:1995/Service.svc?wsdl
I wouldn't normally care about this except for the fact that a packaged product I'm using appears to insist that the URL I give it for the WSDL match exactly what the info page states and I can't figure out why it needs to be different for these two (seemingly identical) machines.
Any help would be greatly appreciated!
(please note I had to delete "http" from the hyperlinks above to keep StackOverflow happy)
The solution here was to add the following line to the SVC web.config file. The behavior was inconsistent across different versions of IIS (and possibly the .net CLR) but adding this line normalized the behavior:
<serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
I have been given a WSDL file from a provider and I have added it as a Service Reference to my C# project in Visual Studio 2013.
I can see the relevant classes I need but when I call the functions on them nothing is transmitting from my program. I have configured Wireshark to listen but no data is coming from my program when I run it.
Where in Visual Studio can I see the IP address/URL that the web service is trying to connect to? At some point I assume it establishes a HTTP connection, where can I see this code to check the URL/IP address?
The WSDL file does not contain the address of the service endpoint. You probably created a Service Reference or a Web Reference, which has created a client class for you. If you instantiate this client (lets call it ExampleClient) with the default constructor:
var serviceCLient = new ExampleClient();
Then the URI will be the path of the WSDL file you imported. This mostly works fine if you import a generated WSDL file file the actual service URI, but in your case, you need to tell it where the service is running. You can either pass the service URI in the constructor:
var serviceCLient = new ExampleClient("http://example.com/service/endpoint");
Or edit your app.config or web.config (depending on project type). It will have something like this:
<system.serviceModel>
<client>
<endpoint address="C:\path\to\your.wsdl" etc etc etc... />
</client>
</system.serviceModel>
And you should change the address attribute there.
For old style web references, you can right click on the reference in Visual Studio (under your project in the Web References folder, and select "properties". The properties screen contains a "Web Reference Url" which you can edit to point to the actual service URI.
From an existing WebApplication I use to make calls to WCF services. Proxies for these services was created using Add Service Reference menu. Thus generating >> Web.config in this project.
I have added another class library project to the solution. This project also adds reference to the service. Thus generating >> App.Config file in this project.
I understand, in an N-Tier application, we should have common gateway to the service. Just out of curiosity I would like to know -
For WCF calls originated in WebApp, propagated to class library which config file (App/Web) would be referred
for locating client endpoint configurations ?
The web.config file will be used for locating the service.
The reason is because in this case, the app domain belongs to the web app, not the class library, and the default config file for this app domain is the web.config.
#musefan is correct. It is the web.config that is used.
If you want to, you can split some confuguration sections into seperate files and reference them from the main web.config. You might want to do this so you can maintain the WCF client and server config in a single place to ensure they are consistent.
foe example, if you want to seperate out the <client> section, you would do this:
<client configSource="client.xml" />
Where client.xml is a file containing the relevant client config information.
This blog post tells you how to do it in a bit more detail.
http://blog.andreloker.de/post/2008/06/keep-your-config-clean-with-external-config-files.aspx
We run a web application with many (50+) WCF service hosts (Written in C#, running on Win 2008R2/IIS 7.5) for integration with different external vendors. We would like to add another service to each of these hosts for administration. This service can be generic enough that we have a single service definition which we define in some library which we can reference from the integration projects. But is there a way of actually adding the endpoint only in configuration? That is, I would like to avoid adding a .svc file, and only add some rows in the web.config service-section.
I tried adding this to the web.config:
<service name="Contracts.AdminService">
<endpoint address="AdminService" contract="Contracts.IAdminService" binding="basicHttpBinding" />
</service>
This does not work however. If I add a simple .svc file like below it works
<%# ServiceHost Language="C#" Debug="true" Service="Contracts.AdminService" CodeBehind="Contracts.AdminService.cs" %>
However, I would really like to avoid this so that it is less likely that a mistake is made when setting up a new host (we already do a bunch of automatic stuff with the config file, so adding a new service would be trivial). Is this possible? Any drawbacks?
Found the answer myself after a while. The solution is WCF 4's file-less activation. This let me just add this to my web.config:
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true">
<serviceActivations>
<add relativeAddress="AdminService.svc" service="Contracts.AdminService"/>
</serviceActivations>
</serviceHostingEnvironment>
After this I can access the service by going to http://<hostname>/<path>/AdminService.svc.
WCF services are hosted in a ServiceHost.
ServiceHosts must be manually created when you are not hosting your WCFs in IIS/WAS, as both IIS/WAS interact with the ServiceHost on your behalf.
What you are basically doing inside the .svc file in IIS is instantianting a new ServiceHost.
Because ServiceHost can only host a single service type, if you plan on creating new types of services for adminsitration, you will need a service host for each of those new types.
So, the short answer to your questions is that you can't just add some information in your web.config for the new services you are going to create, you also need a mechanism to instantiate a ServiceHost.
Here's the situation: I want to be able to run my (.net 3.5) WCF service in two modes:
as a regular .exe file, and
as a windows service.
not much of a problem.
I create 2 projects: one console application and one windows service.
Now, I don't want to duplicate the WCF configuration twice (for each project), so I put it in separate .xml files (that can be shared by both apps).
Now each of the app.config files looks like this:
<system.serviceModel>
<bindings configSource="Config\ServiceModel.Bindings.xml" />
<services configSource="Config\ServiceModel.Services.xml" />
<behaviors configSource="Config\ServiceModel.Behaviors.xml" />
</system.serviceModel>
So far, so good - the service works fine both as console and as service.
The problem starts when I try to manipulate the values in the services section:
string exePath = string.Format("{0}MyService.exe", targetDir);
var config = ConfigurationManager.OpenExeConfiguration(exePath);
var serviceModelSectionGroup = config.GetSectionGroup("system.serviceModel");
var servicesSection = (ServicesSection) serviceModelSectionGroup.Sections["services"];
var services = servicesSection.Services;
But services is an empty collection!
I'm guessing I'm missing something here, but what? Should I also call OpenExeConfiguration for each of my .xml files?