Linq to Entities with WCF - c#

I have all my entities in a seperate project in my edmx file and I expose them to my client application using a WCF service.
That means I don't have to give my client app a direct link to the project that contains the edmx file. That would be bad because it contines the object to query the database with.
But only the entities that my WCF service uses can be accessed from my client app. So for example because I have the following code in my service:
public MyClass GetMyClass()
{
return new MyClass();
}
.. I can use access MyClass in my client app with something like:
myServiceInstance.MyClass cls = new myServiceInstance.MyClass()
What about if I have an entity called MyClass2 in my edmx file that I want to use in my client app! How to I instansiate it without giving my client a direct link to my edmx file project or making a usless method in my service layer that returns MyClass2
What are other people doing?
Thanks a lot

We created a separate project with Domain Transfer Object Classes that served as Data Contracts for our various internal WCF services. We then shared the contracts project with those internal services. We had one data service; those methods would translate these domain objects to/from entity objects before/after storing/retrieving. Meanwhile, the external services made use of the standard proxies generated from XSD and WSDL files, and translated to/from the shared domain transfer model.
We had to do this because the object context is not (yet) portable over WCF, unfortunately.
Some considerations for your situation:
If your client app is external to your system, it should not know anything about your EDMX or its classes. It should only know about your WSDL and XSD.
If your client app is internal, then it is no use trying to share the entity classes in EF v1 because it is not supported properly, yet. You need to transfer more than just the classes/objects - you need the context too, which maintains change tracking, and it cannot be done via WCF directly right now.

If the WCF service doesn't use it, what would you want it for? A WCF service (itself) is purely for data transport - the "mex" approach for metadata doesn't share code, so your MyClass2 would be impotent. If you want, you can use assembly sharing at the client, but I really don't recommend this in this case; EF objects at the client is a mess... (plus it won't work on the lightweight frameworks like Silverlight, Client Profile, Compact Framework, etc)
Another option is ADO.NET Data Services; this works over WCF, but gives you a more LINQ-friendly API than the regular WCF approach - and any domain objects that your model exposes should be available on the client data-context.

If you want to do it the "proper" way, you should be creating special classes for your messages that are going across the wire, rather than trying to reuse business entities or data objects as messages. The value in this is that you are then free to change your business entities and data objects without worrying about the contract you have exposed to consumers changing. Every change to your service is a bit more deliberate since it happens independently of changes to data and business logic.
Another way to handle this is simply to use svcutil (or "Add service reference..." though svcutil works better for multiple service endpoints) to generate all the classes that the client will be using instead of adding a reference to the server project. That way, the only classes your client will ever see are the ones exposed by the service.

Related

Share types/models from service reference to client

I am developing a blazor webassembly program with a web api backend. The backend uses a WCF service reference.
How can i share the types/models generated by the WCF service reference with the webassembly program?
You could try to create the client proxy in a different project. I don't remember any options in VS, you may have to use the command line tool.
But I wouldn't.
The generated code usually isn't the prettiest, with lots of metadata, dependencies and properties you don't need or want in your SPA.
So consider writing a layer of DTO classes in a shared project and use AutoMapper to convert the data.
DTOs are Data Transfer Objects, the shared code between Client and Server. In your Client you can use them as Models and/or ViewModels.

Prism + Modules use WCF as dataaccess layer

I am writing an application ( WPF ) where i use the prism framework. I have a client with the shellview.
I have some module's. So that are different projects. Each module is a sepperate project.
The modules are loaded by Unity.
I have the following
Solution
Client
Modules
Client ( app )
Common
Entities
Server
Data
Web
So you can see i have an Data Project under the server folder. There you can find the edmx.
The Web project is empty, the Entities project is also empty.
The Client (app) has a shellview with its bootstrapper.
The client works. Only the data access layer must be integrated.
What is the best solution to do the data access? WCF, something else?
What template do we need to use for the entities. How can we use the service in the modules where al the code (View/ViewModel) is?
Pff, i am looking and read so much.
Found some topics on stackoverflow. But none of the topics start's from the begin.
Hope someone can help me.
I suggest you to generate POCO or STE on .edmx and use the Repository Pattern for database access. Create a Separate WCF Service Project and call these repositories.
Your Prism Solution will have a Proxy Project with Static Class to return Service Object and your Client (Prism) App will call the WCF Services.
May be you can have a look at Calcium SDK (http://calcium.codeplex.com/) which leverages Prism modular app development along with support for WCF services.
If you are familliar with WCF and EntityFramework on the server side then this is the way to go.
In order to reuse the generated proxy classes from services you can keep your service references in a common assembly that you reference from all modules. Something like "Infrastructure" is a good naming convention.
In case one of your modules needs a unique functionality then you put the service reference on that project.
In case of WPF clent: Use entity framework code first and seperate your Model classes in a seperate assembly so you can reuse them in your main client and modules.
In case of silveright client:
If duplicate model classes and namespaces when generating the service proxy is an issue for you you can checkout WCF RIA Services. Always keep in mind that you can link two assemblys a silverlight and a .net one using RIA Link in Visual Studio project file properties. Then any server side code file you chose can be reused on the client. This is possible using the "shared" suffix in your filename (ex: enums.shared.cs) regardless if you are using WCF services or not. You can find out more here and here
Hope this helped.

Extending WCF Interface with Plugins

I'm building an application with a Silverlight frontend that communicates with a backend service via WCF. My service has an interface that handles all of the core communication with the frontend.
The backend can be extended with various plugins and I plan on loading custom silverlight modules for configuring these plugins with prism. The problem is, these plugins will add additional functions that aren't part of the base WCF interface. I'd like to maintain a single endpoint for all my communication (i.e. not requiring additional router configuration).
I'm looking for some ideas on how to approach this implementation. My "best" thought at the moment is to have a function in my core interface that accepts a function name and a list of parameters, and using reflection to find the function to call in the specific plugin, I'm not a fan of this for many reasons.
What are your recommendations for building an extensible WCF interface on a single endpoint?
Thanks
I can think of two ways this is typically handled:
XML contracts - basically, your service becomes nothing more than an XML parameter, with an XML return value. Then, you can either parse or serialize/deserialize the command going between the client and the server. Because your contract only exposes the single XML, what you do "inside" is up to you. You can do things like transmit schemas for the new methods to validate calls constructed on the client, etc.
RESTful service - this is another easy way to do it. Because the REST contract is the URL, adding a new extension is as simple as providing a new URL format. You could communicate via a formatter to the client how to invoke new calls for the extension methods and manage these as you build out the application.
Realistically, however, I doubt your font-end is going to be able to handle all edge cases and dynamically build new screens and validations as you extend the server side. In this case, a better approach in my opinion would be to construct the Silverlight application as a module application using MEF. When you have an extension on the server, you can simply provide an extension XAP for the client. You can have the server enumerate XAP files in a directory for plugins and send these to the Silverlight application, so when a new one becomes available it can dynamically load these. The XAP would contain the code to wire to the new WCF contracts for the extended functionality.

KISS: Simple C# application which communicates with a RESTful web service

Following the KISS principle, I suddenly realised the following:
In .NET, you can use the Entity Model Framework to wrap around a database.
This model can be exposed as a web service through WCF.
This web service would have a very standardized definition.
A client application could be created which could consume any such RESTful web service.
I don't want to re-invent the wheel and it wouldn't surprise me if someone has already done this, so my question is simple: Has anyone already created a simple (desktop, not web) client application that can consume a RESTful service that's based on the Entity Framework and which will allow the user to read and write data directly to this service?
Otherwise, I'll just have to "invent" this myself. :-)Problem is, the database layer and RESTful service is already finished. The RESTful service will only stay in the project during it's development phase, since we can use the database-layer assembly directly from the web applications that are build around it. When the web application is deployed, the RESTful services are just kept out of the deployment.
But the database has a lot of data to manage over nearly 50 tables. When developing against a local database, we can have straight access to the database so I wouldn't need this tool for this. When it's deployed, the web application would be the only way to access the data so I could not use this tool. But we're also having a test phase where the database is stored on another system outside the local domain and this database is not available for developers. Only administrators have direct access to this database, making tests a bit more complex.
However, through the RESTful service, I can still access the data directly. Thus, when some test goes wrong, I can repair the data through this connection or just create a copy of the data for tests on my local system. There's plenty of other functionality and it's even possible to just open the URL to a table service straight in Excel or XMLSpy to see the contents. But when I want to write something back, I have to write special code to do just that. A generic tool that would allow me to access the data and modify it would be easier. Since it's a generic setup around the ADO.NET Data services, this should be reasonable easy too.
Thus, I can do it but hoped someone else has already done something similar. But it appears that there's no such tool made yet...
You are referring to ADO.Net Data Services. It basically creates an Entity Database Model and adds a REST frontend to the service using ASMX. There is a How To article availble from MSDN here on consuming the service using .Net. I have also done the same thing using the normally WebClient class in .Net in the past.
You can also look at the WCF REST Starter Kit if you want to roll your own based on Entity Framework. The starter kit also contains a handy new WebClient class that can be used to communicate with REST services.
Clarification
There is no prebuilt application client that I am aware off which will talk to these service, since they are pretty much accessing the data using Web Services. There is the Microsoft Smart Client Factory which is most likely the closest thing I have worked with.
I mentioned the above 2 options since they already have libraries in .Net that work with them directly, either as a referenced Web Service, or for the more adventurious, myself included, using the WebClient library or alternatively the new HTTPClient library in the WCF REST Starter kit.
I have used both, in Windows, Web, Silverlight and WCF. The latter being the easiest since they are focussed at REST.
We are currently investigating Prism which strongly leans to using this method when using WCF for front-end development.
Assumption
With regards to this question, you are making a generic assumption that wrapping ADO Entity Framework with a WCF service it will be generic. ADO.Net Data Services is the closest you will get, however the structure of the database will fundamently change the way you interact with it. Going a level higher in a "generic" way would be dangerous, as these 2 technologies, individually or together, are already as generic as possible.
In addition to Data Services (+1), consider RIA Services. It's like a domain-specific version of data services for Silverlight or WPF clients. Less flexible, but easier, than Data Services.

C#: Webservice changes expected parameter type (from a normal POCO to a an autogenerated class)

I have the following class in Class Library: Artist, which is a POCO
Now I have a method in a web-service (which has a reference to the mentioned-above library) with a signature like this:
[WebMethod]
public int Artist_AddArtist(Artist a) {
//
}
When I try to consume this service from an application (that also has a reference to the mentioned-above Class library), the expected parameter of the Artist_AddArtist method is not Artist, but a new type of Artist that is being generated in Reference.cs which is a partial class that is auto-generated.
Thus since in my application I use, supposedly the same Artist class from the library and now the Web Service method expects this new auto generated type, I cannot pass an instance of it to the web-service.
How can I fix this issue?
Maybe switching to WCF services is an option for you. As far as I remember, with a WCF service, you can reuse the same types on ther server and client side.
This article explains how to migrate an ASMX web service to a WCF service.
You cannot, and should not, fix the problem.
Some others will tell you to do things like edit the generated file, but that's not a good practice (as the changes will go away as soon as the Web Reference is updated).
What you're seeing is by design. See Basics: How Web Services Work.
Briefly, when you use "Add Web Reference", Visual Studio downloads the WSDL file from the service, and uses the XML Schemas from the WSDL to create some proxy classes to represent the XML described by the schema. It also creates a proxy class for the service itself, having methods for each operation in the service.
The proxy data classes can serialize to the XML that the service is expecting to receive, and can be deserialized back from the XML that the server sends in reply.
One way to think of it is that you only have this problem because both client and service are .NET. If your client were written in Java, then you wouldn't be thinking of sharing classes.
Note that WCF can do this, if necessary. It introduces a dependency between the client and service (they both have to use compatible versions of the assembly containing the classes), but when you need to do it, the option is there. It's useful when there is behavior in these classes that must be used both by the client and by the service.

Categories

Resources