Wcf referenced Class code update - c#

I am new to wpf and wcf C# application development and stuck into updating the class where wcf service is referenced. For example, Service has a class of testDbConnect and has various service operation contracts functions defined and implemented in iservice.cs and service.cs. Then in wpf class , this service is added as a reference and works perfect when calls the service functions by button click operation. Like this is what I am testing on button click.
Service1Client service = new Service1Client();
if (service.Testdb() == 1) //Testdb is the function in service which is only returning 1
{
MessageBox.Show("Hello there");
}
The problem I am facing, It perfectly starts service and show the message box( hello there) on button click but when I am updating the code even inside the button click , it still keep showing the hello there message box and not updating code. Maybe there is some proxy generation included but I am not understanding it. It'll be great If someone could explain me in easy words and tell me how It could be solved. Thanks

Based on the way you're consuming your WCF Service you need to update your services references.
Suppose you need to rename int Testdb(); in your service for int TestDb();. You go to your contract (IService1.cs), change the signature to match:
IService1.cs
[ServiceContract]
public interface IService1
{
[OperationContract]
int TestDb();
}
Then go to your service and update your method:
Service1.cs
public class Service1 : IService1
{
public int TestDb()
{
return 1;
}
}
Then, on the server side your good to go, but you need to update your service reference on your client app, so your proxies reflect the new method signature. So in your client app you expand Service References folder, right-click ServiceReference1 - or the name of your service reference - node and select Update Service Reference.
Let Visual Studio update the service reference and then you should be able to call the TestDb method by the new name.
Hope this helps!

Related

Find all references with WCF OperationContract and DataContracts

I'm trying to figure out if there's a way to "Find all references" (using the VS feature, as opposed to Control+F entire solution). when it comes to WCF Data and OperationContracts. In case that is unclear:
namespace WcfTestReferences
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello world");
DoStuff();
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
var results = client.GetData(42);
Console.WriteLine(results);
}
static void DoStuff() { }
}
}
namespace WcfTestReferences.WCFApp
{
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
}
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
}
}
Solution looks like this:
Now, if I look at DoStuff() with code lens, I can see that it in fact has a reference to it:
But the same does not hold true for the methods being called in the wcf service:
In the above, the only references to the interface/method is the interface/method. I understand that the reference that I was hoping would be there (from the main method):
var results = client.GetData(42);
is not there, because the client is generated, and is not actually my Service1 implementation... but is there a way to change this?
In the real world, we have a WCF layer with thousands of methods, many of which are not used - but I cannot rely on Code Lens/Find all references to make this determination. Is there any way to change this behavior?
because the client is generated, and is not actually my Service1
implementation
This is the root of the problem.
You are correct - there is no way for your code analyser to determine that the GetData() call you are making from your client is semantically the same thing as the GetDate() service operation you have defined on your interface, because from a binary perspective they are defined in two completely different types.
The root of this is that you're using a service reference. WCF provides service references as the default way of connecting to a service, but in my opinion service references are problematic and should be avoided.
Luckily, WCF provides another way of consuming and calling a service via the user of ChannelFactory<T>. One of the many benefits you will get when using this instead of a service reference is that your client will have use of the service interface via a binary reference to the assembly containing your service definition.
This will allow tools like code lens to resolve references to your interface methods directly to your consuming clients.

Change service url?

In my web application, I have a service reference (not web service reference).
[DebuggerStepThrough]
[GeneratedCode("System.ServiceModel", "4.0.0.0")]
public partial class LoginClient : ClientBase<Login.LoginClient>, Login.LoginSvc
{
public LoginClient() {
EndpointAddress address = new EndpointAddress(ConfigurationManager.AppSettings["login_svc"]);
this.Endpoint.Binding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);
this.Endpoint.Address = address;
}
}
Basically, I have the "login_svc" in the AppSettings. However, it throws the flowing exception:
I don't want to add the service configuration to the web.config system.servicemodel....instead I just want to use the appsettings for the url. How do I do this?
Rather than trying to do this in the constructor, you should just use one of the overloaded constructors already available to you when you instantiate the proxy in your client application. For example,
MyService.Service1Client proxy = new MyService.Service1Client(
new BasicHttpBinding(),
new EndpointAddress("<YOUR ENDPOINT ADDRESS>"));
Also, it's not recommended to edit the auto-generated code like this because if you update your service reference, then those changes will be lost because the Reference.cs file is regenerated at that time. Of course, you could copy the Reference.cs and make it a file in your project you manage as one of your own. It's not clear if you were doing that or not but just wanted to mention this just in case.

"using" of two different libraries with almost identical functions

I'm consuming a SOAP web service. The web service designates a separate service URL for each of its customers. I don't know why they do that. All their functions and parameters are technically the same. But if I want to write a program for the service I have to know for each company is it intended. That means for a company called "apple" i have to use the following using statement:
using DMDelivery.apple;
and for the other called "orange"
using DMDelivery.orange;
But I would like to my program to work for all of them and have the name of the company or the service reference point as a parameter.
Update: If I have to write a separate application for each customer then I would have to keep all of them updated with each other with every small change and that would be one heck of an inefficient job as the number of customers increase.
Can anyone think of a solution? I'll be grateful.
If you have a base contract (interface) for all your services you can use a kind of factory to instantiate your concrete service and only have a reference to your interface in your client code (calling code).
//service interface
public interface IFruitService{
void SomeOperation();
}
//apple service
public class AppleService : IFruitService{
public void SomeOperation(){
//implementation
}
}
Having for example a kind of factory class (you can put your using statements here)
public static class ServiceFactory{
public static IFruitService CreateService(string kind){
if(kind == "apple")
return new AppleService();
else if(kind == "orange")
return new OrangeService();
else
return null;
}
}
And in your calling code (you just add an using statement for the namespace containing your interface):
string fruitKind = //get it from configuration
IFruitService service = ServiceFactory.CreateService( fruitKind );
service.SomeOperation();
You can also use the Dependency Injection principle.
If everything is the same and it's only the endpoint address that is different, maybe you can try changing only that before invoking the web service methods.
MyWebServiceObject ws= new MyWebServiceObject();
ws.Endpoint.Address = new System.ServiceModel.EndpointAddress("http://www.blah.com/apple.asmx");
Use any one client in your implementation. ex. Apple
Write a message inspector and attach this into the out going point
In message inspector replace the name space of the type with appropriate client name space.
EX:
Before Message inspector :MyClinet.Apple.Type
After Message Inspector : MyClient.Orange.Type, if the Provider is Orange.

Using ASMX Web Service Entities in WCF Service

We have a good old .asmx web service (let's call it "Message" Web Service) which we have to preserve for backward compatibility.
The .asmx service exposes this method:
[WebMethod(Description = "Do Something")]
public int DoSomething(Entity1 e)
{
...
}
This web service uses some entities referenced from a DLL, for example:
namespace Software.Project.Entities
{
[DataContract]
public class Entity1
{
[DataMember]
public string property1{ get; set; }
// Lots of other properties...
}
}
This DLL is also used by a brand-new WCF service. Now, I have to call the old .asmx method from WCF. To do so, in the WCF project, I added a reference to the .asmx project, using the "Add service reference" wizard (Advanced - Add Web Reference).
Now, great! It is possible for me to call the DoSomething method from WCF, this way:
Entity1 e1 = new Entity1();
Software.Project.WCFService.ServiceReferenceName.Message m = new Software.Project.WCFService.ServiceReferenceName.Message();
m.Url = ConfigurationManager.AppSettings["MessageWebServiceURL"];
int r = m.DoSomething(e1);
Unfortunately, doing so won't work: I get a compiler error like if Entity1 in WCF is not good as argument for method DoSomething. What I have to do is:
Entity1 e2 = new Software.Project.WCFService.ServiceReferenceName.Entity1();
Software.Project.WCFService.ServiceReferenceName.Message m = new Software.Project.WCFService.ServiceReferenceName.Message();
m.Url = ConfigurationManager.AppSettings["MessageWebServiceURL"];
int r = m.DoSomething(e2);
By doing so, the compiler accepts the call; the problem is that Entity1 in my WCF service is full of fields and data and I would have to copy all the data to the new entity.
I also tried adding the reference to the .asmx as a Service Reference, and flagging "Reuse types in reference assembly", but the result was exactly the same.
I can't believe that there isn't a way to make it understand that Entity1 is exactly the same entity! Is that really impossible?
I am sorry, but i think I have bad news.
You can try to use xml serialization instead of data contract serialization, since asmx does not know about it.
Also, this post say this possible but not so easy: .NET 3.5 ASMX Web Service - Invoked via .NET 3.5 Service Reference - Common Class Reuse
Probably you'll find easier to add your translator class.

Not able to reference Operation contract method in WCF

I am creating a basic Add 2 numbers service in WCF. I have added the following inside IService.cs
[ServiceContract]
public interface ICalc{
[OperationContract]
int Add(int a, int b);
}
Now, inside the Service.cs I have added
public class Service: IService, ICalc {
public int Add(int a, int b){
return a+b;
}
}
Now I build this service and add a service reference to it inside a console application
Program.cs
It is called as
ICalService.Service c = new ICalService.Service();
int result = c.Add(10,20); //Now on this line I cannot seem to get the Add(int a, int b) method
which I had declared earlier.
ICalService
is the name I gave to my service when it was referenced.
Why does the Add(int a, int b) method not show up?
Did you create a proxy for your IService interface or ICalc interface? From what it looks like you must have created a proxy for IService interface.
While adding web reference in the console application, ensure that you are creating a proxy (adding reference) to ICalcService interface.
Maybe it is just a typo or missing from your question, but I don't see the interface IService actually defined, it is only implemented on your class 'Service'. Also, it is sometimes helpful to simply browse to the .svc page you are trying to reference, the browser will sometimes show better error messages than what you would receive by trying to execute the action.
EDIT:
I would ensure that you're able to browse the .svc page and generate a WSDL. If you're able to view the service operation and get a generated wsdl than I believe your service is up and running fine. I would take others suggestion and ensure that you are then creating the proper proxy object.

Categories