Category Archives: Web API

ASP.NET Web API and Streaming Video Content

Below post explains how to stream video content through ASP.Net Web API’s, below is the code for Video Controller which inherits from API Controller. API show both GET and POST approaches.

Main thing to concentrate in the code is usage of Push Stream Content. PushStreamContent enables option to send data in small stream packets which then could be used on client side to stream videos, download large files etc.

    /// API Controller for streaming video files.
    public class VideoController : ApiController
    {
        private const string videoFilePath = "~/Movies/";

        /// Gets the live video.
        [HttpGet]
        [Route("api/video/live")]
        public IHttpActionResult GetLiveVideo(string videoFileId, string fileName)
        {
            string filePath = Path.Combine(HttpContext.Current.Server.MapPath(videoFilePath), fileName);
            return new VideoFileActionResult(filePath);
        }

        /// Gets the live video using post.
        /// The request.
        [HttpPost]
        [Route("api/video/live")]
        public IHttpActionResult GetLiveVideoPost(VideoFileDownloadRequest request)
        {
            string filePath = Path.Combine(HttpContext.Current.Server.MapPath(videoFilePath), request.FileName);
            return new VideoFileActionResult(filePath);
        }
    }

    /// Action Result for Returning Stream
    public class VideoFileActionResult : IHttpActionResult
    {
        private const long BufferLength = 65536;
        public VideoFileActionResult(string videoFilePath)
        {
            this.Filepath = videoFilePath;
        }

        public string Filepath { get; private set; }

        public Task ExecuteAsync(CancellationToken cancellationToken)
        {
            HttpResponseMessage response = new HttpResponseMessage();
            FileInfo fileInfo = new FileInfo(this.Filepath);
            long totalLength = fileInfo.Length;
            response.Content = new PushStreamContent((outputStream, httpContent, transportContext) =>
                {
                    OnStreamConnected(outputStream, httpContent, transportContext);
                });

            response.Content.Headers.ContentLength = totalLength;
            return Task.FromResult(response);
        }

        private async void OnStreamConnected(Stream outputStream, HttpContent content, TransportContext context)
        {
            try
            {
                var buffer = new byte[BufferLength];

                using (var nypdVideo = File.Open(this.Filepath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var videoLength = (int)nypdVideo.Length;
                    var videoBytesRead = 1;

                    while (videoLength > 0 && videoBytesRead > 0)
                    {
                        videoBytesRead = nypdVideo.Read(buffer, 0, Math.Min(videoLength, buffer.Length));
                        await outputStream.WriteAsync(buffer, 0, videoBytesRead);
                        videoLength -= videoBytesRead;
                    }
                }
            }
            catch (HttpException ex)
            {
                return;
            }
            finally
            {
                // Close output stream as we are done
                outputStream.Close();
            }
        }
    }

 

On the client side you can view the video file using below code snippet

<video width="480" height="320" controls="controls" autoplay="autoplay">
        <source src="api/video/live?videoFileId=1001&fileName=sampleVideo.mp4" type="video/mp4">
    </video>

HTTP Methods PUT, POST, Idempotent, Safe…

  • Idempotent – An idempotent HTTP method is a HTTP method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. Again, this only applies to the result, not the resource itself. This still can be manipulated (like an update-timestamp, provided this information is not shared in the (current) resource representation. Consider the following examples:
    a = 4;
    a++;
    The first example is idempotent: no matter how many times we execute this statement, a will always be 4. The second example is not idempotent. Executing this 10 times will result in a different outcome as when running 5 times. Since both examples are changing the value of a, both are non-safe methods.
  • Safe Methods – Safe methods are HTTP methods that do not modify resources. For instance, using GET or HEAD on a resource URL, should NEVER change the resource. However, this is not completely true. It means: it won’t change the resource representation. It is still possible, that safe methods do change things on a server or resource, but this should not reflect in a different representation.
  • PUT and POST
    • Post – The POST verb is most-often utilized to **create** new resources. In particular, it’s used to create subordinate resources. That is, subordinate to some other (e.g. parent) resource. In other words, when creating a new resource, POST to the parent and the service takes care of associating the new resource with the parent, assigning an ID (new resource URI), etc. On successful creation, return HTTP status 201, returning a Location header with a link to the newly-created resource with the 201 HTTP status. POST is neither safe nor idempotent. It is therefore recommended for non-idempotent resource requests. Making two identical POST requests will most-likely result in two resources containing the same information.
      Examples:
      POST http://www.example.com/customers
      POST http://www.example.com/customers/12345/orders
    • Put – PUT is most-often utilized for **update** capabilities, PUT-ing to a known resource URI with the request body containing the newly updated representation of the original resource.However, PUT can also be used to create a resource in the case where the resource ID is chosen by the client instead of by the server. In other words, if the PUT is to a URI that contains the value of a non-existent resource ID. Again, the request body contains a resource representation. Many feel this is convoluted and confusing. Consequently, this method of creation should be used sparingly, if at all.Alternatively, use POST to create new resources and provide the client-defined ID in the body representation—presumably to a URI that doesn’t include the ID of the resource (see POST below).On successful update, return 200 (or 204 if not returning any content in the body) from a PUT. If using PUT for create, return HTTP status 201 on successful creation. A body in the response is optional—providing one consumes more bandwidth. It is not necessary to return a link via a Location header in the creation case since the client already set the resource ID.PUT is not a safe operation, in that it modifies (or creates) state on the server, but it is idempotent. In other words, if you create or update a resource using PUT and then make that same call again, the resource is still there and still has the same state as it did with the first call.If, for instance, calling PUT on a resource increments a counter within the resource, the call is no longer idempotent. Sometimes that happens and it may be enough to document that the call is not idempotent. However, it’s recommended to keep PUT requests idempotent. It is strongly recommended to use POST for non-idempotent requests.Examples:
      PUT http://www.example.com/customers/12345
      PUT http://www.example.com/customers/12345/orders/98765
      PUT http://www.example.com/buckets/secret_stuff
  • PATCH – PATCH is used for **modify** capabilities. The PATCH request only needs to contain the changes to the resource, not the complete resource. This resembles PUT, but the body contains a set of instructions describing how a resource currently residing on the server should be modified to produce a new version. This means that the PATCH body should not just be a modified part of the resource, but in some kind of patch language like JSON Patch or XML Patch. PATCH is neither safe nor idempotent. However, a PATCH request can be issued in such a way as to be idempotent, which also helps prevent bad outcomes from collisions between two PATCH requests on the same resource in a similar time frame. Collisions from multiple PATCH requests may be more dangerous than PUT collisions because some patch formats need to operate from a known base-point or else they will corrupt the resource. Clients using this kind of patch application should use a conditional request such that the request will fail if the resource has been updated since the client last accessed the resource. For example, the client can use a strong ETag in an If-Match header on the PATCH request. Examples:
    PATCH http://www.example.com/customers/12345
    PATCH http://www.example.com/customers/12345/orders/98765
    PATCH http://www.example.com/buckets/secret_stuff
  • DELETE is pretty easy to understand. It is used to **delete** a resource identified by a URI. On successful deletion, return HTTP status 200 (OK) along with a response body, perhaps the representation of the deleted item (often demands too much bandwidth), or a wrapped response (see Return Values below). Either that or return HTTP status 204 (NO CONTENT) with no response body. In other words, a 204 status with no body. HTTP-spec-wise, DELETE operations are idempotent. If you DELETE a resource, it’s removed. Repeatedly calling DELETE on that resource ends up the same: the resource is gone.  There is a caveat about DELETE idempotence, however. Calling DELETE on a resource a second time will often return a 404 (NOT FOUND) since it was already removed and therefore is no longer findable. This, by some opinions, makes DELETE operations no longer idempotent, however, the end-state of the resource is the same. Returning a 404 is acceptable and communicates accurately the status of the call.
    Examples: DELETE http://www.example.com/customers/12345 DELETE http://www.example.com/customers/12345/orders DELETE http://www.example.com/bucket/sample
  • GET – HTTP GET method is used to **read** (or retrieve) a representation of a resource. In the “happy” (or non-error) path, GET returns a representation in XML or JSON and an HTTP response code of 200 (OK). In an error case, it most often returns a 404 (NOT FOUND) or 400 (BAD REQUEST). According to the design of the HTTP specification, GET (along with HEAD) requests are used only to read data and not change it. Therefore, when used this way, they are considered safe. That is, they can be called without risk of data modification or corruption—calling it once has the same effect as calling it 10 times, or none at all. Additionally, GET (and HEAD) is idempotent, which means that making multiple identical requests ends up having the same result as a single request. Do not expose unsafe operations via GET—it should never modify any resources on the server.
    Examples: GET http://www.example.com/customers/12345 GET http://www.example.com/customers/12345/orders GET http://www.example.com/buckets/sample
  • HEAD – The HEAD method is functionally similar to GET, except that the server replies with a response line and headers, but no entity-body, the server MUST NOT return a message-body in the response. Typically HEAD will be used for getting metadata information for the resource. The meta information contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request. This method can be used for obtaining meta information about the entity implied by the request without transferring the entity-body itself. This method is often used for testing hypertext links for validity, accessibility, and recent modification. In cases where the content of a resource is not particularly important, but the existence of the resource is, HEAD is perfect. We can do everything just like a GET and check the response code, without the weight of the response body.
  • CONNECT Method – The CONNECT method is used by the client to establish a network connection to a web server over HTTP.
  • OPTIONS Method – The OPTIONS method is used by the client to find out the HTTP methods and other options supported by a web server. The client can specify a URL for the OPTIONS method, or an asterisk (*) to refer to the entire server.
HTTP Method Idempotent Safe
Options YES YES
GET YES YES
Head YES YES
PUT YES NO
POST NO NO
DELETE YES NO
PATCH NO NO

Tech Interview App – Android Store – Try it and let me know Feedback…

Try my Android Store App – App Contains Categorized Q&A for tech categories focus on OSS stack (Angular, Node) for building hybrid apps as well as  MS Stack (.NET, ASP.NET, MVC, Web API…). Provides Question Count Statistics as well categorized question count break down. Questions and Answers periodically without app upgrade.

Tech Interview App

Android Store Listing

App is built using HTML 5, Angular JS and Web API in the back Ground.

Plan is to add Questions Weekly to the Respository and make more enhancements :).

1 2 3 4 5 6 7

Send Feedback…..

ASP.NET Web API Request Batching and Service Call aggregation

What is HTTP Batching?

  • Group multiple HTTP requests into a single HTTP call. It defines a way to represent a complete HTTP request (headers and all) as a section in a single HTTP POST body.
  • Batch Http API calls together to reduce the number of HTTP connections client has to make. HTTP connection that client makes results in a certain amount of overhead,
  • Batch requests allow grouping multiple operations, into a single HTTP request payload
  • Minimize  number of messages that are passed between the client and the server and reduce network traffic, provides a smoother, promotes less chattiness.
  • Avoid Redundant HTTP API calls.
  • ASP.NET Web API provide OOB support for http batching through HttpBatchHandler. To enable batching Web API provides custom message handlers DefaultHttpBatchHandler which you can register per-route to handle the batch requests.
  • The key thing of Http batching is the Content-Type:multipart/mixed; boundary=12345665431 which is basically informing the reciever that the content of the POST request is made up of multiple parts seperated by the boundary indicator, Boundary Indicator can be any unique identifier.

Registering HTTP batch endpoint

You can use MapHttpBatchRoute, which is an HttpRouteCollection extension method, to create a batch endpoint. For example, the following will create a batch endpoint at “api/batch” in the App_Start WebApiConfig.cs file

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpBatchRoute(
routeName: “WebApiBatch”,
routeTemplate: “api/batch”,
batchHandler: new DefaultHttpBatchHandler(GlobalConfiguration.DefaultServer));

config.Routes.MapHttpRoute(
name: “DefaultApi”,
routeTemplate: “api/{controller}/{id}”,
defaults: new { id = RouteParameter.Optional }
);
}
}

Now, on the client side you can use the angular angular-http-batcher module to make batch requests. This module  hooks into the $http service and creates batch requests to batchable endpoints. Therefore, once the module is included as a dependency in your application it will automatically batch all batchable http request.

Set up the angular http batcher dependency to your angular module which can be app, controller or a service, preferably common service.

var batchedServiceClientModule = angular.module(‘batchedServiceClientModule ‘, [‘jcs.angular-http-batch’]);
batchedServiceClientModule.config([
‘httpbatchServiceClientProvider’,
function (httpbatchServiceClientProvider) {
httpbatchServiceClientProvider.setAllowedBatchEndpoint(
https://localhost:8080&#8217;,
https://localhost:8080/api/batch&#8217;);
}
]);

batchedServiceClientModule.factory(batchedServiceClient, [
‘$scope’,
‘$http’,
function ($scope, $http) {
 $http.get(https://localhost:8080/books&#8217;).then(function (data) {
console.log(‘success Books – ‘ + data.data);
}, function (err) {
console.log(‘error Books – ‘ + err);
});

$http.get(https://localhost:8080/books/1′).then(function (data) {
console.log(‘success books/1 – ‘ + data.data);
}, function (err) {
console.log(‘error books/1 – ‘ + err);
});

$http.put(https://localhost:8080/books&#8217;, {
Name: ‘Harry Potter’,
Autor: ‘J K Rowling’
}).then(function (data) {
console.log(‘success Post Books – ‘ + data.data);
}, function (err) {
console.log(‘error Post Books – ‘ + angular.fromJson(err));
});
}]);

Register ‘batchedServiceClientModule; with your mail ng-App

REST Principles

REST is a set of principles that define how Web standards, such as HTTP and URIs, are supposed to be used.

There are five important REST principle as mentioned below –

  • Addressable Resources – Everything is a resource, each resource should be identified by a URI (unique identifier)
  • Simple and Uniform Interfaces – REST is based on HTTP protocol so use HTTP GET, POST, PUT and DELETE method to perform actions. This make REST simple and uniform.
  • Representation Oriented- Communication are done by representation. Representation of resources are exchanged. GET is used to return a representation and PUT, POST passes representation to the server so that underlying resources may change. Representation may be in many formats like XML, JSON etc.
  • Communicate Stateless – An application may has state but there is no client session data stored on the server. Any session specific data should be held and maintained by the client and transferred to the server with each request as needed.
  • Cacheable – Clients should be able to cache the responses for further use.

Web API & WCF – Comparison

WCF Web API
Back End Services Front End UI Services
SOAP WS* Media Types: JSON, XML, form-URL-encoded, custom
Transports: HTTP, TCP, UDP, Queues, Web Sockets, custom Transports: Http Only
Message Patterns: Request-Reply, One-Way, duplex Message Patterns: Request-Reply Only
Use WCF Web HTTP to add HTTP end points to existing WCF services Use SignalR for Asynchronous Signaling (polling, long-polling, Web Sockets
Use WCF data Services for full OData Support Supports OData