Are Web Service References necessary in all project? - c#

I currently have one Web Service in a solution of multiple projects. Since I don't want to add service references in all project to be able to use it, I have created a project with static a class named "ServiceHelper" for the moment. This project would be the only one with the service references and the helper would do all the request ncessary. The Web Service is set public (not internal).
My problem here is that when I initialize my SoapClient in my helper from another project that do not have the service references, it throws an exception. But when I add the service reference to that other project, it works. Is it normal or not?
The exception throwed translated (because it is said in French) is :
Unable to find an element endpoint default refers to the contract 'ServiceReference.WebServiceSoap' section in the ServiceModel client configuration. This may be due to the fact that the configuration file of your application is not found or the endpoint element matching this contract is found in the client element
Is there something missing in my config file? because I didn't change anything in the 2 projects mentionned.
Exemple of how I initialize my SoapClient in my helper :
private static ServiceReference.WebServiceSoapClient _webService = new ServiceReference.WebServiceSoapClient();

Following on with #zverev.eugene, you don't need the references in every project, but the web.config or app.config in the project is where the connection and configuration information is retrieved from. This is because the application calling your class library is what supplies all configuration information (e.g., if you have a data access layer in a class library, the connection string would come from the .config of the application calling the DAL, not the class library itself).

Related

C# call SOAP webservice from console application

This seems very trivial, but it is not working for me at all. I am attempting to call a soap web service from within my c# console application. The app is built for .net 4.5. Here's what I did:
Added the service reference to the project in visual studio 2013 by pointing it to the wsdl. It finds the Service and it's operations fine.
Attempt to create an instance of that service by doing the following:
ServiceReference1 s = new ServiceReference1();
I get the following error code:
Project1.ServiceReference1 is a 'namespace' but is used like a 'type'
Any ideas? I've searched for this for a while and can't come across someone having the same problem with a real solution. I will provide any more info needed.
If you already added the service reference to the project you see the reference. In this case you left a default name 'ServiceReference1'.
Now you want to call the web service's methods, for this you have to instantiate a SOAPClient.
ServiceReference1.YourWebserviceNameSoapClient client = new ServiceReference1.YourWebserviceNameSoapClient();
client.HelloWorld(); // call of webmethod
now you access the webmethods under the 'client' object.
When you create a service reference, Visual Studio 2013 will generate a proxy class you can use to transparently call into the service. The default proxy namespace is your_project_name.ServiceReference1. The type is the name of your service.
For an example service http://localhost/YourService.svc.
You generate the Service Reference ServiceReference1 from your console project ConsoleApp. The generated files have the namespace ConsoleApp.ServiceReference1. The type is YourService.
var service = new ServiceReference1.YourService();
will return an instance of the proxy generated by Visual Studio. Then you will be able to call any of the service methods.

EntityFramework6 Configuration with WCF Service boundrary

I'm attempting to architect a solution involving a WCF service, which calls a dll containing an EntityFramework6 model. When I attempt to unit test the service however, I receive a message:
Additional information: No connection string named 'SyslogEntities' could be found in the application config file.
My flow is arranged logically as:
SyslogDataSvcTest.dll (app.config has service bindings) ->
SyslogDataSvc.svc (web.config has provider and connection string) ->
LibSyslogData.dll (app.config has providers and connection string)
All the code that touches EF is in the libSyslogData.dll. It maps data to upper layer objects internally, and returns them, instead of exposing its own model info, so EF use should be really isolated.
So what am I doing wrong?
Edit:
I got it working well, but in perhaps a weird way. It seems the settings in my app.config were not correctly specified by NuGet when installing the EF and MySql dependencies.
Instead I created an in-code configuration class as described on MSDN here:
https://msdn.microsoft.com/en-us/data/jj680699
Now that I have this class:
public class EFConfiguration : DbConfiguration {
public EFConfiguration()
{
//For some reason this works much better than the app.config.
//With this defined, upper layer config documents need only specify the "SyslogEntities" Connection string.
SetExecutionStrategy("MySql.Data.MySqlClient", () => new MySqlExecutionStrategy());
SetDefaultConnectionFactory(new MySqlConnectionFactory());
SetProviderFactory("MySql.Data.MySqlClient", new MySqlClientFactory());
SetProviderServices("MySql.Data.MySqlClient", new MySqlProviderServices());
}
}
I can leave the specifics of the DB implementation to the datalayer, and only configure the connection string at the upper layers.
You most likely don't test the actual wcf service (I mean online) based on that exception. I think you are just unit testing the wcf service dlls code. So this would mean the app.config used is from the unit test assembly. Just 1 app.config for runtime for application, having an app.config for a class library does not make sense anyway either.
You need to provide the EF connectionstring that your EF data-access layer is using in your unit test assemblies, as you are doing in your wcf services web.config (since you are not testing the online wcf service). If you want to be totally free of EF references in your unit tests and wcf service configs, you need to override the default constructors for your EF entities and provide the "normal" dbprovider + connectionstring in your app/web configs and create the EF connection string(s) on the fly.

ServiceContract class for an ASP.NET web service

I want to invoke a web service in my C# client application.
I want to be able to bind to this web service dynamically.
I am using the following code for dynamically calling a web service:
class Program
{
interface IInterface
static void Main(string[] args)
{
BasicHttpBinding bin = new BasicHttpBinding();
EndpointAddress endPoint = new EndpointAddress("http://api.wxbug.net/webservice-v1.asmx");
IInterface myInterface = ChannelFactory<IInterface>.CreateChannel(bin,endPoint);
}
}
My question is, how to I generate a ServiceContract Interface for my web service? Is there any tool to autogenerate this? This is because my target web service is quite complex with lots of exposed methods, and I dont want to write the Service Contract Interfaces all my hand.
The svcutil tool is what you use for this. This is also what gets run behind the scenes when you select "Add Service Reference" in Visual Studio.
If you are working in Visual Studio, then "Add Service Reference" will probably be easiest, as it should automatically start up your service in order to get the metadata.
If you can't or don't want to use Visual Studio, you'll need to make sure your service is up and running, and then use svcutil.exe (if you open a .Net Command Prompt it will be in the path variable). Using svcutil is sometimes necessary if you don't want to generate/overwrite the client configuration, or if you want to specify a specific class for the proxy to go in. There's also a handy switch in svcutil which will generate generic collections in the proxy, rather than defaulting to arrays.
You can to right click your project and to select Add Service Reference; it'll grab your web service WSDL and to create your proxy classes.

Getting an Instance of your Web Service Reference

So I believe all you have to do with .NET 2.0 vanilla web services (not WCF) is the following:
1) Add your service reference. In my case I'm using the PayPal WSDL
2) Before you can use any proxy class, you must first create an instance of your service reference
3) Once you create an instance of your service reference, then just do [servicereference].ProxyClassName.Method or whatever you're trying to access from those classes
right?
Ok, so I tried that. I added a service reference and named it SandboxSoapAPI. So that's what you see under references in my C# project.
In code I tried this:
SandboxSoapApi reference = new SandboxSoapApi();
but it doesn't recognize SandboxSoapAPI. Am I doing something wrong? I just want to start calling class methods, etc. with PayPal and I can't seem to get this right.
And if I'm not incorrect, as of .NET 2.0+ it handles the low level sending of the actual request over Http for SOAP web service references?
SandboxSoapAPI is not the SOAP client proxy type name. It's a namespace.
To check this, in VS.NET tick 'show all files' and drill into the Web References, open up the Reference.cs file, you will see the SandboxSoapApi is a subnamespace (not your SOAP client proxy name!) in the project's root namespace.
So either use the fully qualified name:
SandboxSoapAPI.YourProxyType client = new SanboxSoapAPI.YourProxyType();
Or use using SandboxSoapAPI; in your code where you need the SOAP client.

How do I move service references to their own assembly?

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.

Categories