locked
WCF Entity Framework DataAnnotations MVC WPF RRS feed

  • Question

  • Hi there

    I asked this question earlier in Architecture Geenral forum but haven't got any reponse. Hope to get answer over here -

    I am looking out for a good gudiance on designing the diferent layers of an modern application. By modern application I mean a .NET 4.0 based app, whcih uses the domain design priciple using the entity framework, services using the WCF and front end implemented in MVC & WPF with the help of some popular design patterns like Repository, Unit of work.

    What I got till  now for my POC is

    • the data layer using the Entity Framework Code First, implemented using Repository & unit of work pattern.
    • The MVC application is also ready with one controller & a Index method.
    • The business layer that defines some entities (Business Entities BE/DTO) and some business process classes.

    Now I want to have a WCF service which will expose the functionality over one of the endpoint.

    The issue that I am facing is the how should I exposed my data over the service?

    • exposing my EF model doesnt seems to be good idea since my model would get exposed to other layers.
    • This leaves me the option to translate all my data entities into business entities before sending them over the service to clients. Here I am losing the DataAnnotations capability of the framework, since the validation attributes dont get serialize and will not be available to clients. (They wil start imposing there own validation). Also is it a good idea to expose my BE/DTO as DataContract usign WCF service or should I have a DataContract as well.

    I am looking for guidance on how to make the DataAnnoations functionality impose by server on clients thorugh WCf service? Since the MVC and WPF already have builtin support for them.

    Please advise.


    Pravin Chandankhede
    Tuesday, November 22, 2011 3:52 AM

Answers

  • Hi

    of course, when your client doesn't know the type of entity while adding service reference it just creates the proxy type decorated with datacontract and datamember attributes,

    for your case i will suggest, Have all your entities alone in seperate project (if you are using Dto's only Dtos) , so that your WCF and MVC project can have reference.

    In this case, at MVC project side it checks type is already available and creates datasources ({ProjevctName} -> properties -> datasources) refers to actual type, so anyhow MVC uses reflection to generate validation script right?

    Hope this helps you....


    If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".
    Tuesday, November 22, 2011 10:52 AM
  • Hi

     

    So you are suggesting to share the Datacontract(my DTO's with validation attribute) explicitly between the WCF service and the MVC/WPF app. And then use the "use types from reference assemblies" feature from advanced options of "add service reference".

    Given the scenario that both client and server runs on .NET, this seems fine to me but is this best practise?

    When I am going to deploy these components on  various tiers will it be easily maintainable?

    Is it OK to share the assemblies between client & server in an SOA environment?

     

    Please advise

     

     


    Pravin Chandankhede
    Tuesday, November 22, 2011 3:00 PM
  • Hello, actually in most cases, it is recommended that you do not share data access entities with clients. Your service should return its own set of data contracts, which are more user friendly rather than database friendly. This has a lot of advantages. For example, if one day you need to move to another data source, you only need to change the WCF code. As long as your WCF data contract remains the same, client applications do not need to be updated.

    It is also not a good idea to share assemblies, unless you only need to support .NET clients.

    In your case, you can perform the validation in the data access layer using existing Entity Framework code. You just need to write an additional service layer, and conver the Entity Framework objects to your own data contract objects. You can also perform an additional validation on the service layer if you like, but I think validate on the data access layer should be enough.


    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.
    Wednesday, November 23, 2011 3:53 AM
  • Yi-Lun Luo

    That's the same thign I believe, Dont share assemblies share only the data contracts prefebly using the "add service reference" functionality!!!

    The issue that I am facing is I have some Data annotation on my Entity classess in Data Layer. and I am again repeating those on DataContract (This I do not like cinse its NOT DRY). Even then when the service reference is added, those data aanotations are not available on the client side (I can understand the design decision for such behaviour).

    But the issue is MVC application can use these data annotations to provide a very good data validations at client side itself. But since the data annotations doesn't get to the client we are loosing all those good inbuilt validation feature.

    I have no other option to again apply all those attributes using partial classes technique  to my models in MVC app( This would be the third time I am aaplying those attributes).  Even WPF is capable of understanding these validation attributes.

    Did you get my concern - Single validation attribute applied at three different places(maintaining them is a different headache).

    Isn't there a simple way to define these attributes at one places and get them applied at data layer(enforced by EF, service layer(Deliberate validation using ValidatorContext) and client(ModelBinder in MVC)(I understand this wont be possible with non .NET clients, buts thats OK with me).

    Any thoughts?


    Pravin Chandankhede
    Wednesday, November 23, 2011 7:17 AM

All replies

  • Hi

    of course, when your client doesn't know the type of entity while adding service reference it just creates the proxy type decorated with datacontract and datamember attributes,

    for your case i will suggest, Have all your entities alone in seperate project (if you are using Dto's only Dtos) , so that your WCF and MVC project can have reference.

    In this case, at MVC project side it checks type is already available and creates datasources ({ProjevctName} -> properties -> datasources) refers to actual type, so anyhow MVC uses reflection to generate validation script right?

    Hope this helps you....


    If this post answers your question, please click "Mark As Answer". If this post is helpful please click "Mark as Helpful".
    Tuesday, November 22, 2011 10:52 AM
  • Hi

     

    So you are suggesting to share the Datacontract(my DTO's with validation attribute) explicitly between the WCF service and the MVC/WPF app. And then use the "use types from reference assemblies" feature from advanced options of "add service reference".

    Given the scenario that both client and server runs on .NET, this seems fine to me but is this best practise?

    When I am going to deploy these components on  various tiers will it be easily maintainable?

    Is it OK to share the assemblies between client & server in an SOA environment?

     

    Please advise

     

     


    Pravin Chandankhede
    Tuesday, November 22, 2011 3:00 PM
  • Hello, actually in most cases, it is recommended that you do not share data access entities with clients. Your service should return its own set of data contracts, which are more user friendly rather than database friendly. This has a lot of advantages. For example, if one day you need to move to another data source, you only need to change the WCF code. As long as your WCF data contract remains the same, client applications do not need to be updated.

    It is also not a good idea to share assemblies, unless you only need to support .NET clients.

    In your case, you can perform the validation in the data access layer using existing Entity Framework code. You just need to write an additional service layer, and conver the Entity Framework objects to your own data contract objects. You can also perform an additional validation on the service layer if you like, but I think validate on the data access layer should be enough.


    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.
    Wednesday, November 23, 2011 3:53 AM
  • Yi-Lun Luo

    That's the same thign I believe, Dont share assemblies share only the data contracts prefebly using the "add service reference" functionality!!!

    The issue that I am facing is I have some Data annotation on my Entity classess in Data Layer. and I am again repeating those on DataContract (This I do not like cinse its NOT DRY). Even then when the service reference is added, those data aanotations are not available on the client side (I can understand the design decision for such behaviour).

    But the issue is MVC application can use these data annotations to provide a very good data validations at client side itself. But since the data annotations doesn't get to the client we are loosing all those good inbuilt validation feature.

    I have no other option to again apply all those attributes using partial classes technique  to my models in MVC app( This would be the third time I am aaplying those attributes).  Even WPF is capable of understanding these validation attributes.

    Did you get my concern - Single validation attribute applied at three different places(maintaining them is a different headache).

    Isn't there a simple way to define these attributes at one places and get them applied at data layer(enforced by EF, service layer(Deliberate validation using ValidatorContext) and client(ModelBinder in MVC)(I understand this wont be possible with non .NET clients, buts thats OK with me).

    Any thoughts?


    Pravin Chandankhede
    Wednesday, November 23, 2011 7:17 AM
  • There's a trade off. If you want simpler code, you can share the assembly between the client and the service. You can even remove the WCF layer. If you want better architecture, you have to write more code. It's easy to implement a feature, but it is not easy to make it work well (think of all those issues related to performance, security, reusuability, maintanance, etc.). After all, validation is a service implementation detail, which is not shared with clients. Client can do its own validation, and the validation logic can even be completely different from service validation logic. If it's just a simple application, then take the simple approach to quickly implement it so you can spend your time on more important tasks. If it's an important product, then spend your time to do it the right way.
    Lante, shanaolanxing This posting is provided "AS IS" with no warranties, and confers no rights.
    If you have feedback about forum business, please contact msdnmg@microsoft.com. But please do not ask technical questions in the email.
    Wednesday, November 23, 2011 8:12 AM
  • you made a good point I agree with you point you on the trade off.

    Also I think this should be dependent on the size of application as well.. becasue for simple applications there no need to have deliberate complexity. If something can be kept simple then it should be. Thanks


    Pravin Chandankhede
    Wednesday, November 23, 2011 3:50 PM