Saturday, May 21, 2016

Visual C# Technical Guru - April 2016

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

Post in WikiNinjas Official Blog,
image
Visual C# Technical Guru - April 2016
Happy Coding.

Regards,
Jaliya

Monday, May 16, 2016

AngularJS : Passing Object as a State Parameter

In this post let’s see how we can pass Object to another state as a state parameter.

When defining the state, you need to specify that the state is expecting a state parameter. Here it's named as “myobjectparameter”.
.state("app.somestate.someotherstate", {
    url: "/someotherstate/:myobjectparameter",
    templateUrl: "sometemplate.tpl.html",
    controller: "SomeTemlateController",
})
And when you are navigating to “app.somestate.someotherstate” and specifying the value for “myobjectparameter”, you need to convert your object to a JSON string.
$state.go("app.somestate.someotherstate", {
  "myobjectparameter": JSON.stringify({
      "property1": "Property Value1",
      "property2": "Property Value2"
  })
});
And from “app.somestate.someotherstate” state, you need to  parse "$stateParams.myobjectparameter" which was passed as a string to a JSON object.
var myObjectParameter = JSON.parse($stateParams.myobjectparameter);
Happy Coding.

Regards,
Jaliya

Monday, May 9, 2016

ASP.NET 5 (ASP.NET Core 1.0) Middleware : Use, Map, MapWhen and Run

Middleware plays a major role in ASP.NET 5 (ASP.NET Core 1.0) application pipeline. Even the roles of both modules and handlers have been taken over by Middleware and it is important to learn the various ways of configuring Middleware in a ASP.NET 5 (ASP.NET Core 1.0) application.

On ASP.NET 5 (ASP.NET Core 1.0), when configuring Middleware in the application pipeline on IApplicationBuilder (uses to build the application request pipeline),  we have fours options.
  • Use
  • Map
  • MapWhen
  • Run
In this post, let’s see in detail the differences between each of these Middleware configuration options and their usage.

Use


Basically Use adds a Middleware to the application pipeline and it has the capability either to pass the request to next delegate or to short circuit the request pipeline.
app.Use(async (context, next) =>
{
    await context.Response.WriteAsync("Hello World! \n");
    await next.Invoke();
});
So here by calling next.Invoke(), we will be passing the request to the next delegate (basically this is the next Middleware which is defined in the code, the Middleware will get added to the application pipeline in the order they are defined in the code). If we remove calling next.Invoke() we are short circuiting the application pipeline.

Map


We can use Map method to specify if the request path starts with a specific path, add a specific Middleware.
app.Map("/contactus", HandleContactUs);
private static void HandleContactUs(IApplicationBuilder app)
{
   app.Run(async context =>
   {
       await context.Response.WriteAsync("Contact Us");
   });
}
So here if we navigate to “http://localhost:xxxx/contactus”, the request will get branched to HandleContactUs delegate and what ever the other Middlewares defined below app.Map() won’t get added to the pipleline.

MapWhen


Here the concept is same as Map except we have more control over the condition (based on the URL, request headers, query strings, etc) which we checks to add the Middleware to the pipeline.
app.MapWhen(context =>
{
    return context.Request.Query.ContainsKey("pid");
}, HandleProductDetail);

Here if the request URL contains a “pid”, then the request will be branched off to HandleProductDetail delegate.
private static void HandleProductDetail(IApplicationBuilder app)
{
    app.Run(async context =>
    {
        await context.Response.WriteAsync("Product Details");
    });
}

Run


Run will add a Middleware and it will be the end of the request pipeline. It will not call the next delegate.
app.Run(async context =>
{
    await context.Response.WriteAsync("Main Content");

});
I am uploading the sample code to OneDrive.

Happy Coding.

Regards,
Jaliya

Monday, May 2, 2016

AngularJS : Download Files by Sending a HTTP Request to Web API

As you might already know you can’t directly use AngularJS/JQuery/JavaScript to download a file by sending a HTTP request. That’s because usually the file downloads are triggered when a user click on a link and link’s href is targeted to the file location.

But imagine that your server expects a HTTP request (of course an authenticated request), and he will be serving you the file as a octet-stream or as an Attachment in the response.

To understand the scenario properly, consider the following Web API action.
[HttpGet]
[Route("values/download")]
public HttpResponseMessage Download(string name)
{
    try
    {
        string fileName = string.Empty;
        if (name.Equals("pdf", StringComparison.InvariantCultureIgnoreCase))
        {
            fileName = "SamplePdf.pdf";
        }
        else if (name.Equals("zip", StringComparison.InvariantCultureIgnoreCase))
        {
            fileName = "SampleZip.zip";
        }
 
        if (!string.IsNullOrEmpty(fileName))
        {
            string filePath = HttpContext.Current.Server.MapPath("~/App_Data/") + fileName;
 
            using (MemoryStream ms = new MemoryStream())
            {
                using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                {
                    byte[] bytes = new byte[file.Length];
                    file.Read(bytes, 0, (int)file.Length);
                    ms.Write(bytes, 0, (int)file.Length);
 
                    HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
                    httpResponseMessage.Content = new ByteArrayContent(bytes.ToArray());
                    httpResponseMessage.Content.Headers.Add("x-filename", fileName);
                    httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                    httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
                    httpResponseMessage.Content.Headers.ContentDisposition.FileName = fileName;
                    httpResponseMessage.StatusCode = HttpStatusCode.OK;
                    return httpResponseMessage;
                }
            }
        }
        return this.Request.CreateResponse(HttpStatusCode.NotFound, "File not found.");
    }
    catch (Exception ex)
    {
        return this.Request.CreateResponse(HttpStatusCode.InternalServerError, ex);
    }
}
The action is expecting a URL parameter and based on the parameter it will be serving you either a pdf file or a zip file. Now to download a file by calling this endpoint, I believe what the most people would think is, following would work (including me).
$scope.downloadFile = function (name) {
   $http({
       method: 'GET',
       url: 'api/values/download',
       params: { name: name },
   }).success(function (data, status, headers) {
      
   }).error(function (data) {
       
   });
};
Now if you call the downloadFile method to send the HTTP request from client side (for instance on the ng-click event of a anchor tag), it will not download the file. The reason is because JavaScript can’t access file system to save the files.

So here is a workaround (in Stack Overflow by answered by Scott).
$scope.downloadFile = function (name) {
    $http({
        method: 'GET',
        url: 'api/values/download',
        params: { name: name },
        responseType: 'arraybuffer'
    }).success(function (data, status, headers) {
        headers = headers();
 
        var filename = headers['x-filename'];
        var contentType = headers['content-type'];
 
        var linkElement = document.createElement('a');
        try {
            var blob = new Blob([data], { type: contentType });
            var url = window.URL.createObjectURL(blob);
 
            linkElement.setAttribute('href', url);
            linkElement.setAttribute("download", filename);
 
            var clickEvent = new MouseEvent("click", {
                "view": window,
                "bubbles": true,
                "cancelable": false
            });
            linkElement.dispatchEvent(clickEvent);
        } catch (ex) {
            console.log(ex);
        }
    }).error(function (data) {
        console.log(data);
    });
};
So this is the output.
image
Download
image
Download
I have uploaded the sample to my OneDrive, so you can download and play around.

Happy Coding.

Regards,
Jaliya