I have a Wcf Project that is using Linq to Sql -- Serialization Mode = unidirectional with a Wpf Project and a MVC 4 Project.
I have a class library that is holding the dbml for the Linq Classes.
And another Class Library that hold the ViewModels for the Wpf Application
I can add a service reference to the Class Library that holds the ViewModels and access the Wcf methods like normal
client.DoStuff()
Below is the Reference Configuration for the ViewModel C;ass Library
That generates the Correct Reference.Cs
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IMyWebService/DoStuff", ReplyAction="http://tempuri.org/IMyWebService/DoStuffResponse")]
MyDataProject.Data.DatabaseModels.DoStuff[] DoStuff();
When I create a Web Reference for the Mvc project:
(Same Configuration as above but with a Different ReferenceName)
When executing the same
client.DoStuff()
I get the error -- Method "DoStuff" has 1 parameter but is invoked with 0 arguments.
Then I look at the Reference.cs file
And the method looks like this:
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IMyWebService/DoStuffResults", ReplyAction="http://tempuri.org/IMyWebService/DoStuffResultsResponse")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
MyWebProject.MyWebSiteReference.DoStuffResultsResponse DoStuffResults(MyWebProject.MyWebSiteReference.DoStuffResultsRequest request);
Unchecking Reuse types in referenced assemblies allows me to access the method normally, but then I get type mismatches.
Is their a step I am missing for using Wcf in Mvc?
EDIT-- I updated the Reference I am using for the Wpf client that generates the correct .cs
Then I tried this per replies
That generates this
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IMyWebService/DoStuff", ReplyAction="http://tempuri.org/IMyWebService/DoStuffResponse")]
MyWebProject.MyWebSiteReference.DoStuffResponse DoStuff(MyWebProject.MyWebSiteReference.DoStuffRequest request)
Related
I have 3 projects in my solution.
A common class library named ReportBuilderLib
A WPF application named ReportClient that contains a service reference to a 3rd project -
A WCF web service which contains web methods for my application to call upon.
Initially when setting up both the service and the application i added the common library to references on both projects so that i could use the classes i needed to in both.
It quickly cam clear that in the process of generating the code to use the web methods in my client application, it was automatically importing certain namespaces that i had used in service application.
This was throwing me conflicting reference warnings as they were effectively being imported from two separate resources.
I then removed the reference to the library in my report client, i could see that VS was only importing one out of the two namespaces my client requires. Both of which are returned by methods in my ServiceContract!
Having looked at the generated code for the client, it seems to be re-creating the classes i have included in the library and providing only the public properties for access.
Is it possible to use librarys like i am trying to with WCF. Or should i scrap the common library idea and simply create some data transfer classes on the service end?
You should be able to reference the common library on both ends, but it may be useful and less of a headache to implement data transfer classes like you suggested. Using special classes (or serialization like JSON) to send and receive data from the service would make it easier for you to re-use the service for multiple client projects.
Any time you decrease the coupling between layers of an application you make it easier to implement changes/upgrades in the future :)
I have WSDL and XSD as starting point. (WSDL is generated from XSD using WCSF Blue tool). From the WSDL, using a tool, the service code is generated. The project name is “Autogenerated_Service_Project”. Inside this project it will have [ServiceContract] and [DataContract] classes. It has a data contract named “EmployeeDataContract”. In the GetEmployee() service operation, this datacontract is returned to the client.
I have a business layer project named “Business_Project”. It has a method that returns “Employee” entity object.
At present, I am referring the “Business_Project” inside “Autogenerated_Service_Project”.
Business_Project.MyClass b = new Business_Project.MyClass();
EmployeeDataContract d = b.GetAssociate();
return EmployeeDataContract;
The challenge comes when there happens a change in WSDl. When the WSDL is the changed the “Autogenerated_Service_Project” will be recreated and the code mentioned above will be lost.
What is the solution to overcome this code lose?
Note: The “Autogenerated_Service_Project” is the top most project. Ideally, it cannot be referred by any other projects.
You may change the way calling Business layer(may your solution needs additional layer)
But in simple way, you can generate the proxy once, when changes happen to WSDL
handle the changes manually,Or use the tool only for new services.
If the services on WSDL are finely grained, the solution may be applicable.
This can be resolved by using Partial Classes in a different file. The code given in the question can be moved to this new partial class file. This file will persist even if the auto generated file is re-created.
I have a Silverlight app I've been working on. This app relies on a custom class called Customer. Instances of this class are returned from my web service. I've need to add a method called CalculateLoyalty() to this class definition. I want CalculateLoyalty to be available on both the server and client-side (my Silverlight app).
Currently, I can use CalculateLoyalty just fine on the server. Unfortunately, the method doesn't seem to get passed across the wire. I have a hunch its some serialization thing. How do I add a method to my class definition on the server-side and ensure that it is available on the client-side?
Thank you!
When you generate a service reference, it only copies public properties and fields. You can share classes between your server and client and avoid using a service reference. I'm not going to go into detail with how to do this, but here are some related questions that explain what needs to be done.
Create WCF Client without auto generated proxy
Call synchronous WCF operation contract methods asynchronously on silverlight
Even if you do this, I have to recommend against putting logic on your DTOs. I'd recommend creating a LoyaltyCalculator class and passing a Customer to this. In fact, you can do this even if you use generate your client through the Add Service Reference option.
Your defult Silverlight solution will have 2 projects.
MyApp - This is your Silverlight project.
MyApp.Web - This is the host web project.
You don't need to do this, but I recommend adding 2 new projects.
MyApp.Shared - A .NET Class Library
MyApp.Shared.Silverlight - A Silverlight Class Library.
At this point, you will want to add a project reference to the appropriate class library to both your Silverlight project and your Web project.
Add class LoyaltyCalculator to MpApp.Shared, or MyApp.Web if you don't want to make the shared libraries. Go ahead and implement this class here.
Now in MyApp.Shared.Silverlight, or MyApp if you don't want to make the shared libraries, select Add -> Existing Item. Browse to and select LoyaltyCalculator.cs. Do Not Double Click It!!! Instead, click the little down / more arrow on the Add button. Now select Add As Link.
LoyaltyCalculator is now available to both your server and client and you only have to maintain one copy.
Methods are not serialized, only data (property/field values) are, so you must be using a different version of the .cs file on the server than you are on the client. Are you sharing the source code between your web service and silverlight projects?
If you are on .NET 4.5/VS2012, you may be able to create a "Portable class library" with your class in it that can be referenced from both your .NET and Silverlight projects.
I'm currently trying to call a WCF service dynamically See here, therefore, I'm trying to understand what happens behind, when I add a service reference by the GUI of Visual Studio... What's generated..? An object is created and an implicit reference is created...
Are the references contained in a specific container, a sort of pool?
When you add a service reference, VS generates a proxy class for the service. This class implements the interface defined by your service endpoint as its ServiceContract, so it appears to consuming code as if it were the actual object performing the operations, but it contains and uses the communication channel defined by the endpoint and bindings to call the exposed service methods.
If you do not have classes that conform to the signatures of the DataContracts required by the service, VS will generate those classes as well, but if you have already referenced classes that are marked identically to the DataContract (usually because you've referenced the project containing the DataContracts in the project with the client-side code) it will simply use those. Svcutil (the command-line tool) can be given a reference list of locations for these DataContracts as well.
I have a WCF Service project in Visual Studio 2008 that contains about 12 methods, some of which return primitive types like bool or string. I also have a Visual Studio Unit Test Project that references the published WCF Service. The Test Project compiles successfully when all the return types are primitive.
If I add a new method to the service that returns a custom class, publish it and update the service reference in the Test Project, it doesn't compile. The errors are: -
The type 'PublisherFaultException' already contains a definition for 'Reason'.
The type 'PublisherFaultException' already contains a definition for 'PropertyChanged'.
Type 'Publisher.Test.LibraryReference.PublisherFaultException' already defines a member called 'RaisePropertyChanged' with the same parameter types.
all in the auto-generated reference.cs file.
The contract for the method of the WCF Service is: -
Page GetItem(string path);
and the Page class has the DataContract attribute and it's public properties have the DataMember attribute.
I'm reluctant to modify the Reference.cs file as I'll need to do this every time the Service is updated.
Anyone know why this is happening?
Stuart.
When you Add Service Reference, you get a 'reuse types in assembly' option - this is likely to be the key to sorting out the duplication.
Or do you have some Test References that are causing the duplication?
Also, have a look in the References section of the project tree and see if there is anything unexpected in there (do you have references to 2 assemblies that both contain Service References in the same namespace?).
Using auto-generated proxy class it is always pain.
To handle situation like this I using separate assembly with data contract classes and service interface.
Contract dll will have:
public interface IService
{
[OperationContract]
List GetContentList();
}
[DataContract]
public class ContentItem
{
[DataMember] public string Name;
[DataMember] public object Data;
}
The client will have reference to the Contract.dll.
Proxy will be created manually:
class ServiceProxy : ClientBase<IService>, IService
{
public List GetContentList()
{
return Channel.GetContentList();
}
}
The server dll will have reference to the same Contract dll.
So we will be able to avoid any errors with auto generated proxy.
Also the manually created proxy will be simpler, more manageable.
When adding the Service Reference, try clicking Advanced, and select "Generate asynchronous operations".
I think what was happening was that there were some asynchronous methods in the web service, with names ending in "Async", which would conflict with the methods generated in the References.cs.
e.g. imagine the web service contains 2 methods: (1)SayHello and (2)SayHelloAsync.
Generating using the default task-based method produces:
SayHello and SayHelloAsync for (1)
SayHelloAsync and SayHelloAsyncAsync for (2).
The conflict occurred because there were 2 generated methods called SayHelloAsync.
At least I think that's what was going on. Anyway setting "Generate asynchronous operations" worked for me.