none
Expose EF5 entities & methods as OData using wcf service for javascript RRS feed

  • Question

  • Dear all,

    I am new in this area, so bear with me..

    I built a web-service that is responsible of exposing EF5 entities to the client.

    [JSONPSupportBehaviorAttribute]
    //[ServiceContract]
    public class FooDataservice : DataService<FooEntities>
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            // Give readonly access to all of the entities 
            config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
            // Pagesize will change the max number of rows returned
            config.SetEntitySetPageSize("*", 25);
    
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
        }
    
        //[OperationContract]
        [WebGet]
        public int AddNumbers(string nbr1, string nbr2)
        {
            return Convert.ToInt32(nbr1) + Convert.ToInt32(nbr2) ;
        }
    
        //[OperationContract]
        [WebInvoke(Method = "GET",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        UriTemplate = "/AddNumbers3/{nbr1}/{nbr2}/{nbr3}")]
        public int AddNumbers3(string nbr1, string nbr2, string nbr3)
        {
            return Convert.ToInt32(nbr1) + Convert.ToInt32(nbr2) + Convert.ToInt32(nbr3);
        }
    }
    

    When I open the .svc file with the IE, I can see the XML of entities as ATOM & collection.

    I hosted the web-service on IIS 7, then I created a console application to access the web-service

    I can get the entities with no problem...

    My question now is,

    How can I add methods to the previous WS definition to be called from the client (console app)

    I tried to add two methods as shown in the script above, But how can I call them from the console app ??

    Best

    Waleed Seada

    Thursday, December 29, 2016 11:07 AM

Answers

  • Hi Waleed,

    Are you able to access these methods in IE? If not, you need to set rules to indicate which service operations are visible. Something like below:

    public static void InitializeService(DataServiceConfiguration config)
            {
                // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
                // Examples:
                // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
                // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
                config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
                config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
                config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
            }

    After you could access the method in IE with address like “http://localhost:50861/WcfDataService1.svc/AddNumbers?nbr1=%2712%27&nbr2=%272%27”. You could call them from console app like below:

                Uri svcUri = new Uri("http://localhost:50861/WcfDataService1.svc");
                WCFAPI.WCFODataService.TestDBEntities context = new WCFODataService.TestDBEntities(svcUri);
                Uri methodUri = new Uri(String.Format("http://localhost:50861/WcfDataService1.svc/AddNumbers?nbr1='{0}'&nbr2='{1}'", 11, 22));
                int result = context.Execute<int>(methodUri).FirstOrDefault();

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Paladin2k Saturday, December 31, 2016 12:06 PM
    Friday, December 30, 2016 4:25 AM

All replies

  • Hi Waleed,

    Are you able to access these methods in IE? If not, you need to set rules to indicate which service operations are visible. Something like below:

    public static void InitializeService(DataServiceConfiguration config)
            {
                // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
                // Examples:
                // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
                // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
                config.SetEntitySetAccessRule("*", EntitySetRights.AllRead);
                config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
                config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V3;
            }

    After you could access the method in IE with address like “http://localhost:50861/WcfDataService1.svc/AddNumbers?nbr1=%2712%27&nbr2=%272%27”. You could call them from console app like below:

                Uri svcUri = new Uri("http://localhost:50861/WcfDataService1.svc");
                WCFAPI.WCFODataService.TestDBEntities context = new WCFODataService.TestDBEntities(svcUri);
                Uri methodUri = new Uri(String.Format("http://localhost:50861/WcfDataService1.svc/AddNumbers?nbr1='{0}'&nbr2='{1}'", 11, 22));
                int result = context.Execute<int>(methodUri).FirstOrDefault();

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Paladin2k Saturday, December 31, 2016 12:06 PM
    Friday, December 30, 2016 4:25 AM
  • Thanks Edward,

    I found your rely very useful in calling the method, actually the thing made the difference is the attribute on the method itself.

    This definition doesn't work !! I have no clue why

    [WebInvoke(Method = "GET",
    			RequestFormat = WebMessageFormat.Json,
    			ResponseFormat = WebMessageFormat.Json,
    			UriTemplate = "/AddNumbers3/{number}")]

    But this one works:

    [WebGet(
    			ResponseFormat = WebMessageFormat.Json,
    			RequestFormat = WebMessageFormat.Json,
    			UriTemplate = "/AddNumbers3/{number}")]

    do you have any explanation ??

    Best


    Waleed Seada

    Saturday, December 31, 2016 12:06 PM
  • I am new in this area, so bear with me..

    I built a web-service that is responsible of exposing EF5 entities to the client.

    That is bad news,  and you never expose the EF entities to the client. What you expose to the client are DTO(s) and NOT the EF entities.

    https://en.wikipedia.org/wiki/Data_transfer_object

    That's why there are EF solutions like the one shown in the link.

    https://entitiestodtos.codeplex.com/

    The DTO(s) generated  by entity-2-dto are serializable data contracts.

    Again, one doesn't bring the EF entities past the service.

    http://www.mindscapehq.com/documentation/lightspeed/Building-Distributed-Applications-/Building-WCF-Services-using-Data-Transfer-Objects

    Saturday, December 31, 2016 6:31 PM
  • Hello DA24x,

    I believe you missed the title.

    Thanks


    Waleed Seada

    Saturday, December 31, 2016 8:41 PM
  • Hello DA24x,

    I believe you missed the title.

    Thanks


    Waleed Seada

    I built a web-service that is responsible of exposing EF5 entities to the client.

    It concerns your education on what to do and what not to do that you seem to not understand and missed.

    https://msdn.microsoft.com/en-us/library/ee658090.aspx?f=255&MSPPError=-2147217396

    <copied>

    Within the service layer, you define and implement the service interface and the data contracts (or message types). One of the more important concepts to keep in mind is that a service should never expose details of the internal processes or the business entities used within the application. In particular, you should ensure that your business layer entities do not unduly influence your data contracts. The service layer should provide translator components that translate data formats between the business layer entities and the data contracts.

    <end>

    That also concerns those EF entities too, that you don't expose to the client that is consuming the service. What is exposed to the client is the DTO and NOT the EF entity. I suggest that you don't drink the MS Kool Aid that is showing you some cookie-cutter code that is exposing the EF entity to the client in a SOA type solution.

    Saturday, December 31, 2016 9:40 PM
  • Thanks Edward,

    I found your rely very useful in calling the method, actually the thing made the difference is the attribute on the method itself.

    This definition doesn't work !! I have no clue why

    [WebInvoke(Method = "GET",
    			RequestFormat = WebMessageFormat.Json,
    			ResponseFormat = WebMessageFormat.Json,
    			UriTemplate = "/AddNumbers3/{number}")]

    But this one works:

    [WebGet(
    			ResponseFormat = WebMessageFormat.Json,
    			RequestFormat = WebMessageFormat.Json,
    			UriTemplate = "/AddNumbers3/{number}")]

    do you have any explanation ??

    Best


    Waleed Seada


    Hi Waleed,

    As Service Operation Requirements, you need to use WebGet for get method.

    The method must be annotated with the [WebGet] or [WebInvoke] attribute.

    • [WebGet] enables the method to be invoked by using a GET request.
    • [WebInvoke(Method = "POST")] enables the method to be invoked by using a POST request. Other WebInvokeAttribute methods are not supported.

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, January 2, 2017 5:15 AM