I have Restful WCF service which will be used to read the data push by another Restful service hosted somewhere on the internet. I have to expose one method to read the Json data push by the other service.
[ServiceContract]
public interface ITestService
{
[OperationContract]
[WebInvoke( Method = "GET",
ResponseFormat = WebMessageFormat.Json )]
string GetData(string JsonData);
}
Is it right to receive data in string parameter or should i make the DataContract (Class) to receive the Json data. I know the structure of the Json data push by other service and Is it ok to make Get Method ? Also Push service can send bulk of data at once. how can i restrict it so my server works fine even with bulk data.
I personally don't like the default JSON handling in WCF and thus we use Newtonsoft.Json! We define the data values as string and then check the incoming data versus a JSON Schema file. In my opinion it depends on how extensive you use WCF. For use we use WCF primarily for tcp connections where we use the defined Data interfaces. The REST api is just for internal debugging and not exposed. So a clearly documented api isn'T that important. By defining proper data contracts you can utilize the automated docs WCF generates under the root url of the restful service + /help.
Anyway you should NOT use an HTTP GET to receive push notifications.
POST/PUT would be an appropriate endpoint for a push notification. The following article explains quite well how and why to define REST routes the way to be:
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#restful
Hope that helps a bit.
Related
I am creating SOAP service (ASMX service) into WCF service with BasicHttpBinding. Same as implemented here
Wrote Interface as follows
[ServiceContract]
public interface IExample
{
[OperationContract]
[WebMethod]
Task<XmlElement> GetDetails ();
[OperationContract]
[WebInvoke(Method = "Get", UriTemplate = "/GetExample")]
Task<string> GetExample (string guid);
}
Implementations of Interface:
public class ImplementInteface: IExample{
public ImplementInterface(){}
public Task<XmleElement> GetDetails(){
//Implementation of GetDetails function
}
public Task<string> GetExample(string guid){
//Implementation of GetExampl function
}
}
After running service fabric, stateless service running properly.
I have legacy code(asmx file) where same structure was already defined and having ATPs for the same. URL where the legacy apis are exposed, I don't want to mess it.
I want to expose new SOAP apis to the same URL.
But, when I try to call new SOAP APIs from stateless service, it is giving me Bad request as an error.
Is there any way to Create these apis into stateless service in service fabric?
It won't work just like that.
SOAP entails enclosing client requests (actually their body) into an XML.
Typing the address into the browser won't create any XML, but send a plain request
So,
Either you use something else to send a SOAP request (e.g. a WCF client, that you must write in C#, or a third-party product like SoapUI)
Or you give up the SOAP requirement and use WCF to create a REST service, which won't require an XML body and can be called via browser
If you decide to go with #2, you must add this attribute in your svc file
Factory="System.ServiceModel.Activation.WebServiceHostFactory"
I have a WSDL definition for a SOAP service and I have successfully generated *.cs file from it using SvcUtil.
Implementing client is quite straightforward - I just need to call the necessary functions from the generated *.cs and that's it.
Implementing server seems more complicated. As I understand I need to implement an interface from the generated *.cs and then use some magic to turn it into the web server.
But I don't need a new web server, I already have a web server written in C# which already has many functionality unrelated to the SOAP service that I need to implement. I don't want to create another web server but I want my SOAP service to be just a part of my existing application (server), that is my server can answer e.g. requests http://example.com/request1, http://example.com/request2 etc. and I want this SOAP service to be just http://example.com/request3.
Since HTTP is already handled by my server I don't need .NET to handle it for me, basically my server can accept client connections and call the necessary handler based on the URL. I have a handler for SOAP request which looks approximately like this:
MyResponse HandleSOAPRequest(MyRequest request)
{
// 1. parse soap message from request.body
// 2. process it
// 3. generate response, serialize it in SOAP format and return it
}
The question is - can I rely on WSDL definition and .NET libraries to do it?
Currently I'm parsing SOAP request using XDocument and manually extract fields from it and serialize using simple string concatenation. Using .NET built-in functions to serialize or parse XML doesn't work. That is if I try to serialize response from an object of the class defined in the generated *.cs file then produced XML is different from what is expected by the protocol, similarly, if I try to parse request as an object of the class defined in the generated *.cs file I get error because XML parser expects different format. This applies to both the SoapFormatter and XmlSerializer.
Since .NET can implement client this means that everything that is necessary to parse and serialize SOAP messages is already implemented, I just need to figure out a way how to use this functionality.
The documentation for ServiceModel wasn't very helpful.
The easiest way would be to start the service via the ServiceHost:
ServiceHost host = new ServiceHost(typeof(YourService));
host.Open();
(I assumed here the configuration will come from the app.config and will not be setup in code like in the linked example below.)
How to: Expose a Contract to SOAP and Web Clients
The only drawback of this is that the application has to run with admin rights or otherwise a weird cofiguration is necessary.
I'm trialling out ServiceStack and loving what I'm seeing so far. However I've run into a bit of a brick wall.
I have a system retrieving data from another system via web services - a service at both ends. These two systems are from different vendors - so I have no control over changing them - and are configured to talk to each other via WCF web services. Let's say "Lemon" calls "Orange" to get some information about a customer.
The way we implement these two systems is slightly different to what the vendors planned - we point their service configuration to our intermediary service - let's call it "Peach" - which goes off and does some other things before returning the information. For example, "Lemon" calls what it thinks is "Orange" but is actually our intermediary service "Peach" using the same method names. "Peach" calls "Orange" for the customer information and for example overrides the email address for the customer with something else before combining all the information appropriately and returning it to "Lemon" in the format it was expecting.
I would like to get "Peach" using ServiceStack. However it's responses needs to be identical to a WCF service returning via wsHttpBinding. Is this possible with ServiceStack? Would it involve overriding the Soap 1.2 type?
Thanks for your help!
If ServiceStack's built-in SOAP Support doesn't return the response you're after, you may need to return the exact SOAP response you're after as a raw string.
Raw Access to WCF SOAP Message
To access the WCF's Raw Request in your Service you can use the IRequiresSoapMessage interface to tell ServiceStack to skip de-serialization of the request and instead pass the raw WCF Message to the Service instead for manual processing, e.g:
public class RawWcfMessage : IRequiresSoapMessage {
public Message Message { get; set; }
}
public class MyServices : Service
{
public object Post(RawWcfMessage request) {
var requestMsg = request.Message... //Raw WCF SOAP Message
}
}
Creating custom WCF Response
Some level of customization is possible by creating a custom WCF Message response and returning the raw output as a string, e.g:
var wcfResponse = wcfServiceProxy.GetPeach(...);
var responseMsg = Message.CreateMessage(
MessageVersion.Soap12, "urn:GetPeach", wcfResponse);
return responseMsg.ToString();
Otherwise you may need to use a HTTP Client like Http Utils to POST raw SOAP to the WCF Service and return the raw string Response.
This question isn't specifically related to WCF. What WCF returns is not a construct of WCF, it is returning a standards based response as specified by the WS* standards. http://en.wikipedia.org/wiki/List_of_web_service_specifications lists many of the standards.
Your question isn't specifically making ServiceStack emulate WCF, it is for ServiceStack to return responses adhering to existing published standards. Standards that WCF has already built in with the WsHttpBinding configuration.
Simple question (details follow) : how to use named pipes, without soap serialization, i just want to have on method and read the byte array myself. I'm trying to implement a service that does not rely on XML, through named pipes.
Few weeks ago, i wrote a service using wcf and web sockets. This service, to deal with non .net software, use a custom binding with a really simple contract :
[OperationContract(IsOneWay = true, Action = "*")]
Task Message(System.ServiceModel.Channels.Message message);
and the callback :
[OperationContract(IsOneWay = true, Action = "*")]
Task OnMessage(System.ServiceModel.Channels.Message result);
In this case, i just read the byte array and deserialize using protobuf.
I've got another service on the same machine, and i want to improve performence using the protobuf deserializer. This service is already exposed with named pipes (with our former contracts).
With the new websocket server, and the protobuf serializer, i would like to implement it on the second service. Looking at protobuf endpoint behavior, it seems that they override the XmlObjectSerializer, but it seems that it still use some xml.
Do anyone have an idea on how to do this ?
Thanks
I have a WCF service hosted that is returning a byte[] of protobuf-net serialized data. Originally this was hosted over the default webHttpBinding settings (SOAP) and everything was working properly. I recently found out that I need to call HTTP GETs and POSTs directly from our client so I thought it'd be easier to switch to use a RESTful service. I switched to use the WebGet attribute and the WCF REST Template.
I attempted to create a simple web site to test the client and I'm having trouble deserializing the data. This is an example of how I'm calling the service:
using (WebClient client = new WebClient())
{
result = client.DownloadString(url);
}
// Deserialize
BinaryVehicles binVehs;
using (var ms = new MemoryStream(StrToByteArray(result)))
{
binVehs = Serializer.Deserialize<BinaryVehicles>(ms);
}
An example of what is returned in "result":
< base64Binary xmlns="http://schemas.microsoft.com/2003/10/Serialization/">ChsKCzEyMy00NTYtNzg5EgU0NDAwMBoFQmxhY2sKHAoLOTYzLTg1Mi03NDESBTIzMDAwGgZTaWx2ZXI=< /base64Binary>
I also attempted to deserialize the data between the < base64Binary > tags with no results. Does anyone have any idea on how I should go about sending the binary protobuf-net data from an WebGet method and how I should deserialize the data? Thanks.
protobuf-net primarily handles just the serialization aspects (the protobuf spec by Google doesn't define any further than this). So it really comes down to: how are you serializing it?
I must admit that the WCF GET approach is not something I've looked at hugely, so there is no special handling there. One simple approach may be to look at just returning a string, and handling the base-64 encoding yourself, but to be honest if you are doing HTTP GET, then WCF itself seems overkill.
I blogged here about using ASP.NET MVC at the server for protobuf via HTTP GET. The linked sample code also includes a wire-compatible ASP.NET implementation.
If there is something appropriate we can do to make WCF GET easier, I'm all ears...