Changing namespace and schemaLocation attributes in WCF - wcf

I developed a WCF service in C#. Our customer already has a client software written in Java. They say when they try to add our wcf service reference, they get an error. They think that the problem about namespaces.
I don't know much about namespaces or any other tag details in WCF.
They say wcf service's wsdl output has to be like the following:
<xsd:import id="base" namespace="http://helios.theircompanyName.com/im schemaLocation="http://wwwdev1.theirCompanyName.com:8000/HeliosIM/im?xsd=1"/>
But our service gives:
<xsd:import schemaLocation="http://myComputerName/MyWcfProjectFolder/MyWcfService.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
As it can be seen, my service has no attribute like id="base" and namespace, schemaLocation attributes are different.
How can I change WCF to generate wsdl xml like they want?

If you want to change the namespace of your service from tempuri.org (which is the WCF default) you need to change it in 4 places:
Service contract
Data contracts
Service implementation
BindingNamespace in endpoint config element
For example:
// Service Contract
[ServiceContract(Namespace="http://myNamespace")]
public interface IMyService
{}
// Data Contract
[DataContract(Namespace="http://myNamespace")]
public class MyType
{}
// Service implementation
[ServiceBehavior(Namespace="http://myNamespace")]
public class Service : IMyService
{}
<!-- In config -->
<endpoint address="http://whatever"
bindingNamespace="http://myNamespace"
binding="basicHttpBinding"
contract="Something.IMyService" />
HOWEVER, I don't really understand why they are telling you this is necessary. As the provider of the service, it's up to you rather than them what namespace you provide. Whatever this value is set to they will likely have the same problems consuming the wsdl.
The same goes with the schemaLocation, again, it's not up to them where this location points to. Schemalocation is actually completely optiona when you're doing an import in xml schema, so if they're dependent on some value being in there then they're not xsd compliant.
I would guess they're having difficulties consuming your WSDL and do not quite understand what is wrong, so have chosen to blame your service. The service metadata exposed over the basicHttpBinding is the most interoperable of the entire WCF stack, and should be 100% consumable from java.
How are they trying to build their client? Is your service running somewhere they can see it?

Related

Quick and easy implementation of a WCF web service, given wsdl?

I'm writing a client to access a SOAP webservice, that will be hosted by a third party. I have the WSDL and XSD that define the interface and the data.
I've had no problem in creating a service reference from the WSDL, but I'm having a problem in building a simple web service that implements it, that I can use to test against. (The third party's service isn't ready, yet, but even were it running, I'd still like to do my initial testing against my own test server, not against theirs.)
I've browsed around, and apparently I can use svcutil to generate an interface for the service:
svcutil.exe thewsdl.wsdl thexsd.xsd /language:c# /out:ITestService.cs
This generates a file containing the service interface definition. But now what?
I figured the easiest way to go would be to build a self-hosted service, so I created a new console app, and in it I implemented a class derived from the service interface definition, and fired it up with a ServiceHost.
It runs, and while it was running I was able to create a Service Reference in my client app. But when I try to call it, from the client app, I get an error:
The provided URI scheme 'http' is invalid; expected 'https'.
What is the easiest way to get around this? Is there a simple way to simply turn off authentication and authorization, and simply allow unrestricted access?
EDITED:
I'm adding a bounty to this, as the original question seems to have attracted no attention.
But let's get to the crux. I am trying to write a client against a customer's SOAP service. As a part of the development, I want to create my own test WCF service, that implements the same WSDL.
So I have a downloaded .wsdl file, and an associated .xsd file, and with them I want to create a service that I can test against, with VS2010's debugger.
It's not important to me whether this service runs standalone, or within IIS, or that it be production stable. All I want is a service that accepts the requests that the customer's site would accept, and return the responses to my client that I need it to return, in order to test my handling of them.
How do I get there? I've tried adding a WCF Service Library, and then using svcutil.exe within it to add my new service, but it doesn't seem to populate the app.config with the server-side boilerplate, and my attempts to reconstruct it haven't worked.
Since you want a full fledged service to call instead of mocking it.
Follow these steps:
Create new "WCF Service Application" project
Copy wsdl and xsd into project
select your wsdl file and look in the properties section and copy location from full path
Right click on the project in solution explorer and select "Add Service Reference..."
For the service address, paste the location of your wsdl that was copied in previous step and hit go. It should show the operations you are expecting for the service.
hit ok
It should generate all the objects for you including the interface and config file (although at this point is client side in the config- we will have to switch this to be the service)
Now you should add the service config section in the system.serviceModel section. Since I don't know the specifics of your wsdl what you should do is create the services node inside the system.serviceModel section and copy the endpoint node from the client node generated. For example below of services node, you can blank out the address for now:
<system.serviceModel>
<services>
<service name="YourService">
<endpoint address=""
binding="basicHttpBinding" bindingConfiguration="WeatherSoap"
contract="ServiceReference1.WeatherSoap" name="WeatherSoap" />
</service>
delete the client node in the config
In the service, it is implementing a different interface when it generated the project so you will want to replace the interface implemented with the one listed in the contract attribute in the endpoint above. Then implement its members and it should explode out the operations available. You can fill in whatever you want the service operations to return.
depending on what the wsdl has in it, we may need to do a few more things to allow the necessary bindings to run - like setting up for wsHttpbinding, netTCPbinding, etc.
I've used Moq to handle this. Basically in the unit tests you specify the interface (this would have been generated for you with adding the service reference or using svcutil) and what you want it to return if you call it.
example setup below:
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);
So then when you want to moq out your service call
var myObject = new IFoo;
var resp = myObject.DoSomething("whateverwillbeoverriddenbyping");
and resp will be true.
There are other options than using Moq. The options all involve taking the interface and injecting a different version of it. For example, you could also do a constructor injection mock, by passing in the interface to your class constructor.

What is the best way to dynamically host multiple WCF services in a single Windows service sharing a mex endpoint?

I have been given a request to dynamically host multiple WCF services in a single Windows service.
The requirements are the following:
The services are singletone instances implementing some service contract interfaces.
The services aren't known at compile-time - at runtime a collecion of unknown singletone services are passed to the application.
All services are exposed via the same mex endpoint
The endpoints are set programmatically (without using app.config)
I tried solving the problem from two different approaches:
The first approach is to create and open a ServiceHost for each service instance. The problem with this approach is that each ServiceHost is exposed via its own mex endpoint.
The second approach is to create a single ServiceHost for all services, and expose them all via the same mex endpoint.
I tried a couple of ways to implement the second approach:
The first way is to create a service type in runtime (using CodeDom or Reflection.Emit) that wraps all instances, and implements all of the service contracts and routes a given method call to the suitable service instance. This works but seems like a overkill. (I rather to not generate code if possible)
The second way is to programmatically setup ServiceEndpoints for requested contracts. I modified this following code example so it will route a method call to the corresponding service instance's method. The problem with this solution is that a hack is made in order to associate a ServiceEndpoint to its ChannelDispatcher.
Am I missing other approaches? Is there anyway to overcome the problems I mentioned?
If I'm understanding your problem correctly, then one approach would be to implement multiple contract interfaces in a single service class. By doing that, you should be able to get the metadata from a single mex endpoint. Here's a very simple example:
[ServiceContract]
public interface IServiceContract1
{
[OperationContract]
bool DoStuff1();
}
[ServiceContract]
public interface IServiceContract2
{
[OperationContract]
bool DoStuff2();
}
public class ServiceContractImplementation: IServiceContract1, IServiceContract2
{
bool DoStuff1()
{
return true;
}
bool DoStuff2()
{
return true;
}
}
Then in the web.config (or in code in your case):
<service name="ServiceImplementation">
<endpoint binding="basicHttpBinding" contract="IServiceContract1"/>
<endpoint binding="basicHttpBinding" contract="IServiceContract2"/>
<endpoint address="mex" contract="IMetadataExchange" />
</service>

WCF (svc) Service but client wants to connect as if it was ".asmx"

I have this scenario. Client requested us to have a WebService. I created a WCF Service. After we sent them our url to the web service description, client says
As it is we cannot consume a WCF
service, can you publish it a web
service?
Now i am wondering, they are asking me for a asmx... right?
Is there any way that i can "offer" my WCF service as an asmx service so i don't have to rewrite the whole thing?
my first "solution" is to have an .asmx file calling my .svc files directly... i don't know. I havent tried but i am heading on that direction.
Any ideas would be highly appreciated.
Tony
It is completely do-able. Just use an endpoint that exposes the service using basicHttpBinding or wsHttpBinding. The "file extension" of the URL doesn't make any difference to the client, only the content of the rerquest/response.
Here's a reference to another SO question:
REST / SOAP endpoints for a WCF service
It's very much possible.Follow the steps mentioned below and you'll be able to expose WCF service as ASMX endpoint.
Add new web service file (.asmx)
Now open the node of web .asmx file and delete .asmx.cs file
Once .cs file is deleted. You will find wcfasasmx.asmx file.
I have WCF class name as Service1(from the basic WCF service) and this class is present in current NameSpace. So I changed class name as mynamespace.Service1
Some changes is code as shown below-
In web.config in Tag add following code
<system.web>
<webServices>
<conformanceWarnings>
<remove name='BasicProfile1_1'/>
</conformanceWarnings>
</webServices>
</system.web>
Add following 2 attribute on interface(on servicecontract of WCF)
[WebService(Name = "Service1")]
[WebServiceBinding(Name = "Service1", ConformsTo = WsiProfiles.BasicProfile1_1, EmitConformanceClaims = true)]
Add [WebMethod] attribute on each operation contract.
[OperationContract]
[WebMethod]
string GetData(int value);
your service can now be consumed by asmx client too.

How do I specify a contract's namespace in the XML configuration of a WCF endpoint?

I've got this WCF service contract (heavily simplified, but pay attention to the namespace it's in):
namespace Foo.Services.BarService
{
[ServiceContract]
interface BarContract {... }
}
In my app.config (client side), I configure an endpoint for some service:
<endpoint address="..."
binding="..."
contract="Foo.Services.BarService.BarContract" />
However, this results in an error saying that no endpoint was found in the client's configuration that supports BarService.BarContract. I can only get rid of this error by changing the contract attribute value to BarService.BarContract (i.e. by removing the namespace).
Why is that? Where could this error come from? Why must I not mention the namespace part of a contract type? Shouldn't that result even more in WCF not finding a matching endpoint?
Reply to the questions in #Ladislav Mrnka's comment below:
I am talking about the client side. (I forgot to mention this bit; sorry for that.)
Can this error possibly come from the server side?
I generated the above service contract, along with a BarClient class that implements it, via Visual Studio's Add Service Reference facility. I specified the URL of the BarService, which is run by someone else. That's where I also specified that the service should be put in the Foo.Services.BarService namespace.
I was going to use the service directly via the BarClient class auto-generated for me, not via a ChannelFactory<BarContract>.
Creating client by Add Service reference does not recreate namespace structure from service. All created types and contracts are placed into new namespace defined by the name of the service reference. So I guess you named your service reference BarService. Client configuration must follow names of generated contracts.

HTTP POST to a WCF service

What needs to happen to allow an HTTP POST to a WCF service?
I would like to allow people to not only use SOAP with this service, but they must also be able to HTTP POST to this service and ideally receive an XML response.
I cannot find an easy way to allow a WCF service to accept an HTTP POST.
I am past the HTTP 415 error and need some help with maybe a web.config change regarding endpoints, or an additional attribute above the method (WebInvoke).
Thank you!
In order to talk to a WCF service over the standard HTTP verbs, you need to use the WCF REST components.
In .NET 3.5 SP1, there's the WCF REST Starter Kit that you'll need (it's not part of the basic package).
When you have this, you can define an endpoint in your WCF service with a webHttpBinding and that basically should allow you to define GET, POST, PUT and DELETE operations.
Check out the WCF REST developer center for a great deal of white papers, tutorials, walk throughs and screencasts showing you exactly how to do all of this.
In a nutshell, you would adorn your service method(s) that you want to expose over HTTP REST with WebGet or WebInvoke attributes and a URL template - something like:
[ServiceContract]
public partial class YourService
{
[WebInvoke(Method = "POST", UriTemplate = "yourservice/{id}/save")]
[OperationContract]
SomeReturnType YourMethodCall(string someParam);
...
}
and then, in your web.config (for hosting in IIS) or in app.config you need an endpoint with the right binding:
<endpoint name="webEndpoint"
address="...."
binding="webHttpBinding"
contract="IYourServiceContract" />
You might also need a few extra things in your config - the WCF REST dev center should go into all the details in great depth.