Showing posts with label ODataController. Show all posts
Showing posts with label ODataController. Show all posts

Saturday, July 11, 2020

Querying Entities' Properties in Web API OData RESTful with ODataController

In this article we enable the Querying of an Entity's Property in an Web API OData RESTful service with ODataController.
Our task here is to perform OData protocol queries in order to get the value of some Entity's property, the following query for example :
http://localhost:6954/Odata/Notes(10)/Body/$value


When developing an ODataController to create an OData Web API, having configurated the application properly, as in the previous tutorial, you get automatically support for the most common OData protocol's queries. You can then query the OData Web API using $metadata, $value, $select, $top, $skip, $filter and even $expand , to get the JSON response:
http://localhost:6954/OData/$metadata#Notes :

              /Odata/Notes?$filter=From eq 'Fry'





http://localhost:6954/OData/Notes?$skip=2&$top=10

http://localhost:6954/OData/Notes?$select=Body

There are some conventions to follow when developing an ODataController:

1) the controller's name must be the entity name, the root of the resource path:

      /Notes(10)      implies that the Web API will look for a controller named NotesController (case sensitive)

2) the Action name for fetching an Entity's property will be set according to the Entity type and the Property name, as follows:

  /Notes(10)/Body       
      means that the Web API will look for an Action method named GetBodyFromNote()

All this conventions can be found in the Microsoft Asp.Net official site.
Let's say we have an Entity named "Note" with some property called "Body" : we want to call the OData HTTP service with this URI:
      http://localhost:6954/Odata/Notes(10)/Body/

So, according to the OData protocol specification, we need an Action method named GetBodyFromNote(), marked with the attribute "[EnableQuery]" , which returns the required property from the Entity:


(COPY-PASTE THIS CODE) : 


 [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All)]
        public string GetBodyFromNote([FromODataUri]int key)
        {
            IEnumerable<Note> data = Repository.GetAll();
            var note = data.Where(n => n.ID == key) .SingleOrDefault();
            return note.Body ;
        }



Build & run the application, and type the URI to fetch the required property in JSON format:

http://localhost:6954/Odata/Notes(10)/Body/
Also, we can request ONLY the $value of the property:

http://localhost:6954/Odata/Notes(10)/Body/$value
That's all
In this post we've seen how we perform Querying Entities' Properties in Web API OData RESTful with ODataController. 

Enjoy programming.....
    By Carmel Shvartzman
כתב: כרמל שוורצמן

Tuesday, January 5, 2016

How to send an HTTP DELETE Request to a RESTful ODataController Web API Service using Postman

In this post we'll learn Step by step how to send an HTTP DELETE Request to a RESTful ODataController Web API Service using Postman
We'll use Postman to test a RESTful OData Web API application, sending an HTTP DELETE request. We'll use a working OData Web API ODataController  built in a previous tutorial,   and we'll delete a record using  Postman :

How to send an HTTP DELETE Request to a RESTful ODataController Web API Service using Postman




In order to get Postman installed ,  go to the Chrome Tools >> Extensions   ,  search for "Postman" and install the App .

HTTP DELETE Request to a RESTful ODataController Web API with Postman



Now let's see how to call the OData Web API to delete an item :   in order to setup  the ODataController , there will be an ODataModelBuilder at the "Register" method called from the Global.asax file : it's important that the EntitySet name MUST be the same name of the Controller   , therefore we'll look for a "NotesController"  at the application :

Because there is a route prefix set ( "ODataV4" ) ,  we'll also append it to the URL : 



At the ODataController ,  we check for the "Delete" action method , since we're sending an HTTP DELETE request :


Why are we checking this ? Because we want to know what is ODataController method expecting : in our case , it expects a URI which must include an integer "key" ID  ( "[FromODataURI]" ) .  

The Port of the application can be extracted from the Web tab at the application properties:


Put all of this together , and you have the URI for the DELETE request : 

"http://localhost:21435/ODataV4/Notes(6)" :


Important : OData is case sensitive : therefore , if you type "notes" instead of "Notes" , you will not obtain any data.

After setting the URI and the DELETE method , write the "Content-Type" header :




Send the request :


The request details can be seen this way :


In the meantime , the ODataController at the RESTful WebAPI have handled the request with the ID in the ODataURI : 


The action method renders a response with code 410 "GONE" , to express that the record has been deleted , and Postman exposes it : 






That's all... 
In this tutorial we've learned how to send an HTTP DELETE Request to a RESTful  ODataController Web API Service using Postman.
Happy programming.....
      By Carmel Shvartzman
כתב: כרמל שוורצמן






Monday, April 20, 2015

Error 8 'System.Web.Http.HttpConfiguration' does not contain a definition for 'MapODataServiceRoute'


In this article we fix the Error 8 'System.Web.Http.HttpConfiguration' does not contain a definition for 'MapODataServiceRoute', while adding a route to an ASP.NET application containing an OData Web API.



 System.Web.Http.HttpConfiguration MapODataServiceRoute


The error is originated after the Microsoft decision to create a new assembly to support the v4.0 version of the OData protocol, but keeping the OLD assembly which supported the version 3.0. The resultant side by side scenario where applications can reference to v3.0 and v4.0 simultaneously, can be the source of errors as the one we're fixing here. 
May be one of the more important changes here is , the "QueryableAttribute"  has now been renamed "EnableQueryAttribute". You can explore the assemblies differences in this MSDN article.

The new OData v4.0 assembly is "System.Web.OData" instead of the OLD "System.Web.Http.OData" , and the new package is called "Microsoft.AspNet.OData".

So the error appears after you configure the OData Endpoint at the WebApiConfig  Register()  :

Error  8 'System.Web.Http.HttpConfiguration' does not contain a definition for 'MapODataServiceRoute'

public static void Register(HttpConfiguration config)
        {
            
            ODataModelBuilder builder = new ODataConventionModelBuilder();
            builder.EntitySet<Note>("Notes");
            config.MapODataServiceRoute(
                routeName: "ODataRoute",
                routePrefix: "OData",
                model: builder.GetEdmModel());          

        }

The "routePrefix" sets the name of the Service Endpoint.

When you compile, you receive the following error message:



Because the Extension Methods in the new OData v4.0 assembly were moved to "System.Web.OData.Extensions", and the method "MapODataRoute" has been renamed to "MapODataServiceRoute", we must reference to that extensions namespace.
Therefore go to the usings section up in your C# file, and add the Extensions namespace to allow the use of the extension method that we are supposed to use:



using System.Web.Http.OData;
using System.Web.OData.Builder;
using System.Web.Http;
using System.Web.OData.Extensions;



That's all!!!!


By Carmel Shvartzman

עריכה: כרמל שוורצמן

Sunday, March 1, 2015

How to send an HTTP PUT Request to a RESTful ODataController Web API Service using Postman

In this post we'll learn Step by step how to send an HTTP PUT Request to a RESTful ODataController Web API Service using Postman
We'll make use of the Postman tool to test a RESTful OData Web API , sending an HTTP PUT request. That  working OData Web API with ODataController , was built in a previous tutorial. After we update the  record , we check it sending an HTTP GET request :

how to send an HTTP PATCH Request to a RESTful  ODataController Web API Service using Postman



Important : An HTTP PUT request is expected to provide an object to be UPDATED , but the object MUST include all of the object's properties , not just the updated ones . If you want to send a PARTIAL object , you must use the HTTP PATCH verb instead . We explain it in this HTTP PATCH tutorial .

If you do not have Postman installed , just go to the Tools >> Extensions on the Chrome browser , make a search for "Postman" and install the App .

HTTP PUT Request to a RESTful ODataController Web API Service using Postman



Now let's check out how to call the OData Web API : in MVC , to setup  the ODataController there have to be an ODataModelBuilder at the "Register" method called from the Global.asax :  the EntitySet name MUST be called after the name of the Controller ( "Notes" in our case ) , so we'll search for a "NotesController" at the application :

Notice there is a route prefix declared ( "ODataV4" ) , which must be appended to the URI . 



Found the ODataController , now we look for the "Put" method , because we're sending an HTTP PUT request :


Why to check this ? Because we want to know which parameters is expecting the ODataController  :   it expects :
1) a "key" which is the ID of the item : must be in the URI
2) a "Note" object , which must be included in the request's body ( "[FromBody]" ) . 

How do we create a Note object ? Take a look at the declaration inside the Model :



Now we know the Note's properties and its constraints.

Alternatively , you could ask for the METADATA info , but that way you won't know the Data Annotations constraints declared at the Model :

http://localhost:21435/ODataV4/$metadata

The Port  can be obtained from the Web tab at the application properties:


Merge all of this together , and you will have built the URI for the PUT request : "http://localhost:21435/ODataV4/Notes(5)" :

Set the URI , select the PUT method , set the "Content-Type" header , and write the JSON object according to the Note's declaration:


Important : because the OData protocol is case sensitive , if you type "notes" instead of "Notes" , you will not reach the data.


Send the request : as you see , the Controller has bound the JSON object to a local Note variable :




The details of the HTTP PUT request can be seen in Postman as follows : 


 The update was made , and an HTTP GET request can verify that :



That's all... 
In this tutorial we've learned how to send an HTTP PUT Request to a RESTful  ODataController Web API Service using Postman.
Happy programming.....
      By Carmel Shvartzman
כתב: כרמל שוורצמן







Monday, February 23, 2015

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman

In this article we'll learn Step by step how to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman
We'll use Postman to test a RESTful OData Web API application, sending an HTTP POST request. We'll start with a working OData Web API built on an ODataController , which we built in a previous tutorial,   and we'll create an entry using  Postman . After we create a new record , we check it sending an HTTP GET request :



HTTP POST Request to a RESTful OData Web API Service using Postman
In order to get Postman , just go to the Tools >> Extensions on Chrome , do a search for "Postman" and install the App .

HTTP POST Request to a RESTful ODataController Web API Service using Postman



Open Postman and select "POST" from the list :

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman  1

Now let's learn how to call the OData Web API : in MVC , in order to setup  the ODataController , there must be an ODataModelBuilder registered at the "Register" method called from the Global.asax file : as you see in the following snapshot , the EntitySet name MUST be the name of the Controller ( "Notes" in our case ) , so we'll look for a "NotesController" ODataController at the application :

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman   2
Also , there is a route prefix declared ( "ODataV4" ) , so we'll append it to the URI . 


How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman   3

Found the ODataController , now we check for the "Post" action method , because we're sending an HTTP POST request :


How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman     4
Why are we checking this ? Because we want to know which kind of object is the ODataController method expecting : in our case , it expects a "Note" object , which must be included in the request's body ( "[FromBody]" ) . How to create a Note object ? Look at the declaration inside the Model :


How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman   5

Now we know that a Note must include all of those properties.
You could send an OData request asking for the METADATA information to construct the Note object , but that way you won't know the constraints declared with Data Annotations at the Model :

http://localhost:21435/ODataV4/$metadata

The Port of the application can be extracted from the Web tab at the application properties:

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman   6

Put all of this together , and you have the URI for the POST request : "http://localhost:21435/ODataV4/Notes" :

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman   7

Important : OData protocol is case sensitive : therefore , if you type "notes" instead of "Notes" , you will not reach the controller.

After setting the URI and the POST method , set the "Content-Type" header :

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman  8

Next , build the JSON object to be sent inside the request's body , according to the Data Annotations :

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman   9

Send the request :

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman  10

Postman is waiting for the response :

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman   11

In the meantime , the ODataController at the RESTful WebAPI have gotten the JSON object and bound it to a local variable : 

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman    12
The action method renders a response with code 201 CREATED , and Postman exposes it : 


How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman   13

Finally , if you want to , send a HTTP GET request to check for the new record added to the database :

How to send an HTTP POST Request to a RESTful ODataController Web API Service using Postman   14




That's all... 
In this tutorial we've learned how to send an HTTP POST Request to a RESTful  ODataController Web API Service using Postman.
Happy programming.....
      By Carmel Shvartzman
כתב: כרמל שוורצמן









Friday, September 19, 2014

Create an Ajax Web Client for OData Web API RESTful Service - HTTP-DELETE JSON


In this article we'll design a web client for deleting a record by sending an HTTP DELETE call via Ajax to an Web API OData RESTful service implemented using an ODataController. The design will be made applying Twitter Bootstrap.

This post uses an OData Web API  designed in a previous Web API ODataController tutorial. The  Twitter Bootstrap's setup can be learned in this post. Also, the OData protocol for the MVC Web API with ODataControllers can be seen at the Microsoft Asp.Net site

We want to send an Ajax HTTP  DELETE request to the OData HTTP Web API service to delete an item, using this screen :
Ajax Web Client for OData Web API RESTful Service - HTTP-DELETE JSON



First create the MVC application as an empty web site:




Import the style and the script files  (you can learn the Twitter Bootstrap installing instructions here)


Take a look at the Web API ODataController class, to see the Delete( int  ) method that we're using:



The Delete() action method requires an integer ID , returning an  IHttpActionResult object.

Ajax Web Client for OData Web API RESTful Service - HTTP-DELETE JSON



Create a new web client for the OData service:


Add the references to the Twitter Bootstrap:



Then we add a DOM element for selecting the KEY  of the record to delete:

Next, we create all the input tags for showing the record's details:


This is the markup to copy-paste:

   <div class="panel panel-default">            <div class="panel-heading row">                <div class="text-muted col-xs-6">                    <h2>Message Details</h2>                </div>                <div class="text-muted col-xs-3">                    <div class="editor-label">                        ID                    </div>                    <div class="editor-field">                        <input type="number" name="ID" value="3" class="form-control" />                    </div>                </div>
            </div>            <div class="panel-body text-muted">                <div class="row">                    <div class="col-xs-6">                        <div class="editor-label">                            To                        </div>                        <div class="editor-field">                            <input type="text" name="To" class="form-control" />                        </div>                    </div>                    <div class="col-xs-6">                        <div class="editor-label">                            From                        </div>                        <div class="editor-field">                            <input type="text" name="From" class="form-control" />
                        </div>                    </div>                    <div class="col-xs-12">                        <div class="editor-label">                            Heading                        </div>                        <div class="editor-field">                            <input type="text" name="Heading" class="form-control" />
                        </div>                    </div>                    <div class="col-xs-12">                        <div class="editor-label">                            Body
                        </div>                        <div class="editor-field">                            <input type="text" name="Body" class="form-control" />
                        </div>                    </div>                    <div class="center">                        <div class="center">                            <br />                            <div class="row">                                <div class="col-lg-6">                                    <input class="btn btn-sm btn-default" value="See Message Details" />                                </div>                                <div class="col-lg-6">                                    <input class="btn btn-sm btn-default" value="Delete Message" />                                </div>                            </div>                        </div>                        <br />                        <div class="alert alert-success message"></div>                        <div class="alert alert-danger error"></div>                    </div>                </div>            </div>        </div>    </div>  





After the HTML, write the script, opening with the references to the jQuery and the Bootstrap  files:

When the "Details" button is clicked, the web page send an Ajax call containing the key of the item (inside the URI )   :



If the response was an 200 - OK, we show the item; in case of error, we display a message:


This is the code for the script:

  <script src="Scripts/jquery-2.1.1.js"></script>    <script src="Scripts/bootstrap.js"></script>    <script>        $(function () {            $("div.message").css("display", "none");            $("div.error").css("display", "none");
            $("input.btn[value*=Details]").click(function () {
                var id = $("input[name=ID]").val();                $.ajax({                    url: "http://localhost:6954/OData/Notes(" + id + ")",                    type: "GET",                    data: id,                    dataType: "json",                    contentType: "application/json",                    beforeSend: function (data) {                        //alert(id);                    },                    success: function (data) {                        var note = data;                        $("div.error").css("display", "none");                        $("div.message").css("display", "block");                        $("div.message").text("The Message with ID = " + id + " was retrieved successfully!!!");                        $("input[name=To]").val(note.To);                        $("input[name=From]").val(note.From);                        $("input[name=Heading]").val(note.Heading);                        $("input[name=Body]").val(note.Body);                    },                    error: function (msg) {                        var oError = JSON.parse(msg.responseText);                        fnError("Error : " + oError.error.innererror.message, id);                    }                })            });
            function fnError(msg, id) {                $("div.message").css("display", "none");                $("div.error").html("The message with ID = " + id + " does not exist. Try again.");                $("div.error").css("display", "block");            }



The method inside the ODataController renders the required item:



Now, we need an $.ajax() method to DELETE the selected record, using the HTTP DELETE verb:



This is the code for copy-paste in your project:

    $("input.btn[value*=Delete]").on("click", function () {
                var id = $("input.form-control[name*=ID]").val();
                 
                $.ajax({
                    url: "http://localhost:6954/OData/Notes(" + id + ")",
                    type: "DELETE",
                    data: id,
                    contentType: "application/json",
                    dataType: "json",
                    success: function (data) {
                        $("div.error").html(data.responseText); 
                    },
                    error: function (msg) {                                                
                         
                        if (msg.status == "410") {
                            $("div.message").text('The item was successfuly deleted.');
                        }
                    }
                });
            });
        })
    </script>


Here, we send an Ajax HTTP DELETE request to the OData Web API web service. Notice that the response for an OK has been defined as code 410 ("Gone"), that means that the Ajax request receives an ERROR by response, so we handle it in the error callback of the $.ajax() method!!!!!!

Run the application: the User retrieves the item's details, and clicks the second button, deleting the record:





The Ajax request reaches the OData Web API service, which we built in a previous article about   OData v4.0 WebAPI  updating  (HTTP PUT & HTTP PATCH) that can be found here.
This is the Delete() method which handles the HTTP DELETE request at the OData service:



As you see, we just delete the item, sending an "Gone" status message. Remember that "Gone" is the error 410, therefore we handle it at client side at the error callback.

That's all!!!!

In this article we've seen step by step how to create a web client which deletes a record by sending an HTTP DELETE Ajax request to an WebAPI OData RESTful service implemented with an MVC ODataController.
Enjoy OData Web API  !!!!

By Carmel Shvartzman

עריכה: כרמל שוורצמן