I have developed one WCF application, and it is working as a middle layer between the database and my web application. Now my client wants to transfer this WCF to REST-based using ServiceStack.
I have looked around it on GitHub and tried to build a demo. I have created a start up template using NuGet, so it includes a Hello & Todo example.
How can I transfer my logic as object based (DTO)? Because most of the functions I have with different parameters and return the result as a dataset.
How can I make a client in C#? And which reference do I need to add?
When I hosted sample application on IIS after adding the startup template using NuGet, I could not able to find any resources. Is there a specific setting I need to do when I need to host it on IIS?
If you haven't already done so go through the Creating REST Services with ServiceStack presentation.
1) If you've seen ServiceStack's Hello World example it shows you that the only steps needed to do to create a web service is to just provide:
//1. A Request DTO
public class Hello : IReturn<HelloResponse> {
public string Name { get; set; }
}
//2. A Response DTO
public class HelloResponse {
public string Result { get; set; }
}
//3. The web service implementation that takes a Request DTO and returns a Response DTO
public class HelloService : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = "Hello, " + request.Name };
}
}
The above example shows all the code needed to create the Hello web service.
You should be able to re-use a lot of your existing type and logic from your WCF method and just copy it in the Any() method.
2) One of the benefits of ServiceStack is that you don't need to add a ServiceReference, i.e. you can re-use the same generic Service Client and your DTOs for all your web services. e.g:
//Using JSON:
IServiceClient client = new JsonServiceClient("http://localhost/path/to/servicestack");
//Using XML:
IServiceClient client = new XmlServiceClient("http://localhost/path/to/servicestack");
var response = client.Send(new Hello { Name = "Arun" });
Console.WriteLine("Received: " + response.Result);
On the /metadata page there is also a link to your webservices WSDL where you could create generated service clients should you wish. However this is not the recommended approach since it requires much more friction then just using your existing DTOs.
3) ServiceStack Web Services are already an ASP.NET application, i.e. ServiceStack is just a set of IHttpHandler's you can configure to run inside of a normal ASP.NET or MVC web application by adding a Web.config mapping to your web applications Web.config.
Basically you can treat a ServiceStack web service as a normal ASP.NET web application, in fact the Hello World Tutorial shows you how to do this from creating an empty ASP.NET application.
You may also be interested in checking out The Starter Templates example projects which shows you the minimum about of setup required to configure ServiceStack to run in a variety of different hosting options, i.e. ASP.NET / Windows Service / Console Application, etc.
Related
I have a group of services that are written in WCF. This is a whole logic which cannot be changed and rewritten to another technology.
I want to create an application in .NET Core 2.1 and connect to WCF services. I am using library which has clients for all services with custom communication, bindings, endpointbehaviors etc. This library is written in .NET Framework v4.7.2, so if I want to use it in my .NET Core App I need to add target to the .net standard 2.0.
I did this and now I am having a problem as some classes are not supported in .netstandard2.0.
public class UserInfoBehavior : Attribute, IServiceBehavior, IEndpointBehavior
{}
For Example above class is used for adding EndpointBehaviors to my Channel:
public DashboardServiceClient(InstanceContext instanceContext, string endpointConfigurationName, string endpointAddress)
: base(instanceContext, endpointConfigurationName, endpointAddress)
{
base.ChannelFactory.Endpoint.EndpointBehaviors.Add(new UserInfoBehavior());
}
The problem is that IServiceBehavior is not available in .netstandard 2.0. Do you know some equivalent for this? There are more classes which I am using and are not supported:
RemoteEndpointMessageProperty,
Method Open() which is in ClientBase,
ChannelDispatcher,
and also EndpointDispatcher which is empty class in System.ServiceModel.Dispatcher
I am wondering if it is possible to target it to netstandard
You can call the wcf service by adding a connected reference.
Select the WCF Web Service Reference Provider.
Enter your WCF Service URI:
Check all quotes and finish.
You can see this folder in the client.
Just call it in the client, and you can acess the method in WCF Service.
static void Main(string[] args)
{
ServiceReference2.Service1Client service1Client = new ServiceReference2.Service1Client();
var t=service1Client.GetDataAsync(15);
Console.WriteLine(t.Result);
Console.ReadKey();
}
You can also refer to this link to call the wcf service:
Use the WCF Web Service Reference Provider Tool
I have an issue related with WCF Service and Web API with below steps.
Create a WCF Service Application which is Service1.svc
Right Click this project, and Add -> Web API -> Web API Controller Class
Could I host Web API in WCF solution like this? I did not find any place to configure or register Web API, so if I run this project, Web API will not run correctly.
Code For hosting web api
public class Service1 : IService1
{
public Service1()
{
var config = new HttpSelfHostConfiguration("http://localhost:8080");
config.Routes.MapHttpRoute(
"API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
using (HttpSelfHostServer server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}
}
No, you can't add a web API controller into a WCF service project and expect it to work. WCF and WebAPI have almost no overlap in terms of their dependency on the BCL.
I think Prashant, in his comment, puts it very eloquently when he argues:
why you want to do this ?
You can host both a WebAPI project and a WCF service project in the same solution, but even though you can do this, why would you want to?
If you want to expose the same endpoints over both SOAP and REST you can already do this using only WCF.
I have been going through the book "Learning WCF" trying to get my head around creating and using WCF web services. The first part of the book walks the reader through creating and then consuming a simple "Hello World" web service.
The problem I am having is that the client application seems to have no know the structure of the WCF Interface when calling it. How can this be necessary if a web service could be called from any number of programming languages?
I have listed the relevant example code below ...
Here is the code for the Interface
[ServiceContract(Namespace="http: //www.thatindigogirl.com/samples/2006/06")]
public interface IHelloIndigoService
{
[OperationContract]
string HelloIndigo();
}
Here is the code for the Service that hosts the web service
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(HelloIndigo.HelloIndigoService) ,
new Uri("http: //localhost: 8000/HelloIndigo")))
{
host. AddServiceEndpoint(typeof(HelloIndigo. IHelloIndigoService) ,
new BasicHttpBinding(), "HelloIndigoService");
host. Open( );
Console. WriteLine("Press <ENTER> to terminate the service host") ;
Console. ReadLine();
}
}
Here is the code for the client app that consumes the WCF service
This is where I get confused. Since this client application could be any language capable of calling a web service why is there a necessity of knowing the definition of the interface?
using System. ServiceModel;
[ServiceContract(Namespace = "http: //www.thatindigogirl.com/samples/2006/06")]
public interface IHelloIndigoService
{
[OperationContract]
string HelloIndigo( );
}
static void Main(string[ ] args)
{
EndpointAddress ep = new
EndpointAddress("http: //localhost: 8000/HelloIndigo/HelloIndigoService") ;
IHelloIndigoService proxy = ChannelFactory<IHelloIndigoService>.
CreateChannel(new BasicHttpBinding(), ep);
string s = proxy. HelloIndigo();
Console. WriteLine(s) ;
Console. WriteLine("Press <ENTER> to terminate Client.") ;
Console. ReadLine();
}
Am I missing an important point here? Perhaps my understanding of what is needed to consume a web is lacking. My goal is to be able to use WCF to create a .NET service that could be called from any programming language or environment.
Might anyone suggest a good tutorial on creating "cross platform consumable" web services from within .NET? Thanks!
This approach is based on shared interface (the book acutally does not share the interface but instead it uses local copy) and is successfully applied in environment where both client and server are written in .NET. This approach is not usable for interoperability or SOA solutions.
Other approach uses metadata exposed by the service. Metadata are defined as WSDL document plus several XSD documents. These metadata files are way to provide information about your service to both .NET and non .NET developers. The book contains definition of Metadata (mex) endpoint so you will definitely read about that.
Using metadata in .NET means creating service proxy. You can do it automatically using Visual studio's Add service reference or command line utility svcutil.exe. Anyway generated proxy code will probably still contain the interface created from metadata. It is used to create transparent abstraction of the service for the client.
'The interface' doesn't mean a .NET interface file, it means the more general programming interface - a set of objects with properties, and methods with parameters. This is also called the service contract.
The reason that the client and the service need to share (i.e. both know about) the interface is simple when you think about it - if the client doesn't know the interface, how do they know what operations are available and what the expected request/response objects should look like?
Every WCF service is composed of
A - address
B - binding
C - contract
The contract is declared using an interface on the serverside. It declares which methods are available to the client. If you are using a http binding you can invoke a service operation by issuing a http request (using a http client in any library or language - or even a web browser) pointed at the correct address. So the client does not need any interface reference at all. It just needs to follow the ABC of the service.
Here is a nice blog on WCF and Java interopability.
To answer your question on how to develop 'cross platform consumable' web services, consider the REST approach. Making REST-style web services truly makes them independent of the platform that consumes them. Simply put, they use the already well established HTTP protocols everything supports: GET and POST Http methods.
You could then have a Java app simply make POST calls to your WCF services with your own custom XML content in the payload without having to fiddle with more complex stuff like making SOAP wrappers and the like. Check out Rob Bagby's article on REST:
http://www.robbagby.com/rest/rest-in-wcf-part-i-rest-overview/
Here's what I've done so far:
1) Created an ASP.NET MVC relying party application and secured it with ADFS v2.0. This works.
2) Created a WCF Service using the Claims-Aware service template for an ASP.NET website. I've turned ASP.NET compatibility for the service ON because the service wouldn't activate otherwise. I've moved the interface for said service to a 'SharedContracts' assembly.
3) Set up the WCF service as a relying party using the "Add STS" reference, also pointing at my ADFS server.
4) Configured the ADFS server to include the WCF service as a relying party and issue it LDAP claims.
What I want to do now is talk to the service using ActAs. In other words, when someone hits HomeController.Index() from the ASP.NET MVC site with a token full of claims (remember the MVC site is a relying party), I want this method to programmatically create a client proxy and invoke the single service method I have on the WCF service (a method called "HelloClaim", which is nearly identical to the stock method that comes with the claims-aware service template).
Here's the code I've got so far:
[ValidateInput(false)]
public ActionResult Index()
{
SecurityToken callerToken = null;
IClaimsPrincipal claimsPrincipal = Thread.CurrentPrincipal as IClaimsPrincipal;
if (claimsPrincipal != null)
{
foreach (IClaimsIdentity claimsIdentity in claimsPrincipal.Identities)
{
if (claimsIdentity.BootstrapToken is SamlSecurityToken)
{
callerToken = claimsIdentity.BootstrapToken;
break;
}
}
string baseAddress = "http://khoffman2/SecureServices/Service.svc";
ChannelFactory<IHelloClaim> factory = new ChannelFactory<IHelloClaim>(new WebHttpBinding(), new EndpointAddress(baseAddress));
factory.ConfigureChannelFactory<IHelloClaim>();
IHelloClaim hello = factory.CreateChannelActingAs<IHelloClaim>(callerToken);
string result = hello.HelloClaim();
ViewData["Message"] = "Welcome to ASP.NET MVC!";
}
return View();
}
When I attempt to invoke the method, I get the following error message:
Manual addressing is enabled on this factory, so all messages sent must be pre-addressed.
I'm pretty sure I'm just not doing enough to configure the binding and the endpoint programmatically. If any of you have done this before or you know how to do it, I would love to be able to get this working.
Bottom line is I'm just making use of the basic identity delegation scenario - the only difference is I'm not using generated client proxies.
Take a look at this guide over at TechNet as it has a walkthrough on how to setup the scenario you've described:
http://technet.microsoft.com/en-us/library/adfs2-identity-delegation-step-by-step-guide(WS.10).aspx
In their example, I believe they are using standard WebForms, but in the case of MVC you can put the ChannelFactory initialization within the Global.asax within the Application_Start.
I am trying to create a WCF application that will be hosted in a Windows Service
I have two options in Visual Web Developer
1) New Website -> WCF Service
2) New Project -> WCF Service Application
Which will be suitable for creating service that can be hosted in windows service? Is there any tutorial explaining hosting in windows service using any of the above mentioned methods?
Thanks
Lijo
In most cases what you'll actually want to do is create two projects; first a WCF Service Library (that's under the WCF templates) and then a Windows Service (which is under the Windows templates), then reference the WCF Service Library from your Windows Service.
The WCF Service Library holds all of your WCF-specific classes - contracts, services, etc. - then you just create a ServiceHost inside the Windows service. This last part requires very little code:
public class MyService : ServiceBase // Windows Service class
{
private ServiceHost host;
protected override void OnStart(string[] args)
{
host = new ServiceHost(typeof(MyWcfLibrary.MyWcfService));
host.Open();
}
protected override void OnStop()
{
host.Close();
}
}
There's a more detailed tutorial here.
As for creating your service - if you already plan to use a NT Service as your host, just use a class library and then add a WCF service to that. Neither of the two options given will give you something suitable for using in a NT Service.
For hosting, see:
MSDN: Host a WCF Service in a managed application
Hosting WCF Services
Lijo,
This page in the MSDN help shows you how to create the WCF service by starting with a Console application. I was able to get everything done with this as a starting point.