C# MVC: HttpContextBase from HttpContext.Current

It's easy by using the HttpContextWrapper

HttpContextBase basecontext = (new HttpContextWrapper(HttpContext.Current));
Happy coding!

How to upload a file in an ASP.Net MVC page

For this example, I’m using a controller named “HomeController”, with the view “Index”. When you click the “Submit” button on the view, it will be submitted to the “Save” method of HomeController.

Index.cshtml

@using(Html.BeginForm("Save", "Home", FormMethod.Post, 
               new {enctype = "multipart/form-data"}))
{
    <table>
        <tr>
            <td>File:</td>
            <td>
                <input type="file" name="UploadedFile" />
            </td>
        </tr>
        <tr>
            <td colspan="2">
                <input type="submit" name="Submit" value="Submit"/>
            </td>
        </tr>
    </table>
}

Notice the two additional parameters for BeginForm

FormMethod.Post, new {enctype = "multipart/form-data"}

You need those to have the file included in the HTTP Post action to the Save method on the controller. Other than that, you just need a file input control, with a unique name attribute set.

HomeController

using System;
using System.Web;
using System.Web.Mvc;

namespace FileUpload.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Save(FormCollection formCollection)
        {
            if(Request != null)
            {
                HttpPostedFileBase file = Request.Files["UploadedFile"];

                if((file != null) && (file.ContentLength > 0) && 
                   !string.IsNullOrEmpty(file.FileName))
                {
                    string fileName = file.FileName;
                    string fileContentType = file.ContentType;
                    byte[] fileBytes = new byte[file.ContentLength];
                    file.InputStream.Read(fileBytes, 0, 
                                       Convert.ToInt32(file.ContentLength));

                    string pth = Path.GetFileName(fileName);
                    // change the folder
                    file.SaveAs(Server.MapPath("~/Uploads") + "/" + pth);
                }
            }

            return View("Index");
        }
    }
}

The Request object is a base object for handling HTTP requests. Since we set the FormMethod and enctype in the view, we have access to the file that was submitted on the page.

If the Request object isn’t null, we can check for the file by getting the HttpPostedFileBase from the Request object’s list of files, using its name (which is why a unique name was required for the file input control on the view).

Then we do some checking, to make sure the file actually has data, and get its information.

If you’re going to save the files somewhere (which is probably why you’re letting people upload files), then you’re going to need a way to display it for them later. To display a file within a browser, you need to know its ContentType. This will let the browser display it in the correct way.

With the byte array of the file’s contents, you can either save it to the database, in a varbinary column [for SQL Server], or write it out to disk, or some other document storage location.

Where you should save the files depends on what you’re going to do with them, how large they are, and what type of file they are.

If you see an error like

The SaveAs method is configured to require a rooted path, and the path '~/App_data/Uploads/1.pdf' is not rooted.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Web.HttpException: The SaveAs method is configured to require a rooted path, and the path '~/App_data/Uploads/1.pdf' is not rooted.

the problem is in the SaveAs function. You must pass a valid full path such as “C:\Uploads\Test\1.png”. For this reason I created in the root of the project a folder called Uploads and use Server.MapPath to find the full path.

Happy coding!

How to check if IsNumeric?

If you need to check if something is a number, in C# doesn’t exist a function for that. That I’ve created the following code.

public bool IsNumeric(object Expression)
{
    if (Expression == null || Expression is DateTime)
        return false;

    if (Expression is Int16 || Expression is Int32 || 
        Expression is Int64 || Expression is Decimal || 
        Expression is Single || Expression is Double ||
        Expression is Boolean)
        return true;

    try
    {
        if (Expression is string)
            Double.Parse(Expression as string);
        else
            Double.Parse(Expression.ToString());
        return true;
    }
    catch { } // just dismiss errors but return false
    return false;
}


Happy coding!

Remove line numbers from code

Often you copy from a site some code but it has line numbers and you have to spend some times to remove them. With my simple tool on line, you can remove them quickly.

Try it!

Customize Json result in Web API

If you work with Visual Studio 2015 and WebAPI, this short post is for you!

We have to make our Web API project easy to debug so, I’m going to remove the XML formatter. I’m doing that because I’m in a test project and I’d like to see the response in the browser. The easily way to force the response to Json for all Web API requests is to remove the XML. Obviously you shouldn't do it in production.

Global.asax

var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);

Now we can start change the setting for all Json responses accessing to GlobalConfiguration.Configuration.Formatters.JsonFormatter.

In the following examples I’ll use always the class below (create it under Models folder):

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace PSC.Models
{
    public class MapModel
    {
        public string Firstname { get; set; }
        public string Lastname { get; set; }
        public string Username { get; set; }
        public DateTime Birthdate { get; set; }
        public Uri Website { get; set; }
        public int Age { get; set; }
        public double Salary { get; set; }

        [JsonIgnore]
        public string IgnoreProperty { get; set; }
    }
}

Now we customize the Global.asax again to reply with the correct format. Change the Global.asax as following code:

using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace PSC
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            GlobalConfiguration.Configure(WebApiConfig.Register);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            // start change the setting for all Json responses accessing to
            // GlobalConfiguration.Configuration.Formatters.JsonFormatter
            var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
            // How can we indent the json response?
            json.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
            // How can we change the case in the response?
            json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
            // How can we manage the null in the response?
            json.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
            // How can we change the DateTime format?
            json.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
            // How can we change the TimeZone format?
            //json.SerializerSettings.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
            // How can we change the Culture of the serializer?
            // json.SerializerSettings.Culture = new CultureInfo("en-GB");

            var formatters = GlobalConfiguration.Configuration.Formatters;
            formatters.Add(json);
        }
    }
}

Then under Controllers create a new one and add the following code:

using Newtonsoft.Json.Serialization;
using PSC.Models;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http;

namespace PSC.Controllers
{
    public class MapController : ApiController
    {
        public HttpResponseMessage Get()
        {
            IList<mapmodel> result = new List<mapmodel>();
            result.Add(new MapModel
            {
                Age = 34,
                Birthdate = DateTime.Now,
                Firstname = "Enrico",
                Lastname = "Rossini",
                IgnoreProperty = "This text should not appear in the reponse",
                Salary = 1000,
                Username = "enrico",
                Website = new Uri("http://puresourcecode.com")
            });

            var formatter = new JsonMediaTypeFormatter();
            var json = formatter.SerializerSettings;

            json.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
            json.DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc;
            json.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
            json.Formatting = Newtonsoft.Json.Formatting.Indented;
            json.ContractResolver = new CamelCasePropertyNamesContractResolver();
            json.Culture = new CultureInfo("en-GB");

            return Request.CreateResponse(HttpStatusCode.OK, result, formatter);
        }
    }
}

The result is pretty cool!

webapi-json

Happy coding!

Khronos releases Vulkan 1.0 open graphics specification

talos-vulkan

Khronos has released Vulkan 1.0, the next generation open graphics API, and a Vulkan SDK for Windows and Linux is now available from LunarG.

Khronos is an industry consortium which creates open graphics standards, including OpenGL and WebGL. Vulkan was announced in March 2015 and represents the next generation after OpenGL, though Khronos is keen to emphasise that OpenGL, and the cut-down OpenGL ES designed for mobile and embedded use, remain in active development.

Today's release includes version 1.0 of the specification, LunarG's SDK which has been sponsored by Valve Corporation, open source conformance tests, and a sample application. Croteam's Talos Principle, running on Steam, is available in a beta version that uses the Vulkan API.

Vulkan has wide support from GPU vendors. AMD has announced a beta of its Radeon software driver which supports the Vulkan API. Intel is offering "industry-certified drivers for three generations of Intel graphics platforms, with more to come," according to VP Imad Sousou. NVIDIA has Vulkan drivers for Windows, Linux and Android available from today. Imagination has early-access Linux drivers for its PowerVR GPU and is promising "Vulkan support extended to all our tools in the very near future". Qualcomm has announced Vulkan drivers for Android 6 for its Adreno 530 and 4xx GPUs, and ARM also has drivers in progress. Google is adding Vulkan support to the Android SDK.

Vulkan is not an update of OpenGL, but takes a different approach, allowing more direct access to GPU hardware and giving developers the ability to create and manage multiple threads running on GPU cores. This enables lower latency and better performance, though porting from OpenGL is not straightforward and in some respects the Vulkan API is more challenging for developers.

Piwik C# Tracking API

This is an extension of the unofficial C# implementation of the Piwik Tracking API. You find my code on GitHub.

Usage

Three Visual Studio Solutions are provided : 

How to contribute

The Piwik C# Tracking API is a translation of the official PHP Tracking API in C#.

Translating the project is currently a manual process.

Manually translating the project is tedious because it requires

  • identifying features that have already been translated
  • merging code

We would ideally like to automate this process, we welcome contributions aimed towards this goal.

To ease the process in the mean time, the following rules are applied to any new code contributions :

  • a commit in the PHP project implies a commit in the C# project with the same message and content
  • one-to-one tag mapping between the PHP and C# projects
  • the C# code should mirror as close as possible the PHP code

As long as we do not have an automated process, we welcome suggestions in improving the manual process.

Code style

To mirror as close as possible the PHP code, we copy-paste the PHP code in the C# class and alter it so it compiles.

This can lead in a loss of C# best practices. We consider the time savings an acceptable trade-off.

Publishing the project to NuGet

Requirements

  1. The process detailed in this section must be executed right before adding a release tag to git.
  2. Publishing the project to NuGet must be done by a member of the Piwik team, holder of the private NuGet Key.

Creating a URL shortener using ASP.NET WepAPI and MVC: error handling

In the two previous post I discussed about the first step to creare this application and the implementation of the business logic. Now we can implement the error handling.

We have two custom exception classes:

  • ShorturlConflictException (when a segment already exists) and
  • ShorturlNotFoundException (when a segment isn’t found in the database).

There is also a third type: an unexpected exception, for example when there is no database connection. Normally, the user will see these errors. We have to build a mechanism where these exceptions are caught and a nice error page is shown, corresponding to the type of error, with the corresponding HTTP status code.

We need to add a filter to the Web project. Add a new folder called “Filters” and add a “ShorturlExceptionFilter” class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using PSC.Shorturl.Web.Exceptions;

namespace PSC.Shorturl.Web.Filters
{
    public class ShorturlErrorFilter : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            HttpStatusCode code = HttpStatusCode.InternalServerError;
            var ex = filterContext.Exception;
            string viewName = "Error500";

            if (ex is ShorturlNotFoundException)
            {
                code = HttpStatusCode.NotFound;
                viewName = "Error404";
            }
            if (ex is ShorturlConflictException)
            {
                code = HttpStatusCode.Conflict;
                viewName = "Error409";
            }

            filterContext.Result = new ViewResult()
            {
                ViewName = viewName
            };

            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = (int)code;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }
    }
}

This filter extends from the HandleErrorAttribute, and overrides the OnException method. In this method we do our own exception handling. If the exception is one of our own exceptions, a 404 or 409 is returned, else a 500 is returned. At the bottom of the method we tell the context that the exception is handled, and the current response (the ugly error page) will be cleared and our custom views (which are defined below) will be returned.

Add the following views in the “Views\Shared” folder:

Error404.cshtml

@{
    ViewBag.Title = "Not Found";
}

<h2>Not Found</h2>

<p>The resource you've requested isn't found.</p>

Error409.cshtml

@{
    ViewBag.Title = "Conflict";
}

<h2>Conflict</h2>

<p>The name you've chosen already exists.</p>

Error500.cshtml

@{
    ViewBag.Title = "Error";
}

<h2>Error</h2>

<p>An unexpected error occured.</p>

The only thing we have to do now is add the filter to our FilterConfig class (under App_Start). In the FilterConfig class, replace the existing method with this method:

using System.Web;
using System.Web.Mvc;
using PSC.Shorturl.Web.Filters;

namespace PSC.Shorturl.Web
{
    public class FilterConfig
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new ShorturlErrorFilter());
            filters.Add(new HandleErrorAttribute());
        }
    }
}

Now, when there is an exception, a nice error page will be shown. Next post about WebApi integration.

Creating a URL shortener using ASP.NET WepAPI and MVC: implementing the business layer

In my previsious post I discussed the first implementation of this application. In this post I’m explained how to implement the business layer.

First of all you make sure the Business project references the Data, Entities and Exceptions projects. In the Exceptions project you add two new classes:

ShorturlConflictException

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSC.Shorturl.Web.Exceptions
{
    public class ShorturlConflictException : Exception	
    {
    }
}

ShorturlNotFoundException

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PSC.Shorturl.Web.Exceptions
{
    public class ShorturlNotFoundException : Exception
    {
    }
}

We’ve implemented a stub for a business manager. The manager actually doesn’t do anything, but since we’ve implemented the database layer, it’s now possible to do some advanced stuff. Below you’ll see the new IUrlManager and UrlManager.

IUrlManager

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PSC.Shorturl.Web.Entities;

public interface IUrlManager
{
    Task<ShortUrl> ShortenUrl(string longUrl, string ip, string segment = "");
    Task<Stat> Click(string segment, string referer, string ip);
}

UrlManager

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PSC.Shorturl.Web.Data;
using PSC.Shorturl.Web.Entities;
using PSC.Shorturl.Web.Exceptions;

namespace PSC.Shorturl.Web.Business.Implementations
{
    public class UrlManager : IUrlManager
    {
        public Task<ShortUrl> ShortenUrl(string longUrl, string ip, string segment = "")
        {
            return Task.Run(() =>
            {
                using (var ctx = new ShorturlContext())
                {
                    ShortUrl url;

                    url = ctx.ShortUrls.Where(u => u.LongUrl == longUrl).FirstOrDefault();
                    if (url != null)
                    {
                        return url;
                    }

                    if (!string.IsNullOrEmpty(segment))
                    {
                        if (ctx.ShortUrls.Where(u => u.Segment == segment).Any())
                        {
                            throw new ShorturlConflictException();
                        }
                    }
                    else
                    {
                        segment = this.NewSegment();
                    }

                    if (string.IsNullOrEmpty(segment))
                    {
                        throw new ArgumentException("Segment is empty");
                    }

                    url = new ShortUrl()
                    {
                        Added = DateTime.Now,
                        Ip = ip,
                        LongUrl = longUrl,
                        NumOfClicks = 0,
                        Segment = segment
                    };

                    ctx.ShortUrls.Add(url);
                    ctx.SaveChanges();

                    return url;
                }
            });
        }

        public Task<Stat> Click(string segment, string referer, string ip)
        {
            return Task.Run(() =>
            {
                using (var ctx = new ShorturlContext())
                {
                    ShortUrl url = ctx.ShortUrls.Where(u => u.Segment == segment).FirstOrDefault();
                    if (url == null)
                    {
                        throw new ShorturlNotFoundException();
                    }

                    url.NumOfClicks = url.NumOfClicks + 1;

                    Stat stat = new Stat()
                    {
                        ClickDate = DateTime.Now,
                        Ip = ip,
                        Referer = referer,
                        ShortUrl = url
                    };

                    ctx.Stats.Add(stat);
                    ctx.SaveChanges();

                    return stat;
                }
            });
        }

        private string NewSegment()
        {
            using (var ctx = new ShorturlContext())
            {
                int i = 0;
                while (true)
                {
                    string segment = Guid.NewGuid().ToString().Substring(0, 6);
                    if (!ctx.ShortUrls.Where(u => u.Segment == segment).Any())
                    {
                        return segment;
                    }
                    if (i > 30)
                    {
                        break;
                    }
                    i++;
                }
                return string.Empty;
            }
        }
    }
}

You’ll see two new methods here: Click and NewSegment. The Click method will be executed any time anyone clicks on a short URL; some data (like the refering website) will be stored in the database. The NewSegment method creates a unique segment for our short URL. If it hasn’t found a valid segment in 30 loops, an empty string will be returned (this situation will be very rare though). The ShortenUrl method now actually shortens a long URL and stores it, together with a generated segment, in the database.

As you can see, any time a database action is executed, a new context object is created. When there are changes to the data, SaveChanges() is executed on the context at the end.

Putting it in the UrlController

Now we have a working business layer, we can call the business methods in the URL controller. Below, you see the updated Index() method:

public async Task<ActionResult> Index(Url url)
{
    if (ModelState.IsValid)
    {
        ShortUrl shortUrl = await this._urlManager.ShortenUrl(url.LongURL, Request.UserHostAddress);
        url.ShortURL = string.Format("{0}://{1}{2}{3}", Request.Url.Scheme, 
                                     Request.Url.Authority, Url.Content("~"), 
                                     shortUrl.Segment);
    }
    return View(url);
}

The controller asks the UrlManager for a new ShortUrl. When all went well, a full URL with the segment at the end will be created. At the moment there is only one problem; when we navigate to that URL, nothing happens, so we have to implement another method in the UrlController which handles the redirects. You’ll see this method below:

public async Task Click(string segment)
{
    string referer = Request.UrlReferrer != null ? Request.UrlReferrer.ToString() : string.Empty;
    Stat stat = await this._urlManager.Click(segment, referer, Request.UserHostAddress);
    return this.RedirectPermanent(stat.ShortUrl.LongUrl);
}

The only thing we have to do now is tell MVC that when we go to http://yourapp/segment, we wind up in that specific method. Below, you’ll see the new RegisterRoutes method of the class RouteConfig.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;

namespace PSC.Shorturl.Web
{
    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Click",
                url: "{segment}",
                defaults: new { controller = "Url", action = "Click" }
            );

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Url", action = "Index", 
                                id = UrlParameter.Optional }
            );
        }
    }
}

It’s very important that the “Click” route stands above the “Default” route.

Another nice thing our URL manager supports is adding a custom segment, for example http://yourapp/mysite. We have to modify three things for that:

1. Update the Url model

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace PSC.Shorturl.Web.Models
{
    public class Url
    {
        [Required]
        public string LongURL { get; set; }

        public string ShortURL { get; set; }

        public string CustomSegment { get; set; }
    }
}

2. Update the Index method

public async Task<ActionResult> Index(Url url)
{
    if (ModelState.IsValid)
    {
        ShortUrl shortUrl = await this._urlManager.ShortenUrl(url.LongURL, 
                                  Request.UserHostAddress, url.CustomSegment);
        url.ShortURL = string.Format("{0}://{1}{2}{3}", Request.Url.Scheme, 
                                     Request.Url.Authority, Url.Content("~"), 
                                     shortUrl.Segment);
    }
    return View(url);
}

3. Update the view

@model PSC.Shorturl.Web.Models.Url
@{
    ViewBag.Title = "URL shortener";
}

<h2>Shorten a URL</h2>

@Html.ValidationSummary()

@using (Html.BeginForm())
{
    <div class="form-group">
        @Html.TextBoxFor(model => model.LongURL, new { placeholder = "URL you would like to have shortened", 
                         @class = "form-control" })
    </div>

    <div class="form-group">
        @Html.TextBoxFor(model => model.CustomSegment, new { placeholder = "If you like, fill in a custom word for your short URL", 
                         @class = "form-control" })
    </div>

    if (!string.IsNullOrEmpty(Model.ShortURL))
    {
        <div>
            <h3><a href="@Model.ShortURL" target="_blank">@Model.ShortURL</a></h3>
        </div>
    }

    <input type="submit" class="btn btn-primary" value="Shorten" />
}

After this is done, it looks like we have a basic, and functioning, URL shortener. We still have to add some error handling; when an error is thrown from within the business layer, a big old ugly error page will be shown to the user. This is not something we want, this is what we’re going to fix next. In the next post.

Happy coding!

Agile approaches

There are a number of specific Agile approaches, as well as a generic agile style of working.

Extreme Programming is a software development methodology, containing mainly programming practices such as Test Driven Development, Pair programming and Continuous Integration, but little management.

Lean, which came from the manufacturing environment, is all about efficient processes. The focus is on eliminating waste from the production line and thereby reducing cost.

Scrum is a very simple agile process, designed for delivering software in small chunks, taken from a backlog of work to be done. The strength of Scrum is that it is very simple. But this is also a weakness because there is no concept of a 'project' that is managing delivery of a finite piece of work, with a process containing a beginning, middle and end.

Scrum, Lean and Extreme Programming are lightweight approaches with minimal structure and guidance.

DSDM and Agile Unified process are stronger but are still agile. The strength of DSDM lies in it being designed to deliver projects in an agile way.

Advertsing

125X125_06

Planet Xamarin

Planet Xamarin

Calendar

<<  July 2017  >>
MonTueWedThuFriSatSun
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

View posts in large calendar

Month List