I've created the default WCF Service in VS2008. It's called "Service1"
public class Service1 : IService1
{
public string GetData( int value )
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract( CompositeType composite )
{
if ( composite.BoolValue )
{
composite.StringValue += "Suffix";
}
return composite;
}
}
It works fine, the interface is IService1:
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData( int value );
[OperationContract]
CompositeType GetDataUsingDataContract( CompositeType composite );
// TODO: Add your service operations here
}
This is all by default; Visual Studio 2008 created all this.
I then created a simple Winforms app to "test" this. I added the Service Reference to my the above mentioned service and it all works. I can instanciate and call myservice1.GetData(100); and I get the result.
But I was told that this service will have to be consumed by a Winforms .NET 2.0 app via Web Services, so I proceeded to add the reference to a new Winforms .NET 2.0 application created from scratch (only one winform called form1). This time, when adding the "web reference", it added the typical "localhost" one belonging to webservices; the wizard saw the WCF Service (running on background) and added it.
When I tried to consume this, I found out that the GetData(int) method, was now GetData(int, bool).
Here's the code
private void button1_Click( object sender, EventArgs e )
{
localhost.Service1 s1 = new WindowsFormsApplication2.localhost.Service1();
Console.WriteLine(s1.GetData(100, false));
}
Notice the false in the GetData call?
I don't know what that parameter is or where did that come from, it is called "bool valueSpecified".
Does anybody know where this is coming from? Anything else I should do to consume a WCF Service as a WebService from .NET 2.0? (winforms).
Well well… apparently here's the answer and possible solutions or workarounds.
Related
In c# .Net Framework 4.5 (Visual Studio Ultimate 2012, Version 11.0.61219.00 Update 5), I'm trying to define a service variable at runtime for which webservice to use. Each webservice (there are many) are all defined the same except for the endpoint url but the credentials will not cross over to authenticate. The below condition is menial to simplify the issue at hand. The following code gives the error: Cannot implicitly convert type WebService2.Service to WebService1.Service.
What I've tried: calling functions to return the proper service but the parameters or assignment all require a specific type.
var service = new WebService1.Service();
service = new WebService2.Service();
I want to be able to use the variable service in the rest of the program without having to duplicate code everywhere for using the many web service references.
It seems like what you are looking to do, you would need a common interface between the two services so you could inject whichever service you wish to use.
public class WebService1 : IWebService {...service code}
public class WebService2 : IWebService{...service code}
public interface IWebService{...service methods you will be calling}
Then you could do the following.
IWebService service = new WebService1.Service();
service = new WebService2.Service();
Assuming that the different services share the same method names, you can create an interface that all of the services implement by using the interface
IMyService.cs
interface IMyService
{
void MyMethod(string filter);
}
MyWebServiceImplementation.cs
public class MyWebServiceImplementation : IMyService
{
public void MyMethod(string filter);
}
MySecondWebServiceImplementation.cs
public class MySecondWebServiceImplementation : IMyService
{
public void MyMethod(string filter);
}
MyImplemetationCode.cs
//Use different services from same variable
IMyService service = new MyWebServiceImplementation();
service.MyMethod("filter");
service = new MySecondWebServiceImplementation();
service.MyMethod("another filter");
This question already has answers here:
Hosting WCF service inside a Windows Forms application
(3 answers)
Closed 7 years ago.
I am quite new to WCF. How do you host a WCF service in a WinForm? Obviously the service would only be available while the form is open but this is exactly what I am after.
There are only a few (poor) examples of doing it which I have found and even the MSDN starts talking about hosting one in a WinForm but then goes and implements it in a Windows Service.
You can open your app, and place something like this in your form:
Create your WCF interface
<ServiceContract()>
Public Interface IyourInterface
<OperationContract()>
Function asyouwant ....
Create the class that implements it
Public Class clsYourClass
Implements IyourInterface
Instantiate it from your winforms app.
(This is vb.net)
Dim oYourService As ServiceHost
Dim oYourBinding As New System.ServiceModel.BasicHttpBinding
' Or WSHttpBinding ... configure as you want
Dim aAddress As Uri()
aAddress= New Uri() {New Uri("http://localhost:port")}
oYourService = New ServiceHost(GetType(clsYourClass), aAddress)
oYourService.AddServiceEndpoint(GetType(IyourInterface), oYourBinding, "myWinformService.svc")
oYourService.Open()
4 - Try this: http://localhost:port/myWinformService.svc
Simple service for example..
IService
[ServiceContract]
public interface IService
{
[OperationContract]
string Calculate(int price, int Qty);
}
Service
public class Service : IService
{
public string Calculate(int price, int Qty)
{
return Convert.ToString(price * Qty);
}
}
Consume service by user
Go to Add Service reference option and discover the service. Add the service. Now the service displays in solution explorer.
http://localhost/WCFServiceSample/Service.svc
To check in web browser.
Usage in Application
using WindowsFormsApplicationWCF.ServiceReference1;
Service1Client obj = new Service1Client();
private void btnSubmit_Click(object sender, EventArgs e)
{
string result;
result = obj.Calculate(Convert.ToInt32(txtPrice.Text), Convert.ToInt32(txtQty.Text));
lblresult.Text = "The total price is" + result;
}
Check these links for you reference,
Hosting WCF service inside a Windows Forms application
http://www.c-sharpcorner.com/UploadFile/0c1bb2/consuming-wcf-service-in-windows-application/
https://msdn.microsoft.com/en-us/library/ms731758(v=vs.110).aspx
I have the following simple WCF library which was developed on Visual Studio 2008.
When running WCFTestClinet/javascript(with SOAP) that calls this wcf service I get false value for the following scenario:
1. GetNumber --> output: "Your number is 0"
2. SetNumber --> No output
3. GetNumber --> output: "Your number is 0" instead of output: "Your number is 8" !!!
Can anyone explain why is this happening and how can I solve it?
Thanks
public class Service1 : IService1
{
private int Number;
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
public string GetNumber()
{
return string.Format("Your number is : {0}", Number);
}
public void SetNumber()
{
Number = 8;
}
}
It's all about instances. One instance of your service will by default be instantiated per session; but depending on the configuration (for example using the BasicHttpBinding) the service may be instantiated per call (and/or not even support sessions at all).
Probably because you have configured your WCF service to be per call instead of per session.
Great answer telling the differences: https://stackoverflow.com/a/2542991/70386
How per call works: http://wcftutorial.net/Per-Call-Service.aspx
Per session: http://wcftutorial.net/Per-Session-Service.aspx
Is this in the same instance? As Number will always be set to 0 otherwise
I haven't used the SOAP WCF, but in my work with other web services my understanding is that each time an invocation is made to the service a new instance is created. This means that whatever you did on SetNumber is not there for the following GetNumber as it is a new instance.
If you wanted, you could make that value static to preserve the changes between calls.
This is because by default, WCF 3.5's instance mode is PerCall. This means that for every call WCF receives, it creates a new instance of the service class, performs the call, and then destroys that instance.
If you want to have shared values you can configure your service to be a singleton, like so:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Service1 : IService1
I've a WCF web service method (over 3.5 NET Framework) which needs to be refactored to use optional input parameters. Mi investigation concluded optional parameteres as a concept is being introduced on 4.0 so I need to do some workaround to solve my issue. My code update looks like this:
partial class Class1: IService {
public int MethodName ( int param1, string param2 )
{
// code here
}
public int MethodName ( int param1)
{
// code here
string param2 = FillInInternally();
return this.MethodName(param1, param2);
}
I've also updated my operation contract:
[ServiceContract]
public interface IService
{
[OperationContract(Name = "Alias1")]
int MethoName(int param1, string param2);
[OperationContract(Name = "Alias2")]
int MethoName(int param1);
}
public partial class ServiceClient : ClientBase <IService>, IService
{
public int MethoName(int param1, string param2)
{
return Channel.MethodName(param1, param2);
}
public int MethoName(int param1)
{
return Channel.MethodName(param1);
}
}
Having that explained, I was able to get the Web Service correctly build. Besides oh that Integration Tests also ran perfectly. After that, I needed to install on the server and when trying to test the WSDL, I've faced an issu indicating an error on the svc file at column 1, row 1 ( please note I'm not including the exact error message because I rolled back the WS to the previous version to avoid prod issue during the weekend).
My question is: does somebody think I'm missing something from development? Or will I be able to get my WCF service method correctly overloaded when the "installation?" issues is solved?.
Any comments will be welcome.
Thanks,
.NET Framework 3.5
Visual Studio 2008 Standard Edition
C#
Are you manually constructing the ServiceClient class? I recommend you to use the svcutil.exe tool to generate the proxy and don't encourage yourself to do the modifications directly in the generated proxy code.
If you have generated the proxy through the tool or VS add service reference you should see the IService and the ServiceClient should look something like this,
[ServiceContract]
public interface IService
{
int Alias1(int param1, string param2);
int Alias2(int param1);
}
public partial class ServiceClient : ClientBase <IService>, IService
{
// other stuff
public int Alias1(int param1, string param2)
{
return base.Channel.Alias1(param1, param2);
}
public int Alias2(int param1)
{
return base.Channel.Alias2(param1);
}
}
Note that your client have the methods as Alias1 and Alias2 not MethodName. Please make sure yourself you have the right proxy to talk to service.
I'm looking for a way to cache objects in memory with a RESTful WCF service. The service is completely stateless and is hosted outside of an IIS. I want to implement the caching by myself, so memcached isn't an option.
Right now I'm thinking of hosting a separate stateful System.ServiceModel.ServiceHost that does all the caching. It'll communicate with the rest of the WCF methods through a separate port or by some other means. However I'm not sure if this is the ideal solution to my problem. Has anyone got any tips?
I understand your confusion between stateless service and a stateful host and how the two can interact.
In this code sample I demonstrate conceptually how an in-memory singleton (Caching mechanism, I refer to as CachingProvider henceforth) can be referenced by both the service class (the service instance more precisely during the lifecycle of the request) and the service host (in this case I chose it to be a Console Application)
I assume here, the service interface and class are both located within the console applicaiton project that hosts the service.
In this simple example, my primitive CachingProvider class basically acts as a counter of how many service calls are made to the GetData method, and the service host will poll the CachingProvider every 5 seconds to get the count of service calls made so far.
note: you can use the WCFTestClient utility to test this quickly.
Disclaimer: I by no means suggest that a complex Caching mechanism be implemented as simply as in this sample, this code is merely for demosntration purposes.
namespace ServiceHostConsole
{
[ServiceContract]
public interface ITestService
{
[OperationContract]
string GetData(int value);
}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class TestService : ITestService
{
public TestService()
{
CachingProvider.CallCount++;
}
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
//For demonstration purposes only
static class CachingProvider
{
static CachingProvider()
{
//private static constructor can initialize
//static cacheable resources
_callCounter = 0; //Trivial example of initialization
}
private static int _callCounter;
public static int CallCount
{
set { _callCounter = value; }
get { return _callCounter; }
}
}
class Program
{
static void Main()
{
using (var host = new ServiceHost(typeof(TestService), new Uri("http://localhost/TestService")))
{
host.Open();
//Example how the ServiceHost can report on a persistent in-memory object that is being
//updated each time the service is called.
new Timer(state => Console.WriteLine("# of service calls: {0}", CachingProvider.CallCount), null, 0, 5000);
Console.Read();
host.Close();
}
}
}
}