I'm trying to host my WCF service with a custom ServiceHost on IIS. I found a couple of articles on MSDN like this: Custom Service Host. Here, I'm supposed to add something to my services svc file, but I don't have one and I can't add one in visual studio either. Then I found this article: Configuration-Based Activation in IIS and WAS. This says
"The configuration-based activation feature removes the requirement to have a .svc file and therefore the associated overhead."
so I can just create a serviceHostingEnvironment entry in my Web.config (which I don't have either, but I guess App.config is equivalent since it contains my system.serviceModel configuration). However, I have to specify a relativeAddress for the service activation.
"The relativeAddress attribute must be set to a relative address such as <sub-directory>/service.svc or ~/<sub-directory/service.svc. "
So it should point to my svc file? I'm a bit confused, could you point me to the right direction?
I know documentation on MSDN is little confusing. Here is configuration that you need to put in web.confi/app.config
<serviceHostingEnvironment>
<serviceActivations>
<add relativeAddress="MyNonExistingServiceSVC.svc" service="MyService" factory=”MyServiceHostFactory”/>
</serviceActivations>
</serviceHostingEnvironment>
Here relative address will be just any dummy name. This name will be used to browse your service metadata. Please note that this name can be anything of your choice and it DOES NOT require same physical file to be present on disk. It just needs any name with .SVC extension.
So while accessing service metadata your URL will be
http://myserver/myservice/MyNonExistingServiceSVC.svc
Related
I recently migrated one of our assemblies (a referenced library) from the old CSProj format to the new CSProj format (the Microsoft.Net.Sdk format). This helps a lot due to the globbing rules and how it handles dependencies (reference, project reference, package reference) so well.
After the transition, there is no longer an option for "Service References", instead we have "Connected Services". I removed the old Service Reference files (code, wsdl, xsd, etc.) and created a new Connected Service.
It seems cleaner because it generates a json configuration (used for auto-generating code) and a single Reference.cs file. The auto-generated code is a bit different than the old service reference code that was generated. Firstly, all methods are async (makes sense), so I adjusted our code to account for this.
The problem I am running into is that we had originally relied on the application's Web.Config file (also Web.Dev.Config, Web.Test.Config, etc.) -- during our deploy process we rename/replace the Web.Config with the appropriate environments configuration. This worked just fine, our app added a reference to our library and the app held the config information.
With the new Connected Services auto-generated code, it is hard coding in the localhost address as the endpoint because I used that to auto-generate the code.
Basically, the old "Service Reference" generated code had the default constructor of the client pull the endpoint from the application config. The new Connected Service offers overloads, but does not by default pull the endpoint from the config.
<system.serviceModel>
<client>
<endpoint address="http://xdev/xservice.svc" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IXService" contract="XService.IXService" name="BasicHttpBinding_IXService" />
</client>
</system.serviceModel>
What do I do different to take advantage of my app config with the new WCF Connected Services auto-generated code?
See this answer:
There is a partial abstract method partial void ConfigureEndpoint in your service client to override. There you can programmatically set the endpoint via serviceEndpoint.Address = new EndpointAddress(...).
This URL can be stored in the <appSettings> of your .config or in the appsettings.<Environment>.json, depending on your platform.
Note, that the development endpoint from which the code was generated gets hard-coded into the sources and remains as a fallback. If for some reason your overridden method does not get called, you have a very hard to spot error. If someone has a solution for that, I'd be very interested.
I'm new to WCF and am trying to make my first service (a simple usage reporting service). I've gone through examples and tutorials and created a service. I have a simple test program that can run my core code and send the report. Currently I'm running locally hosted in the debugger, but running this simple exe program hosts the service, sends the report, and the service creates the log file just like it's supposed to... all is good.
Now, my actual program is an addin to another commercial program that runs in it's API (Autodesk Revit). When I run the exact same code inside of the Revit API I get an error that there is no endpoint defined. My guess is that this is because it's looking for the main Revit.exe.config which obviously will not have my endpoint defined. I have a .config file for my dll created (MyLibrary.dll.config) and in the executing directory for my code and it defines the endpoint properly, but that doesn't seem to be recognized.
So my question is how do I get it to load the connection settings from this config file? Or is there another way I should be doing this? I'm open to setting it in code somehow or whatever, just can't figure out how to get it to connect...
I'm not sure if it matters, but here is the configuration that is working in the standalone program:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IReportingService" />
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8733/Design_Time_Addresses/SPECtrumReportingService/Service1/"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IReportingService"
contract="ReportService.IReportingService" name="BasicHttpBinding_IReportingService" />
</client>
</system.serviceModel>
</configuration>
My constructor that is throwing the endpoint exception is simply:
_reporter = new ReportingServiceClient();
Here is the exception that is thrown:
Could not find default endpoint element that references contract 'ReportService.IReportingService' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
at System.ServiceModel.Description.ConfigLoader.LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, String configurationName)
at System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName, EndpointAddress address)
at System.ServiceModel.ChannelFactory`1..ctor(String endpointConfigurationName, EndpointAddress remoteAddress)
at System.ServiceModel.ConfigurationEndpointTrait`1.CreateSimplexFactory()
at System.ServiceModel.ClientBase`1.CreateChannelFactoryRef(EndpointTrait`1 endpointTrait)
at System.ServiceModel.ClientBase`1.InitializeChannelFactoryRef()
at RDES.Revit.Sumex.CommonUse.ReportService.ReportingServiceClient..ctor() in c:\RD\Projects\13-004 SPECtrum\Code\SPECtrumBase\Service References\ReportService\Reference.cs:line 241
at RDES.Revit.Sumex.CommonUse.ImportVM..ctor() in c:\RD\Projects\13-004 SPECtrum\Code\SPECtrumBase\ImportVM.cs:line 41
Any help would be greatly appreciated...
it's not relevant that the dll's configuration file is in the same folder as the application. only the application's (executable's) app.config file is read. the solution is to copy the WCF service configuration from the dll config file to you application's app.config file.
the other solution, for modular applications, is to set the service's ABC in code. the problem with this is that you cannot configure it without rebuilding and redeploying the addin.
to create a WCF proxy entirely in code you could use something like this:
IServiceContract proxy = ChannelFactory<IServiceContract>.CreateChannel(new WSHttpBinding(),
new EndpointAddress("<you url here>"));
I found this post that lead me to a possible answer. I have now updated my constructor as follows:
_reporter = new ReportingServiceClient(new BasicHttpBinding(), new EndpointAddress("http://localhost:8733/Design_Time_Addresses/SPECtrumReportingService/Service1/"));
I've left the binding as just default although it looks like I can set other properties if I need to. I just pulled the endpoint address out of the config file that worked in the standalone program and used that to construct.
This seems to be working as expected inside of Revit at least with preliminary tests. Can anyone comment on if this would cause any issues or if there is a better way to handle this situation?
Though you can inject endpoint info into a proxy class ReportingServiceClient through your application codes, the first class programming approach is to use app.config.
In your client config, you have an endpoint named "BasicHttpBinding_IReportingService", to use this endpoint, you should then write:
_reporter = new ReportingServiceClient("BasicHttpBinding_IReportingService");
If you want
_reporter = new ReportingServiceClient();
to work, remove the name attribute or make the name attribute value in the client endpoint defined in the client config. This will be the so called "default endpoint element" mentioned by the exception.
I am trying to start and stop a WCF service library through a windows desktop application but got stuck. I cannot start it because it gives me error in the shost.Open();
Code:
private void startwcfedcHost()
{
ServiceHost shost = new ServiceHost(typeof(WcfServiceLibrary.Service));
shost.Open();
}
Error:
Service 'WcfServiceLibrary.Service' has zero application (non-infrastructure)
endpoints.
This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.
But when I try to run my wcf service it works, How can I fix this issue?
Since you don't specify the endpoints via code, you need to specify them via configuration. What you probably have is a missing configuration file. Change the Main method (if a console application; something like the Page_Loaded event if you're writing a windows app) to print the following value:
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
That will show the name that the application expects its configuration file to be. Once you have that, make sure that that file exists, and it has the appropriate <system.serviceModel> section to define the service endpoints.
I suggest you take a look at the following:
Here
WCF is about A(address) B(binding) C(contract), you need to specify binding.
I am running a Client/Server WinForm application.
I added a Service Reference to a server side project.
However during runtime I get the following error:
Could not find default endpoint element that references contract '' in the ServiceModel client configuration section.
This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element.
However the node does exist. Is there a certain section that it needs to reside in? Could I have it located in the wrong location of the web.config file?
Currently in my web.config it is in the
"<system.serviceModel>
<client>
my endpoint node
</client>
</system.serviceModel>"
please check your contract in endpoint on client side, as your dnt provide the endpoint xml part of config file we cant tell what is the issue. but what i think contract part of endpoint is making an issue
A little background:
I'm creating a set of adapters to allow communication with mobile devices over different cellular networks. This will be achieved using a class factory pattern. At least one of the networks requires a service reference to communicate with their devices through a web service.
So far I've got 3 assemblies so far which represent:
An assembly which contains the main adapter library: this contains
The interface definition for each of the adapters
Base classes
The class factory to instantiate the specified adapter at runtime.
An assembly for each network adapter implementation.
An assembly that contains my main application.
Given that I don't want to be adding service references and their configuration to the main application assembly [as that's not relevant to the main application], how do I force each assembly's service reference to get its configuration from its own app.config?
If I have the service reference configuration in the main app.config, everything works just fine, but if I move the configuration to the adapter's app.config everything stops working throwing the following exception at the point where I new up the Soap1Client.
"Could not find default endpoint element that references contract 'MobileService.Service1Soap' in the ServiceModel client configuration section. This might be because no configuration file was found for your application, or because no endpoint element matching this contract could be found in the client element."
In the end, I just removed the service reference and added a web reference [i.e. did it the 2.0 way]. For some reason the web reference will access its own app.config instead of the main application's app.config.
Far easier than the alternative...
You can set all the options programatically.
I don't believe there is a built in .NET way to accomplish this. However you should be able to accomplish it by writing some code to parse each referenced assembly's .config file.
Here is a sample using assembly specific configuration files that should point you in the right direction: http://www.bearcanyon.com/dotnet/#AssemblySettings.
I've done something similar in a .NET Winforms app and it worked out well.
If you must have the library read the configuration for the service from a config file, then you might be out of luck. The library becomes part of the process and the process uses the configuration of the application that initiated the process.
However, in your library you could use one of the service reference proxy class constructor overloads to dynamically set the configuration when you instantiate the service reference. Then you don't have to have the service reference binding configuration in any config file. The overload I use takes two parameters: System.ServiceModel.Channels.Binding binding & System.ServiceModel.EndpointAddress remoteAddress. Note that the Binding class is a abstract class, you have to use one of the classes that inherit from it - you can find a list of them here: https://msdn.microsoft.com/en-us/library/system.servicemodel.channels.binding(v=vs.110).aspx.
For a simple http service reference I use a default instance of the BasicHttpBinding class and create an instance of the EndpointAddress class using the URL of the service I'm referencing. Obviously you would have to modify this to use https or secured services, etc.
Of course this still begs the question of how does the library get the correct service URL if you don't want to hard code it in the library? A couple of ways would be to read it from a database or a known file location.