Continuous: C# and F# IDE for the iPad by Frank A. Krueger

continuous_app

Continuous gives you the power of a traditional desktop .NET IDE - full C# 6 and F# 4 language support with semantic highlighting and code completion - while also featuring live code execution so you don’t have to wait around for code to compile and run. Continuous works completely offline so you get super fast compiles and your code is secure.

Continuous gives you access to all of .NET’s standard library, F#’s core library, all of Xamarin’s iOS binding, and Xamarin.Forms. Access to all of these libraries means you won’t be constrained by Continuous - you can write code exactly as you’re used to.

Real Work, on the iPad

I love the iPad but was still stuck having to lug around my laptop if I ever wanted to do “real work”. Real work, in my world, means programming. There are indeed other IDEs for the iPad: there is the powerful Pythonista app and the brilliant Codea app. But neither of those apps was able to help me in my job: writing iOS apps in C# and F#. I couldn’t use my favorite languages on my favorite device and that unfortunately relegated my iPad to a play thing.

Well it took me a bit of time, but I finally have it: a .NET IDE on the iPad (and phone too!).

But it’s not “just an IDE”. I didn’t want it to simply be sufficient - I wanted it to be great. I also thought it was a nice time to push the state of the art in .NET IDEs a tad.

For ages compiled languages like C# and F# have forced a sequential development loop on programmers: the Code-Compile-Run-Test loop. We code something up, wait for it to compile, then wait for it to deploy and run, then we get to test it.

I hate waiting for compilation and deployment so I designed Continuous to minimize those steps. It does this by eagerly compiling your code - never waiting for you to tell it when to start. It runs your code as soon as those compiles complete successfully and displays the results of that execution right next to your code. Now you can focus on the code and the results of that code instead of being distracted by all the silly machinery of a compiler and IDE.

The benefits of making compilation and execution fast have surprised me. My iPad has become my favorite place to write apps now.

  • The UI is visualized right next to the code that is building it.
  • I am no longer constrained by designers with their static view of the world - the UI objects in Continuous are live and interactive.
  • I can use real code files but still visualize objects out of them as if they were scripts.
  • I can focus on building one screen of my app at a time and see the results without having to navigate from the first screen to see the screen I’m working on over and over.

I could argue that I’m a more efficient programmer thanks to these changes. Perhaps I am more productive. But the truth is, I’m just happier using Continuous. I play with GUIs more now, trying new ideas and tweaking things left and right. It’s quite liberating and plain old fun to get nearly instant feedback on your work.

I hope you find these features as exciting as I do. Please visit the website if you want more details on them, or throw caution to the wind and buy Continuous on the App Store now to see them first-hand.

Standing on the shoulders of giants

Continuous wouldn’t be possible if it wasn’t for .NET’s great open source ecosystem. Continuous uses Roslyn for compiling C# and FSharp.Compiler.Service for compiling F#. Continuous also relies heavily on Cecil (what problem can’t be solved with Cecil?) Also, Xamarin.Forms could only be included thanks to Xamarin open sourcing it.

And of course, none of this would be possible without mono and Xamarin.

Colophon

I wrote Continuous in F# using Xamarin Studio. The code is more functional than object oriented and uses a redux style architecture. I don’t think I could have built such a large app with its sophisticated requirements without F# at my side. Three years ago I wasn’t sure how to write GUI apps in a functional language, now I question why I haven’t always done things this way.

C# 7 Features Previewed

Over the last year we've shown you various features that were being considered for C# 7. With the preview of Visual Studio 15, Microsoft has decided to demonstrate the features to make it into the final release of C# 7.

Tuple Value Types

.NET has a tuple type, but in the context of C# there are a lot of problems. Being a reference type, you probably want to avoid using it in performance sensitive code as you have to pay for GC costs. And as they are immutable, while making it safer for sharing across threads, making any changes requires allocating a new object.

C# 7 will address this by offering a tuple as a value type. This will be a mutable type, making it more efficient when performance is essential. And as a value type, it makes a copy on assignment so there is little risk of threading issues.

To create a tuple, you can use this syntax:

var result = (5, 20);

Optionally, you can name the values. This isn't necessary, it just makes the code more readable.

var result = (count: 5, sum: 20);

Multi-value Returns

Returning two values from one function has always been a pain in C-style languages. You have to either wrap the results in some sort of structure or use output parameters. Like many functional languages, C# 7 will do the first option for you:

(int, int) Tally (IEnumerable<int> list)

Here we see the basic problem with using generic tuples: there is no way to know what each field is for. So C# is offering a compiler trick to name the results:

(int Count, int Sum) Tally (IEnumerable<int> list)

We'd like to stress that C# isn't generating a new anonymous type. You are still getting back a tuple, but the compiler is pretending its properties are Count and Sum instead of Item1 and Item2. Thus these lines of code are equivalent:

var result = Tally(list);
Console.WriteLine(result.Item1);
Console.WriteLine(result.Count);

Note that we do not yet have a syntax for multi-assignment. Presumably when it happens, it will look something like this:

(count, sum) = Tally(list);

Beyond simple utility functions such as this, multi-value returns will be useful for writing asynchronous code, as async functions aren't allowed to use out parameters.

Pattern Matching: Enhanced Switch Blocks

One of the long standing complaints of VB and functional programmers alike is that C#'s switch statement is extremely limited. VB developers want ranges, while those who used to F# or Haskell want decomposition-style pattern matching. C# 7 intends to offer both.

When pattern matching on types, you can create variables to hold the result of the cast. For example, when using a switch on a System.Object you could write:

case int x:

If the object is an integer, the variable x will be populated. Otherwise it will check the next case block in a top to bottom fashion. If you want to be more specific, you can use range checks:

case int x when x > 0:
case int y:

In this example, if the object is a positive integer the x block will be executed. If the object is zero or a negative integer, the y block will be executed.

If you want to check for null, simply use this syntax:

case null;

Pattern Matching: Decomposition

So far we've just seen an incremental improvement over what is available in VB. The real power of pattern matching comes from decomposition, where you can tear apart an object. Consider this syntax:

if (person is Professor {Subject is var s, FirstName is "Scott"})

This does two things:

  1. It creates a local variable named s with the value of
    ((Professor)person).Subject
  2. It performs the equality check
    ((Professor)person).FirstName == "Scott"

Translated into C# 6 code:

var temp = person as Professor;
if (temp != null && temp.FirstName == "Scott")
{
   var s = temp.Subject
}

Presumably we'll be able to combine enhanced switch blocks in the final release.

Ref Returns

Passing large structures by reference can be significantly faster than passing them by value, as the latter requires copying the whole structure. Likewise, returning a large structure by reference can be faster.

In languages such as C, you return a structure by reference using a pointer. This brings in the usual problems with pointers such as pointing to a piece of memory after it has been recycled for another purpose.

C# avoids this problem by using a reference, which is essentially a pointer with rules. The most important rule is that you can't return a reference to a local variable. If you tried, that variable would be on a portion of the stack that is no longer valid as soon as the function returns.

In the demonstration, they instead returned a reference to a structure inside an array. Since it is effectively a pointer to an element in the array, the array itself can be modified. For example:

var x = ref FirstElement(myArray)
x = 5; //MyArray[0] now equals 5

The use case for this is highly performance sensitive code. You wouldn't use it in most applications.

Binary Literals

A minor feature is the addition of binary literals. The syntax is simple prefix, for example 5 would be "0b0101". The main use cases for this would be setting up flag based enumerations and creating bitmasks for working with C-style interop.

Local Functions

Local functions are functions that you define inside another function. At first glance, local functions look like a slightly nicer syntax for anonymous functions. But they have some advantages.

  • First, they don't require you to allocate a delegate to hold them. Not only does this reduce memory pressure, it also allows the function to be in-lined by the compiler.
  • Secondly, they don't require you to allocate an object when creating a closure. Instead it just has access to the local variables. Again, this improves performance by reducing GC pressure.

Presumably the second rule means that you can't create a delegate that points to a local function. Still, this offers organizational benefits over creating separate private functions to which you pass the current function's state as explicit parameters.

Partial Class Enhancements

The final feature demonstrated was a new way to handle partial classes. In the past, partial classes were based around the concept of code-generation first. The generated code would include a set of partial methods that the developer could implement as needed to refine behavior.

With the new "replace" syntax, you can go the other way. The developer writes code in a straight forward fashion first and then the code generator comes in and rewrites it. Here is a simple example of what the developer may write,

public string FirstName {get; set;}

Simple, clean, and completely wrong for a XAML style application. So here's what the code generator will produce:

private string m_FirstName;
static readonly PropertyChangedEventArgs s_FirstName_EventArgs 
                   = new PropertyChangedEventArgs("FirstName")

replace public string FirstName {
   get {
      return m_FirstName;
   }
   set {
      if (m_FirstName == value)
         return;
      m_FirstName = value;
      PropertyChanged?.Invoke(this, m_FirstName_EventArg);
   }
}

By using the "replace" keyword, the generated code can literally replace the hand-written code with the missing functionality. In this example, we can even handle the tedious parts that developers often skip such as caching EventArgs objects.

While the canonical example is property change notifications, this technique could be used for many "Aspect Oriented Programming" scenarios such as injecting logging, security checks, parameter validation, and other tedious boilerplate code.

Integration with C# and ReactJS

The goal for this project is to show a list of books with ReactJS from a WebAPI written in C#. You can download this project from Github.

New project

Start by creating a new ASP.NET MVC 4 project: 1. File → New → Project 2. Select ".NET Framework 4" and Templates → Visual C# → Web → ASP.NET MVC 4 Web Application. Call it "CSReact" 3. In the "New ASP.NET MVC 5 (or 4) Project" dialog, select the MVC (or empty) template.

Install ReactJS.NET

We need to install ReactJS.NET to the newly-created project. This is accomplished using NuGet, a package manager for .NET. Right-click on the "ReactDemo" project in the Solution Explorer and select "Manage NuGet Packages". Search for "ReactJS.NET" and install the ReactJS.NET (MVC 4 and 5) package.

Create basic controller and view

Right-click on the Controllers folder and click Add → Controller. Name the controller "HomeController" and select "Empty MVC Controller" as the template. Once the controller has been created, right-click on return View() and click "Add View". Enter the following details:

  • View name: Index
  • View Engine: Razor (CSHTML)
  • Create a strongly-typed view: Unticked
  • Create as a partial view: Unticked
  • Use a layout or master page: Unticked

Replace the contents of the new view file with the following:

@{
    ViewBag.Title = "Home Page";
}
@section featured {
    <section class="featured">
        <div class="content-wrapper">
            <hgroup class="title">
                <h1>@ViewBag.Title.</h1>
                <h2>@ViewBag.Message</h2>
            </hgroup>
            <p>
            </p>
        </div>
    </section>
}
<h3>React here:</h3>
<div id="content"></div>

@section scripts {
    <script src="https://fb.me/react-0.14.0.min.js"></script>
    <script src="https://fb.me/react-dom-0.14.0.min.js"></script>
    <script src="@Url.Content("~/Scripts/pages/books.jsx")"></script>
}

We also need to create the referenced JavaScript file books.jsx. Right-click on Scripts folder, select Add > New Folder, and enter "pages" as the folder name. Once created, right-click on the folder and select Add > New Item. Select Web > JavaScript File, enter "books.jsx" as the file name, and click "Add".

Create a model

Under Models folder add a new class called BookModels with the following code:

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

namespace CSReact.Models {
   /// <summary>
   /// Book models
   /// </summary>
   public class BookModels {
      /// <summary>
      /// Title of the book
      /// </summary>
      public string Title { get; set; }

      /// <summary>
      /// Author of the book
      /// </summary>
      public string Author { get; set; }
   }
}

Generate WebAPI for Books

To generate a WebAPI right-click on Controllers folder and then you select Add → Controller. Choose now WebAPI 2 Controller - Empty and type Books. The API name will be BooksController.

Fill in the controller the following code:

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;
using System.Web.Script.Serialization;
using CSReact.Models;
using Newtonsoft.Json.Serialization;

namespace CSReact.Controllers
{
    public class BooksController : ApiController
    {
       public HttpResponseMessage Get() {
          IList<BookModels> result = new List<BookModels>();
          result.Add(new BookModels() { Author = "Michael Crichton", 
                                        Title = "Jurassic Park" });
          result.Add(new BookModels() { Author = "Agatha Christie", 
                                        Title = "And Then There Were None" });

          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);
       }
    }
}

This API reply on your local server. You can call your API with an URL similar to

http://localhost:60273/api/books

and the result in the browser is a json result

[
  {
    "title": "Jurassic Park",
    "author": "Michael Crichton"
  },
  {
    "title": "And Then There Were None",
    "author": "Agatha Christie"
  }
]

Generate a book list

In the books.jsx file write the following code:

var BookList = React.createClass({
    render: function() {
        var bookNodes = this.props.data.map(function (book) {
            return (
                <div>
                    {book.title} ({book.author})
                </div>
            );
        });

        return (
            <div className="bookList">
                {bookNodes}
            </div>
        );
    }
});

This function will receive as a property data. data will contain the list of books that it has read from our WebAPI. For each row in data (you can read for each book in data), it creates a new div with title and author from book. The function returns a new div within the list of book.

Then we can write the other part of the books.jsx where you read the data from the WebAPI and display it calling BookList function. The complete code of books.jsx is

var BookList = React.createClass({
    render: function() {
        var bookNodes = this.props.data.map(function (book) {
            return (
                <div>
                    {book.title} ({book.author})
                </div>
            );
        });

        return (
            <div className="bookList">
                {bookNodes}
            </div>
        );
    }
});

var App = React.createClass({
    getInitialState: function() {
        return {data: []};
    },

    componentDidMount: function() {
        $.get(this.props.url, function(result) {
            var book = result[0];
            if (this.isMounted()) {
            }
        }.bind(this));
    },

    componentWillMount: function() {
        var xhr = new XMLHttpRequest();
        xhr.open('get', this.props.url, true);
        xhr.onload = function() {
            var jdata = JSON.parse(xhr.responseText);
            this.setState({ data: jdata });
        }.bind(this);
        xhr.send();
    },

    render: function() {
        return (
          <div className="commentBox">
            <BookList data={this.state.data} />
          </div>
      )
    }
});

ReactDOM.render(
  <App url="/api/books/Get" />,
  document.getElementById('content')
);

If you're lucky and try to start your app, you can see the list of books in your index page.

Why Visual Studio Code?



Visual Studio Code provides developers with a new choice of developer tool that combines the simplicity and streamlined experience of a code editor with the best of what developers need for their core code-edit-debug cycle. Visual Studio Code is the first code editor, and first cross-platform development tool - supporting OSX, Linux, and Windows - in the Visual Studio family.

At its heart, Visual Studio Code features a powerful, fast code editor great for day-to-day use. The Preview release of Code already has many of the features developers need in a code and text editor, including navigation, keyboard support with customizable bindings, syntax highlighting, bracket matching, auto indentation, and snippets, with support for dozens of languages.

For serious coding, developers often need to work with code as more than just text. Visual Studio Code includes built-in support for always-on IntelliSense code completion, richer semantic code understanding and navigation, and code refactoring. In the Preview, Code includes enriched built-in support for ASP.NET 5 development with C#, and Node.js development with TypeScript and JavaScript, powered by the same underlying technologies that drive Visual Studio. Code includes great tooling for web technologies such as HTML, CSS, LESS, SASS, and JSON. Code also integrates with package managers and repositories, and builds and other common tasks to make everyday workflows faster. And Code understands Git, and delivers great Git workflows and source diffs integrated with the editor.

But developers don't spend all their time just writing code: they go back and forth between coding and debugging. Debugging is the most popular feature in Visual Studio, and often the one feature from an IDE that developers want in a leaner coding experience. Visual Studio Code includes a streamlined, integrated debugging experience, with support for Node.js debugging in the Preview, and more to come later.

Architecturally, Visual Studio Code combines the best of web, native, and language-specific technologies. Using the GitHub Electron Shell, Code combines web technologies such as JavaScript and Node.js with the speed and flexibility of native apps. Code uses a newer, faster version of the same industrial-strength HTML-based editor that has powered the “Monaco” cloud editor, Internet Explorer's F12 Tools, and other projects. And Code uses a tools service architecture that enables it to use many of the same technologies that power Visual Studio, including Roslyn for .NET, TypeScript, the Visual Studio debugging engine, and more. In future previews, as we continue to evolve and refine this architecture, Visual Studio Code will include a public extensibility model that lets developers build and use plug-ins, and richly customize their edit-build-debug experience.

We are, of course, still very early with Visual Studio Code. If you prefer a code editor-centric development tool, or are building cross-platform web and cloud applications, we invite you to try out the Visual Studio Code Preview, and let us know what you think!

Next Steps

Read on to find out about:

  • Code Basics - a quick orientation of VSCode
  • Editing Evolved - from code colorization & multi-cursor to IntelliSense
  • Debugging - OK time for the really fun stuff - break, step, watch

Exception Handling in ASP.NET MVC

Index

Introduction

Exception handling is a serious matter in any application, whether it's web or desktop. Implementing a proper exception handling is important in any application. In most cases once we catch the exception we have to log the exception details to database or text file and show a friendly message to the user.

In ASP.NET applications, error handling is done mostly in two ways: at local level using try-catch blocks and at global level using application events. ASP.NET MVC comes with some built-in support for exception handling through exception filters. The HandleError is the default built-in exception filter. Unfortunately, the HandleError filter not gives a complete answer to the exception handling problem and that makes us to still rely on the Application_Error event.

In this article, we will learn about the HandleError filter and discuss about the different exception handling mechanisms that will fit to an MVC application.

HandleError Attribute

Exception filters

The exception filters are attributes that can be applied over an action or a controller or even at a global level. When you apply the filter at the global level then it will handle the exceptions raised by all the actions of all the controllers. The exception filters not only catches the exceptions that are raised by the actions but also the ones that are raised by the action filters that are applied over the actions.

All the exception filters implements the IExceptionFilter interface. Listing 1. shows the definition of this interface. The IExceptionFilter contains a single method called OnException which will be called whenever an exception occurs. The ExceptionContext parameter which derives from ControllerContext provides access to the controller, route data and HttpContext.

public interface IExceptionFilter
{
	void OnException(ExceptionContext filterContext);
}

Listing 1. IExceptionFilter definition

The HandleErrorAttribute is the default implementation of the IExceptionFilter. When you create a MVC application you will see the HandleErrorAttribute is added to the GlobalFiltersCollection in the Global.asax.cs.

public static void RegisterGlobalFilters(GlobalFiltersCollection filters)
{
	filters.Add(new HandleErrorAttribute());
}

Listing 2. Registering HandleErrorAttribute to GlobalFiltersCollection

What the HandleError filter does?

The HandleError filter handles the exceptions that are raised by the controller actions, filters and views, it returns a custom view named Error which is placed in the Shared folder. The HandleError filter works only if the <customErrors> section is turned on in web.config.

The HandleError filter handle exceptions only if the <customErrors> is turned on in web.config

Error View

The Error view that is created by default contains the following html.

@{
   Layout = null;
}

<!DOCTYPE html>
<html>
<head>
   <meta name="viewport" content="width=device-width" />
   <title>Error</title>
</head>
<body>
   <h2>
       Sorry, an error occurred while processing your request.
   </h2>
</body>
</html>

Listing 3. Error View

It contains nothing other than a simple text message. The Layout property is set to null so that the Error view doesn't inherits the application's style.

Accessing the exception details in Error view

In some cases, we have to access the exception information from the Error view. The HandleError filter not only just returns the Error view but it also creates and passes the HandleErrorInfo model to the view. The HandleErrorInfo model contains the details about the exception and the names of the controller and action that caused the exception.

Here is the definition of the HandleErrorInfo.

public class HandleErrorInfo
{   
	public HandleErrorInfo(Exception exception, string controllerName, 
		string actionName);

	public string ActionName { get; }

	public string ControllerName { get; }

	public Exception Exception { get; }
}

Listing 4. HandleErrorInfo error model

Though it's not necessary let's strongly type the Error view to the HandleErrorInfo model.

@model System.Web.Mvc.HandleErrorInfo

Listing 5. Strongly typing Error view to HandleErrorInfo model

We can easily show the exception and other information by accessing the model through the Model property.

<h2>Exception details</h2>
<p>
	Controller: @Model.ControllerName <br>
	Action: @Model.ActionName
	Exception: @Model.Exception
</p>

Listing 6. Displaying exception details in Error view

Returning different views for different exceptions

We can return different views from the HandleError filter. For ex. if you want to return one view for database exceptions and another view for application exceptions, you could easily do that by specifying the View and Exception properties as shown in the below listing.

[HandleError(Exception = typeof(DbException), View = "DatabaseError")]
[HandleError(Exception = typeof(AppException), View = "ApplicationError")]
public class ProductController
{
	
}

Listing 7. Setting views for exceptions

The HandleErrorAttribute can be applied multiple times over a controller or action or at global level.

Limitations of HandleError

The HandleError filter has some limitations by the way.

1. Not support to log the exceptions
2. Doesn't catch HTTP exceptions other than 500
3. Doesn't catch exceptions that are raised outside controllers
4. Returns error view even for exceptions raised in AJAX calls

Let see one by one.

1. Not support to log the exceptions

Logging is very important in error handling and even simple applications get much benefit by logging the errors to a text file or database. The HandleError filter suppresses the exceptions once they are handled and all it does is showing a custom view to the user.

2. Doesn't catch HTTP exceptions other than 500.

The HandleError filter captures only the HTTP exceptions having status code 500 and by-passes the others. Let's assume we have an action that returns all the posts published for a particular category. If the category not exists then we are throwing a 404 HTTP exception.

public ViewResult Posts(string category)
{
	if(_blogRepository.Category(category) == null)
		throw new HttpException(404, "Category not found");

	return _blogRepository.Posts(category);
}

Listing 8. Throwing HttpException from action

If any user passes an invalid category a 404 exception will be thrown from the action and the HandleError don't catch this error. Usually in this case, programmers like to show a custom view with a message "The requested category is not found or invalid". Not only the 404 exceptions, the HandleError doesn't catch any HTTP exception other than 500.

Handling the HTTP exceptions in filters is right or wrong is a thing for debate. In some cases we may have to bypass the HTTP exceptions to the framework to take proper action against it. So handling HTTP exceptions in filters depends upon the application and it's not mandatory.

3. Doesn't catch exceptions that are raised outside controllers

The HandleError is an exception filter and exception filters are called only if any exception happens inside the action or in the action filters that are applied over the action. So if the exception happens some other place the filter will be silent.

For ex. say we have set up a route constraint for a specific route as shown in the below listing.

routes.MapRoute(
	 "Default", 
	 "Strange~Action",
	 new { controller = "NonIE", action = "Action"  },
	 new { browserConstraint = new UserAgentConstraint("IE") } 
);

Listing 9. Adding constraints to routes

Route Constraints restricts a route against matching URLs.

The UserAgentConstraint that we set up in the above route restricts the route to handle requests from only Internet Explorer browsers. In the implementation of UserAgentConstraint I'm purposely throwing an exception.

public class UserAgentConstraint : IRouteConstraint
{
	private readonly string _restrictAgent;

	public UserAgentConstraint(string restrictAgent)
	{
		_restrictAgent = restrictAgent;
	}

	public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
	{
	  // TODO: return true if the browser is not restricted one.
		throw new NotImplementedException("You forget to implement me");
	}
}

Listing 9. UserAgentConstraint

This exception is thrown at very early stage and HandleError filter won't be there to catch this. When we access the route where the above constraint is applied we will see the yellow screen instead of the custom error page.

4. Return error view even in exceptions occurred in AJAX calls.

In case of AJAX calls, if some exception happens the HandleError filter returns the custom error view, which is not useful in the client-side. It would be great to return a piece of JSON in AJAX exceptions and for that we have to extend the HandleError filter or have to create a custom exception filter.

HandleError vs. Application_Error

Exception filters are not global error handlers and this is an important reason that forces us to still rely on Application_Error event. Some programmers don't even use the HandleError filter in their application at all and use only the Application_Error event for doing all the error handling and logging work. The important problem we face in the Application_Error event is, once the program execution reaches this point then we are out of MVC context and because of that we can miss some context information related to the exception.

Another important feature that exception filters brings to us is we can handle the exceptions in different ways at different scopes, this is important in some cases, for ex. when exceptions are raised from one controller we have to return a custom error view and for other controllers we have to return a different error view, this could be easily accomplished through exception filters but not easily through the Application_Error event.

The bottom-line is, we need to use the Application_Error event at most of the cases in applications unless we are using a framework like ELMAH which magically handles all the exceptions. But whether we need to use the HandleError filter or not is totally depend upon the application. When we need a controller or action level exception handling then we can use the HandleError filter along with the Application_Error event else we can simply ignore the HandleError filter.

Extending HandleError

Most of the cases we have to extend the built-in HandleError filter or have to create a custom exception filter to do some useful job like logging. Here is an example that shows how to extend the built-in filter to log the exceptions using log4net and return a JSON object for AJAX calls.

public class CustomHandleErrorAttribute : HandleErrorAttribute
{
	private readonly ILog _logger;

	public CustomHandleErrorAttribute()
	{
		_logger = LogManager.GetLogger("MyLogger");
	}

	public override void OnException(ExceptionContext filterContext)
	{
		if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
		{
			return;
		}

		if (new HttpException(null, filterContext.Exception).GetHttpCode() != 500)
		{
			return;
		}

		if (!ExceptionType.IsInstanceOfType(filterContext.Exception))
		{
			return;
		}

		// if the request is AJAX return JSON else view.
		if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
		{
			filterContext.Result = new JsonResult 
			{ 
				JsonRequestBehavior = JsonRequestBehavior.AllowGet, 
				Data = new 
				{ 
					error = true,
					message = filterContext.Exception.Message
				} 
			};
		}
		else
		{
			var controllerName = (string)filterContext.RouteData.Values["controller"];
			var actionName = (string)filterContext.RouteData.Values["action"];
			var model = new HandleErrorInfo(filterContext.Exception, controllerName, actionName);
			
			filterContext.Result = new ViewResult
			{
				ViewName = View,
				MasterName = Master,
				ViewData = new ViewDataDictionary<HandleErrorInfo>(model),
				TempData = filterContext.Controller.TempData
			};
		}

		// log the error using log4net.
		_logger.Error(filterContext.Exception.Message, filterContext.Exception);

		filterContext.ExceptionHandled = true;
		filterContext.HttpContext.Response.Clear();
		filterContext.HttpContext.Response.StatusCode = 500;

		filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;      
	}
}

Listing 10. Extending HandleError

Most of the code are same as in the built-in filter. Notice we have ignored the HTTP exceptions so anyway we need to wire-up the Application_Error event to catch and log the missed exceptions. If the request is an AJAX call then we are returning a JSON object that contains a boolean and the exception message else we are returning the error view. We are setting the response status code as 500 and the HandleError filter also does the same, this is important in terms of REST and HTTP standards.

Returning views from Application_Error

In some applications we have to depend upon the Application_Error event for handling all the exceptions or the ones that are missed by the exception filters. Mostly programmers like to return an MVC view instead of a static page. Though we are out of the MVC context still we can return a view using a controller (thanks to StackOverflow).

Let's create an Error controller that return different views for different errors as shown in the below listing.

public class ErrorController : Controller
{
	public ActionResult Index()
	{
		return View();
	}

	public ActionResult NotFound()
	{
		return View();
	}
}

Listing 11. Error Controller

We have to invoke this Error controller from the Application_Error to return a view after the exception is logged.

protected void Application_Error(object sender, EventArgs e)
{
	var httpContext = ((MvcApplication)sender).Context;
	var currentController = " ";
	var currentAction = " ";
	var currentRouteData = RouteTable.Routes.GetRouteData(new HttpContextWrapper(httpContext));

	if (currentRouteData != null)
	{
		if (currentRouteData.Values["controller"] != null && !String.IsNullOrEmpty(currentRouteData.Values["controller"].ToString()))
		{
			currentController = currentRouteData.Values["controller"].ToString();
		}

		if (currentRouteData.Values["action"] != null && !String.IsNullOrEmpty(currentRouteData.Values["action"].ToString()))
		{
			currentAction = currentRouteData.Values["action"].ToString();
		}
	}

	var ex = Server.GetLastError();
	var controller = new ErrorController();
	var routeData = new RouteData();
	var action = "Index";

	if (ex is HttpException)
	{
		var httpEx = ex as HttpException;

		switch (httpEx.GetHttpCode())
		{
			case 404:
				action = "NotFound";
				break;

			// others if any
		}
	}

	httpContext.ClearError();
	httpContext.Response.Clear();
	httpContext.Response.StatusCode = ex is HttpException ? ((HttpException)ex).GetHttpCode() : 500;
	httpContext.Response.TrySkipIisCustomErrors = true;
	
	routeData.Values["controller"] = "Error";
	routeData.Values["action"] = action;

	controller.ViewData.Model = new HandleErrorInfo(ex, currentController, currentAction);
	((IController)controller).Execute(new RequestContext(new HttpContextWrapper(httpContext), routeData));
}

Listing 12. Returning views from Application_Error

We are doing many things in the above code, mainly we are instantiating the Error controller and invoking it by calling the Execute() method passing the HandleErrorInfo model and this is the model used by the HandleError filter as well. To know the controller and action that handled the request we have to access the GetRouteData method of RouteTable.Routes passing the httpcontext.

We are using a switch statement just to demonstrate how we can return different error views for different HTTP exceptions. If you want to take care of AJAX calls you have to change the implementation little as we did in the custom HandleError filter but to keep things simple I've ignored that part.

ELMAH

ELMAH (Error Logging Modules and Handlers) is an application-wide error logging facility that is completely pluggable. You can easily configure ELMAH for an ASP.NET MVC application without much code. The other benefits brought up by ELMAH is, it provides a custom page where the admin can view the errors including the original yellow screen, also it provides options to send emails, generate RSS etc.

ELMAH logs only unhandled exceptions so we have to signal ELMAH to log the exceptions that are handled. When we use the HandleError filter and ELMAH in an application we will confused seeing no exceptions are logged by ELMAH, it's because once the exceptions are handled by the HandleError filter it sets the ExceptionHandled property of the ExceptionContext object to true and that hides the errors from logged by ELMAH. A better way to overcome this problem is extend the HandleError filter and signal to ELMAH as shown in the below listing.

public class ElmahHandleErrorAttribute : HandleErrorAttribute
{
	public override void OnException(ExceptionContext filterContext)
	{
		var exceptionHandled = filterContext.ExceptionHandled;
		
		base.OnException(filterContext);
		
		// signal ELMAH to log the exception
		if (!exceptionHandled && filterContext.ExceptionHandled)
			ErrorSignal.FromCurrentContext().Raise(filterContext.Exception);
	}
}

Listing 13. Signaling to Elmah

Summary

In this article we saw about the built-in HandleError filter available with ASP.NET MVC to handle the exceptions. The HandleError filter has some limitations and most importantly it doesn't handle all the exceptions that are raised by the application.

Although HandleError filter bring some benefits in customizing error handling at a controller or action level still we have to rely on the Application_Error event. ELMAH is an error handling module that is easily pluggable to an ASP.NET application. Unlike HandleError, ELMAH catches all the exceptions raised by the application.

ExceptionHandling.zip (1.9MB)

The Rise of Mobile C#

Microsoft have been struggling to get traction with their mobile computing efforts, with Windows Phone stuck at around 3% share of the smartphone market. Windows 8 is doing a little better in the tablet market but is still a distant third to iOS and Android. Despite losing in the platform wars, Microsoft’s developer ecosystem is still strong and they’re not showing much sign of wanting to give up their tools. The latest Developer Economics survey showed that 38% of mobile developers were using C# for some of their work and 16% use it as their main language. Those developers are not all focused on Microsoft platforms by a long way. They’re not all building games with Unity either. So what are they doing?

Not just Windows Phone, particularly not for pros

Whilst 30% of all developers in the survey were targeting Windows Phone, that doesn’t quite account for the majority of those whose main language is C#. Also, more than half of the developers targeting Windows Phone are Hobbyists and Explorers – i.e. those not working on mobile apps full time. If we focus on full time professional mobile developers, as we will for the rest of this article, then just 50% of those that use C# as their main language are primarily targeting Microsoft platforms. Apple’s iOS (with 23% of developers) and Google’s Android (14%) are in fact more popular targets than Windows 8 (10%). So, how do developers use C# on other platforms? With cross-platform tools, particularly Unity and Xamarin.

A flexible cross-platform approach

A lot of popular cross-platform tools for mobile development only support iOS and Android. As such, for those also wanting support for Windows Phone and possibly desktop Windows and Mac too, Xamarin is one of very few serious options. That said, it’s not just a default choice. Using Xamarin.Forms, developers can get the write-once-run-anywhere efficiency that drives many decisions to use a cross-platform approach. The downside to this approach is that it can give a lowest common denominator of functionality; not allowing developers to really optimise for the unique features of each platform. However, Xamarin also directly wraps the native platform APIs, allowing developers to call anything in the native SDKs. They can even automatically create bindings for popular third party libraries on each platform. The other key reason developers often go with a native rather than cross-platform approach is performance. However, a recent independent performance test (by an early Google engineer) showed Xamarin’s compiler produces raw performance that’s comparable to native on iOS and Android. Raw performance isn’t the only thing that counts of course – a garbage collection pause causing a stutter in your animation is jarring, however fast the the code is executing otherwise. Enterprises customers will usually put up with mild inconveniences of that nature to get the cost savings and maintenance benefits of a single code base across platforms though.

Better revenues

Possibly the best measure of the success of C# on mobile devices is the revenues of the developers using it. Whether you believe the same level of smoothness in the user experience can be achieved or not, it only matters if it costs users and revenue. Here there is no room for debate. The revenues of full time professional developers whose main language is C# are comparable to, or better than, those of other developers targeting the same primary platform with the native language. For example, the revenue distribution for C# developers on iOS is extremely similar to that for Objective-C developers and the average revenues are higher. This is both because there are more C# developers earning more than $10K (46% vs 36%) per month and while there are slightly fewer earning more than $100K per month (16% vs 17%), a significantly greater fraction of those using C# earn more than $500K per month (14% vs 6%).

This is not to suggest that C# is somehow a better language for targeting iOS than Objective-C. This is correlation and not causation. The cause of the better revenues is that the C# developers are much more likely to be targeting enterprises than the Objective-C developers and that’s where the higher revenues are most likely to be found. There’s an enormous pool of developers trained in C# and related Microsoft technologies. A lot of them are working on desktop enterprise apps or the server side. As it becomes increasingly clear that C# is a viable language for successfully delivering cross-platform mobile solutions, C#’s rise on mobile looks set to continue for several years yet.

Creare App per Windows Phone 8

Oggi è stato pubblicato il libro di Enrico Rossini Creare App per Windows Phone 8 Concetti di base.

Nel mercato degli smartphone è arrivato da qualche tempo il nuovo sistema operativo di Microsoft, Windows Phone, che rappresenta un taglio netto con il passato: nuova architettura, nuova user experience, nuova grafica e anche nuovi strumenti di sviluppo. Con questo libro, partendo dalle basi fino ad arrivare agli aspetti più avanzati, scopriamo tutte le caratteristiche della piattaforma e quali sono gli strumenti che abbiamo a disposizione per creare applicazioni originali e innovative. Dai sensori (accelerometro, GPS, NFC ecc.) alla rete, passando per notifiche, tile e accesso ai dati. Il libro è basato sulla versione più recente della piattaforma, Windows Phone 8 che, rispetto alla release originale, ha portato a un profondo rinnovamento dell’architettura e ha introdotto moltissime novità sia per gli utenti sia per gli sviluppatori.

In questo primo volume si affrontano tutti i più importanti aspetti della programmazione con Visual Studio nella versione 2012 o 2013 fino ad utilizzare tutti i componenti base messi a disposizione e l'utilizzo del Windows Phone Toolkit. I concetti qui illustrati possono essere utilizzati per Windows Phone 8, Windows Phone 8.1 e Windows 8.

Advertsing

125X125_06

Planet Xamarin

Planet Xamarin

Calendar

<<  November 2017  >>
MonTueWedThuFriSatSun
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

View posts in large calendar

Month List