Call WCF Using SOAP call - wcf

I want to call a WCF service using SOAP?
this is my contract:
[ServiceContract(Namespace = "http://www.MySite.com/Services/TransferFile")]
public interface ITransferFile : ICloseableAndAbortable
{
/// <summary>
/// This will send the file which is associated with this rule to all the subscribers.
/// </summary>
/// <param name="ruleId"></param>
[OperationContract]
void ByRuleId(int ruleId);
}
the binding is currently set to this, will i need to change it?
<endpoint address="" binding="wsHttpBinding" contract="FileTransfer.Wcf.ITransferFile">
so how would i call it via soap? for example using the (HttpWebRequest)WebRequest
Many thanks in advance

Change the Binding to basicHttpBinding
2 the message
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<ByRuleId xmlns="http://www.MySite.com/Services/TransferFile">
<ruleId>3</ruleId>
</ByRuleId>
</soap:Body>
</soap:Envelope>
3 the soap action
POST /FileTransferService/TransferFile.svc HTTP/1.1
SOAPAction: "http://www.MySite.com/Services/TransferFile/ITransferFile/ByRuleId"
fyi i asked for a (HttpWebRequest)WebRequest, only as a posible way, I ended up using a Web Reference and fiddler

Is there a reason you prefer WebRequest instead of generating a client proxy with svcutil.exe which takes care of all the plumbing?

There's a number of ways you can do this:
create a little WCF client for your service yourself, by using svcutil or "Add Service Reference" in a Visual Studio project
run a SOAP testing tool like SoapUI or WCFStorm against your service and create requests and call your service (and see the results)
use the WCF test client WcfTestClient.exe which is in your (Visual Studio)\Common7\IDE\Tools\bin (?? not 100% sure about the location - check and you'll find it for sure!) and which allows you to connect to a running WCF service, inspect its operations, and also call them
Marc

Related

Changing namespace and schemaLocation attributes in 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?

WCF REST Service - 401 Unauthorized

We're in the process of developing a WCF REST web service which just receives a bunch of arbitrary text from any anonymous user and then performs some processing on the back end.
For example, here's one method from our web service:
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class MyRESTService : IMyRESTService
{
[WebInvoke(Method = "PUT", UriTemplate = "/MyRESTMethod?paramA={paramA}&paramB={paramB}")]
public Stream MyRESTMethod(string paramA, string paramB, Stream rawData)
{
//do some stuff...
}
}
If we just use the default IIS settings we get a (401) Unauthorized. However, after much trial and error we figured out that we could get it to work by giving WRITE access to 'Everyone' on the actual .svc file for our service.
My question is: why in the world would IIS need to have WRITE access to an .svc file for this to work? Is there a better way or am I stuck with this hackish (and possibly insecure) workaround?
WTF Microsoft?
Possibly related:
PUT and DELETE in RESTful WCF Service cause 401 Unauthorized error
IIS7 Post/Put/Patch/Delete WCF oData - Authentication Failure 401.3
I have also found this can be fixed by putting
<authentication mode="None" /> inside of <system.web> in your web.config
After talking to a tech representative from M$ I was informed that this is indeed the expected behavior. The service must have write access enabled for someone to send a request to it, and when you do this it will actually set write access automatically on the .SVC file as well.

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.

Get WCF to recognise incoming SOAP request

I'm trying to write a C# app to receive eBay notifications which are sent as SOAP over HTTP. I am receiving the notifications OK but I can't get them passed to my WCF service. What do I need to do on the WCF service configuration to allow the incoming SOAP request to be recognised? I'm using a webHttpBinding with the WCF service.
The SOAP request is:
POST /paypal/ebaynotification.svc HTTP/1.0
Host: myserver.com
Content-Type: text/xml;charset=utf-8
SOAPAction: "http://developer.ebay.com/notification/ItemListed"
Content-Length: 6610
X-Original-Client: 10.71.29.83
Via: 1.0 sjcproxy10b:8081 (squid)
Cache-Control: max-age=86400
Connection: keep-alive
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<ebl:RequesterCredentials soapenv:mustUnderstand="0" xmlns:ns="urn:ebay:apis:eBLBaseComponents" xmlns:ebl="urn:ebay:apis:eBLBaseComponents">
<ebl:NotificationSignature xmlns:ebl="urn:ebay:apis:eBLBaseComponents">RnvpyFAXc9Duo0W+/Mk68g==</ebl:NotificationSignature>
</ebl:RequesterCredentials>
</soapenv:Header>
<soapenv:Body>
....
</soapenv:Body>
</soapenv:Envelope>
My WCF service interface is:
[ServiceContract(Namespace="http://developer.ebay.com/notification")]
public interface Iebaynotification
{
[OperationContract]
void ItemListed(ItemType item);
}
You need something to "catch" that incoming SOAP request and spin up the WCF class to handle it.
You can either have a self-hosted WCF service (e.g. inside a Windows NT Service) listening on a given endpoint URL, or you can have a message-based activation, like IIS/WAS that will catch an incoming message and pass it to WCF for handling.
So basically, you need to implement that service contract in a WCF service class, and then you need to host / deploy that WCF service in such a way that the incoming message will be handled by it.
But most importantly: since it's a SOAP message, you cannot use webHttpBinding which is the binding used for WCF REST services. You will need to use something like basicHttpBinding or wsHttpBinding.
If eBay exposes a SOAP endpoint, I would guess that they've have a publicized a WSDL document describing the callback service. You can use the svcutil.exe command line tool to generate a correct WCF contract(s) / C# interface that you need to implement in your service implementation to handle the SOAP message you're describing. See eBay's API documentation...

Invoking WCF service method through a browser

I've a WCF service which uses basic http binding.
How do I invoke its operations/methods through a browser?
You would need to add WebGetAttribute to your method like following sample
[OperationContract]
[WebGet(UriTemplate = "/placesList/{userId}",
ResponseFormat = WebMessageFormat.Xml)]
List<Places> GetAllPlacesForUser(String userId)
{
string xml = "";
// build xml here
return xml;
}
Now in the browser, you could invoke the method like this
http://localhost:8085/GeoPlacesDataService/placesList/10
where 10 is the userId parameter.
Note: In order to add WebGetAttribute you have to reference System.ServiceModel.Web namespace which is found in a separate assembly
I would recommend setting up multiple endpoints for the Service. Add an endpoint using webHttpBinding to get an XML version of the service. If this is done correctly the response you will get from the service is identical to the basicHttpBinding endpoint, but without the SOAP overhead.
Other than that, you can't call a SOAP web service directly from the browser because it requires a form post. You could use a tool to test it using SOAP though, I recommend Soap UI. Its written in Java but I try not to hold that against it. :)
After adding the above code, the endpoint property has to be modified in web.config, binding="webHttpBinding" and behaviorConfiguration="webHttp".