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.
Related
I have an asp.net/Blazor VS solution with three projects,
Shared
asp.net core apis
Blazor webassembly.
I created bunch of classes in Shared project and from the other two projects, made a reference to the Shared project. All is good so far.
Then I used Swagger UI to generated stubs for me so I can interact with the remote APIs. Swagger UI created the Service.cs and Contract.cs which is great. The problem is that Contract.cs has redefined the classes that I have declared in Shared projects under it's own namespace. Now I don't know which to use and which to import. If I use my own Shared classes, then I won't be able to use the APIs from swagger in Service.cs without casting. If I modify Contract.cs, then all my changes will be lost the next time I run Swagger UI.
This also resulted in having two DBContext - 1) the one I defined and 2) The one that swagger defined. Now every time I want to do something, I also have to use --context parameter on the command line to specify which DBContext to use.
The question is how can I use my own classes yet use swagger to make life easy in terms of talking to the remote APIs? What is the best practice here?
When you want to use Swagger (client side) then you shouldn't reference the Shared project. The swagger claases is what you get/want then.
But you don't need Swagger in Blazor. The opportunity to share DTO classes in Shared is one of the highlights of Blazor.
If you want some help with the boilerplate stuff on the Client then there are options like refit. See this blog about it.
I create a lot of object classes when I do programming. There are many situations where same object definition will be reused across multiple projects. In windows, I simply build them into .dll file library and include them as the project reference. Therefore, when I need to add additional properties or methods, I just need to do it once and I don't need to worry about go through all projects and manually update the object class definition.
Now, I'm given a project to build an Android application which requires several object classes that's being used within other projects (and must be synced). Of course, I can manually create them within Android and update them every time whenever there's a change, but this is very dangerous because one day in the future, it is very likely to be out-of-synced.
Anyone have suggestions on how to share class library across C# and Android?
Thank you
The only way I know how to do this is to use Xamarin which would allow you to write your entire Android application in C#.
The problem is Android and .Net use completely different runtimes that are not compatible.
I don't have a clear enough view of what your application does, but if you are using the C# objects on a webAPI and looking to keep your objects synced with the client app, you can use Breeze.js - this keeps your client/server biz objects synced. The classes get pulled in dynamically via a meta service call.
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 :)
This might get a little convoluted so please let me know if you need clarification.
I have a solution which contains the following projects
Project A - WPF application
Project B - ASP.NET application (with exposed webservices)
Project C - Class Library
Both project A and project B reference types that are located in project C, but more importantly project A makes webservice calls to project B using types located in project C.
The problem I am running into is it appears that when making webservice calls I have no way of referencing the types located in project C directly but rather need to use the types as exposed by the webservice.
Now the basic idea of why this is done I understand (obviously typically the consumer of your webservice would only have the WSDL to go from) however in my case this is an internal application (which is part of a single solution) so this is not a concern.
The biggest problem I see with continuing this approach is that any updates to the types in project C will need to be reflected in project B and then "refreshed" in project A. This seems pretty nasty to me. Surely there is a smoother path?
Am I wrong? What is a typical approach to this issue?
You may be a little confused here.
The types in Project C and the types you see when you add a reference to your web service are different.
When you added the Web Service reference. Visual Studio used svcutil.exe, read metadata from your web service (I'm assuming .asmx?) and then created proxy classes for you.
Check the types for the Web Service (they will obviously have the same names). Put your cursor on them and pres F12. It'll take you to some designer generated code.
So there is no real workaround as such. When you update your types in Project C and then Update your web services in Project B . You will have to Update Service Reference from Project A Which again uses svcutil.exe and regenerates all your proxies.
Also, this is the same way WCF Services work too.
#giddy is correct - the types exposed by the web service are different to the types contained in Project C - even though their definition may be identical. The web service exposes type information via a wsdl, which Visual Studio uses to generate proxy types.
There is a way around this - you can create an interface which declares all the methods in the web service class, and include it in your shared library. You can then skip the "Add service reference" process, and create the web service proxy with code (you will not need the proxy classes, as you use the classes in the shared library).
Either way, if you make a change to your data transfer objects or the web service class, you will need to update the client by either by requerying the wsdl using "refresh service reference", or by copying the shared library over.
I'm going to create a new PayPal project. Should I just create a regular Class Library project then add the reference to the WSDL? We are not using WCF. I just want to know what the best project type / template I should use if I'm going to share this project with lets say another WAP web project. I simply want to create wrappers for some of the WSDL that we'll be using in part of the PayPal API.
Yes a class library project seems the right thing to use if you're wrapping the code that consumes a web service.
Unless it's going to be tiny (say, just one class) in which case you might want to include it in an existing common project that is already used by both of your consuming projects, just to keep everything a little simpler.