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"
Related
Is it possible to add as a reference and call an APIs controller methods as a service on another project? What are the alternatives if this is not possible?
Web API types of applications do not have a 'service reference' anymore. They do not produce WSDL, so you cannot add them like you used to do with SOAP services. No proxy classes are generated... no intelli-sense.
Web APIs are typically called with lightweight http requests and return JSON and not XML based SOAP responses like traditional ASMX or SVC (WCF) services.
You have some reading to do I believe.
To answer your question, you CAN indeed call API services from a web application (say a controller method in an MVC app), but you won't have proxy classes to help you.
https://learn.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
When you create a service reference you end up with a reference to an interface and a client class that implements the interface.
You can follow pretty much the same pattern without a WCF service reference. In fact, that's one of the benefits of depending on an interface. It doesn't matter to your application whether the implementation is a call to a WCF service, an API, or anything else.
First declare an interface that describes how you will interact with the API.
public interface ISomethingService
{
public SomeData GetSomeData(string id);
}
That interface is what your other classes depend on. They'll never know what the implementation is.
Your implementation could be something like this. I'm using RestSharp to create the API client because I like it better than managing an HttpClient:
public class SomethingServiceApiClient : ISomethingService
{
private readonly string _baseUrl;
public SomethingServiceApiClient(string baseUrl)
{
_baseUrl = baseUrl;
}
public SomeData GetSomeData(string id)
{
var client = new RestClient(_baseUrl);
var request = new RestRequest($"something/{id}", Method.POST);
var response = client.Execute<SomeData>(request);
return response.Data;
}
}
In your startup you would register this class as the implementation of ISomethingService and pass the base url from configuration. That would also allow you to pass a different url for development, production, etc. if needed.
Ultimately it's no different from depending on a WCF service. One difference is that a WCF service defines an interface, but in this case you have to do it. That's actually a good thing, because it's better for your application to define its own interface rather than directly depending on the ones someone else provides. You can wrap their interface or API in a class that implements your own interface, giving you control over the interface you depend on.
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.
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.
Is it possible to send objects through RoutingService to peer WCF services without having the router know about the exact type of these objects ?
My intention is to create a router once for all, then be able to add new WCF services, dynamically add them to the routing table, and allow clients to communicate with these services without having to stop, change the code of the router, then start it again.
I was thinking of a generic contract like this:
[DataContract]
public class RequestObject
{
}
[DataContract]
public class ReplyObject
{
}
[ServiceContract]
public interface IGenericServiceInterface
{
[OperationContract]
ReplyObject DoJob(string jobType, RequestObject request);
}
I could put this in a common library that all 3 components link to (client, router, services). But, I am not sure, it will be possible to derive new sub classes to allow new clients/services with new data exchanges to be added without having to change the router.
Any advise ? is it possible for the solution to work when encryption is enforced through clients till services ?
Thanks in advance.
There's a good msdn on using the Message class in WCF to build contract agnostic endpoints. Does not use routing service, but you could build a router using this:
http://msdn.microsoft.com/en-us/library/ms734675.aspx
I have an ADO.NET Data service that I run through WCF:
public class AdminService : DataService<BOPApplicationAccessEntities> {
public static void InitializeService(DataServiceConfiguration config) {
config.UseVerboseErrors = true;
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
config.SetEntitySetAccessRule("*", EntitySetRights.All);
}
}
I'd like to add some custom methods to it, such as the following contract
[ServiceContract]
public interface IAdminService {
[OperationContract]
void RequestAccess(int applicationID, string username);
}
If I add the decoration and implement the method on the data service, an error is thrown when a client tries to connect, saying:
AdminService implements multiple servicecontract types, and no endpoints are defined in the configuration file.
Is it not possible to add service contracts onto an ADO.NET data services service?
The error states that the service exposes multiple contracts (interfaces), which is true, because you just added a new one. The host is not able to work based on implicit default values anymore, because it does not know which service interface to host on which endpoint.
Make sure you have an explicit endpoint defined in your service configuration file for each contract your service implements. Thing will start to work for you again after that, though you might need to update the service reference in your client application after making the modifications.
Update: Combine How to disable authentication schemes for WCF Data Services which tells how to explicitly create an endpoint for your WCF Data Service with http://www.west-wind.com/weblog/posts/2008/Apr/10/WCF-REST-Configuration-for-ASPNET-AJAX-and-plain-REST-Services to troubleshoot problems with your specific error message.