2017-04-08

Adding CORS to ASP MVC WebApi to support to Angular-Cli

Imagine going to a website, say a forum of some kind, and viewing a page that a malicious user has posted information to and that post contains some JavaScript that reads your cookie and sends that information to another server, allowing the malicious user to steal your authentication cookie and then use that website as you.

Well written websites will not allow this, but not all websites are well written. So, to err on the safe side Web Browsers will only allow JavaScript to call out to the same domain that served the webpage the browser has received. So, it wouldn't be possible to retrieve a page from www.MyFavouriteForums.com and have some malicious JavaScript in a page you are viewing steal your cookie and send it to www.MyMaliciousCookieStealer.com

This is good practice, but sometimes you need the webpage you serve to be able to call out to other domains. A good example is when you are writing an Angular JS website. Executing "npm start" will run a developer webserver and let you access the app you are developing via the URL http://localhost:4200 - If the WebApi server you are accessing is on http://localhost:12345 this is not the same origin. The domain is the same (localhost), but the port is different, so they are not equal.

When you try to call out and grab some data you might see the following error message.

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access.

To solve this you must edit your Web.Config file. Inside the system.webServer section add

    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />      
      </customHeaders>
    </httpProtocol>
In the above example I have set Access-Control-Allow-Origin to *. You can set this to a specific value if you wish, but for development purposes I have instructed the server to accept requests from any origin. This will tell the web server to add the headers to any responses, which will tell the Browser that the origin of the source page you are viewing is permitted to access it.

When you deploy you will probably serve your Angular app from the same origin that runs the WebApi app. If that is the case then you will need to remove those headers from Web.Config when publishing your website.

In Web.Release.Config

  <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" xdt:Transform="Remove" />
        <add name="Access-Control-Allow-Headers" xdt:Transform="Remove" />
        <add name="Access-Control-Allow-Methods" xdt:Transform="Remove" />
      </customHeaders>
    </httpProtocol>
  </system.webServer>
If the Angular JS app is served from a different origin then put the real origin in the Web.Config rather than *.

On my machine the express server that runs when you type "npm start" returns a header that looks like this

Access-Control-Allow-Origin:*
This tells the Browser that the page served should allow JavaScript to call out to any other server, and is only present because we are running a development server. If your server is not returning this header then your page will not be permitted to call out to any origin other than the one that served it.  In that case you will need to edit the server JavaScript to add the header.

Edit node_modules\webpack-dev-server\lib\Server.js

Search for "var app" which should have "new express" in the same line.  Add the following beneath that line
    app.use(function (req, res, next) {
        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        next();
    });


2016-12-21

Preventing Unity3D IL2CPP from stripping your code

I was trying to get a list of a type's constructors at runtime using reflection, so that I could create an instance of the class using dependency injection.

All worked just fine until we tried to build the app for iOS. At first we were using Mono as the scripting back-end, but it seems that new versions of iOS pop up a dialog telling the user the app is 32 bit and may run slowly (i.e. "Your app is crap"). When switching the backend scripting to IL2CPP (in File->Builder->Player Settings) the app suddenly wasn't working. It turns out that SomeType.GetConstructors().Count was returning zero, which was a problem because obviously I wanted to invoke those constructors with dependencies.

The problem was that because these constructors weren't being calling explicitly from anywhere in my app IL2CPP decided I didn't need them, and stripped them out.

The solution is to create a file in your Assets folder called link.xml and fill it in like so....

<linker>
  <assembly fullname="Assembly-CSharp">
    <type fullname="Holovis.*" preserve="all"></type>
  </assembly>
</linker>

Assembly-CSharp is the default name created for all of your scripts by Unity. If you are using any others you need to prevent stripping on then you can add additional <assembly> nodes. As you can see from the example you can list types individually or use * as a wild card.  You can have multiple <type> nodes per <assembly> node.

Read this page from the manual for more information.

2016-12-09

Forcing a device-orientation per scene in Unity3D

Unity3D has a Screen class with an orientation property that allows you to force orientation in code, which lets you have different scenes with different orientations (useful in mini-games). this works fine for Android but crashes on iOS.
The problem is the file UnityViewControllerBaseiOS.mm that gets generated during the build for iOS has an assert in it which inadvertently prevents this property from being used. It is possible to create a post-build class that runs after the iOS build files have been generated that can alter the generated code before you compile it in XCode.
Just create a C# script named iOSScreenOrientationFix.cs and paste in the following code - adapted from this Unity3D forum post.
using UnityEngine;
using UnityEditor;
using UnityEditor.Callbacks;
using System.IO;

namespace Holovis
{
    public class iOSScreenOrientationFix : MonoBehaviour
    {
#if UNITY_CLOUD_BUILD
    // This method is added in the Advanced Features Settings on UCB
    // PostBuildProcessor.OnPostprocessBuildiOS
    public static void OnPostprocessBuildiOS (string exportPath)
    {
        Debug.Log("OnPostprocessBuildiOS");
        ProcessPostBuild(BuildTarget.iPhone,exportPath);
    }
#endif

        [PostProcessBuild]
        public static void OnPostprocessBuild(BuildTarget buildTarget, string path)
        {
#if !UNITY_CLOUD_BUILD
            ProcessPostBuild(buildTarget, path);
#endif
        }

        private static void ProcessPostBuild(BuildTarget buildTarget, string path)
        {
            if (buildTarget == BuildTarget.iOS)
            {
#if !UNITY_CLOUD_BUILD
                Debug.Log("Patching iOS to allow setting orientation");
#endif
                string filePath = Path.Combine(path, "Classes");
                filePath = Path.Combine(filePath, "UI");
                filePath = Path.Combine(filePath, "UnityViewControllerBaseiOS.mm");

                Debug.Log("File Path for View Controller Class: " + filePath);

                string classFile = File.ReadAllText(filePath);

                string newClassFile = classFile.Replace("NSAssert(UnityShouldAutorotate()", "//NSAssert(UnityShouldAutorotate()");

                File.WriteAllText(filePath, newClassFile);
            }
        }
    }
}
You can set it in a scene by attaching the following MonoBehaviour to a game object
using UnityEngine;

namespace Holovis
{
    public class SetDeviceOrientation : MonoBehaviour
    {
        public ScreenOrientation orientation = ScreenOrientation.AutoRotation;

        void Awake()
        {
            Screen.orientation = orientation;
        }
    }
}

2016-11-29

A UI thread dispatcher for Unity3D

I've recently been working on implementing an IHttpService that can work outside of a MonoBehaviour and call out to web services asynchronously.

Rather than providing my IHttpService.JsonPost method with callbacks I decided to have it return a Promise, the code for which I took from this Real Serious Games GitHub repository.

The problem is that when you use WebClient's async methods they call back the Complete events on the worker thread, so code like this won't work because you cannot manipulate UI from any thread other than the main one.

httpService.JsonPost<MyInfo>(url)
  .Then(myInfo => someTextUiObject.text = myInfo.Name);
And there seems to be no kind of thread Dispatcher in Unity3D for UI updates as there is in Windows.Forms - so I wrote my own.

using System.Collections;
using System;
using System.Threading;
using System.Collections.Generic;
using UnityEngine;
public class UiThreadDispatcher : Singleton<MonoBehaviour>
{
    static volatile int lockValue = 0;
    static Queue<Action> actionQueue = new Queue<Action>();
    void Awake()
    {
        StartCoroutine(CheckForDispatchedActions());
    }
    public static void Dispatch(Action action)
    {
        Lock();
        actionQueue.Enqueue(action);
        Unlock();
    }
    static void Lock()
    {
        while (Interlocked.Exchange(ref lockValue, 1) != 0) { }
    }
    static void Unlock()
    {
        lockValue = 0;
    }
    private IEnumerator CheckForDispatchedActions()
    {
        while (true)
        {
            Action action = null;
            Lock();
            try
            {
                while (actionQueue.Count > 0)
                {
                    action = actionQueue.Dequeue();
                    action();
                }
            }
            catch (Exception unexpectedException)
            {
                Debug.LogException(unexpectedException);
            }
            finally
            {
                Unlock();
            }
            yield return null;
        }
    }
}

The idea is that any piece of code can call the static Dispatch method, for example

//Instead of this
httpService.JsonPost<MyInfo>(url)
  .Then(myInfo => someTextUiObject.text = myInfo.Name);
//You would do this
httpService.JsonPost<MyInfo>(url)
  .Then(myInfo => UiThreadDispatcher.Dispatch(() => > someTextUiObject.text = myInfo.Name));
The Queue object needs to be locked to Enqueue/Dequeue items, but I use a simple SpinLock pattern because clashes will be very rare. Then I just have the MonoBehaviour instance execute the queued actions.

*Note to self: Must test on iOS.



2016-06-11

NodeJS, Web-Express, and TypeScript from scratch

Over the past year I've been spending my time contracting for a company in Norway. Now that project is completed it is time for me to start playing again, so I thought I'd pick up an old Node Express project. This time I intend to use TypeScript instead of Javascript. I'd also like to write unit tests and dependency injection - both are something I'm very familiar with in the C# world, but not in Node. I'm going to use this blog to record what I did; I will undoubtedly revisit some of these posts and make changes as I learn.

In this first blog I intend to cover how to get up and running with Node, Express, and WebStorm (optional) from a fresh installation of Ubuntu Linux.

The first thing we need to do is use apt-get to install Node.
sudo apt-get install nodejs
I've noticed that some Linux apps will look for a command "node" and others will look for "nodejs", so after installing I want to make an alias so that both commands will work.
cd /usr/bin
sudo ln -s nodejs node
Next we need to install the package manager for Node. This allows us to reference 3rd party libraries (such as the Express web server) in our applications. It also keeps track of which specific versions we have used for different applications we have developed, so it's possible to have different apps running on different library versions and upgrade them independently of each other.
sudo apt-get install npm
With npm installed we can now get start to import our Node dependencies. These dependencies are used for getting a project up and running very quickly and so need to be installed as global packages, which means they will be available anywhere on your Linux installation by using the npm command. To install an npm package globally we need to use the -g option.
sudo npm install -g gulp
sudo npm install -g yo
sudo npm install -g generator-express-typescript
Gulp and Yo are both task automation applications. Gulp is used to compile (transpile) our TypeScript into JavaScript and then run our test web server, we can also use it to run automated unit tests. Yo is used to create the skeleton app that we will develop further, and generator-express-typescript is the template it will use to create it. So, make a folder, cd into it and type
yo express-typescript
Yo will ask if you wish to use gulp or grunt, choose gulp; when asked if you wish to create a Dockerfile select Yes.

Once the skeleton for our new application has been created type
gulp
The gulp command will look for a file named gulpfile.js - this is where we can create named tasks to run from the command line. If no command is specified, gulp will run the default task in the file, which is named 'default'.

You will see output similar to this
[10:51:12] Using gulpfile ~/source/yourapp/gulpfile.js
[10:51:12] Starting 'clean'...
[10:51:13] Finished 'clean' after 1.22 s
[10:51:13] Starting 'ts'...
[10:51:16] Finished 'ts' after 2.29 s
[10:51:16] Starting 'server:start'...
[10:51:16] Finished 'server:start' after 19 ms
[10:51:16] Starting 'default'...
[10:51:17] Finished 'default' after 942 ms
[10:51:17] Development server listening. (PID:52108)
You can now see your skeleton app by navigating to http://localhost:3000

Optional - Downloading WebStorm

As this part is optional I won't explain the steps. Downloading and running software should be simple enough.

  1. Download webstorm to your Downloads folder
  2. cd ~/Downloads
  3. tar -xvcf WebStorm[the rest of the download's file name]
  4. sudo mv ./WebStorm-....... /opt/webstorm
  5. /opt/webstorm/bin/webstorm.sh 

Using strongly typed libraries

One of the benefits of using TypeScript instead of JavaScript is that it is strongly typed. The problem is that not all libraries are written in TypeScript and so no type information is provided by default. Thankfully the Definitely Typed project has a huge collection of definition files to help us. They are implemented as a set of interfaces; TypeScript interfaces don't transpile to JavaScript, they are just for type safety checking.

By default the Yo express-typescript template adds some of these files, but it uses an out-of-date method of referencing them. So, the next thing we will do is to remove the strongly typed definition files for this project in order to add the newer ones using the new recommended approach.

  1. Delete the tsd.json file
  2. Delete the typings folder (type rm -r typings)
  3. Edit the /app.ts and /routes/index.ts files
Next we need to install the Node package "typings", we'll do this globally so that it is available as a standard npm command and can be used when creating new projects.
sudo npm install -g typings
Now make sure you are in the root of your project and initialise typings for it.
typings init 
Now instead of downloading Definitely Typed files and putting them somewhere in our project's sources we can search for libraries using the typings search command, and install them using the typings install command.

If you look in one of your project's TS files using an editor like WebStorm you will see that the require keyword is no longer recognised. This is because the typings folder we deleted contained library definitions to give us strongly typed information for Node itself. The first thing we want to do is to correct that. Type in the command

typings search node
This will show you all strongly typed definition files that match the search phrase. An important thing to pay attention to is the Source column. When installing one of these libraries we need to prefix its name with the value in that column, separated with a tilde. For example, the "node" entry has a source "dt", so it's fully qualified name for installing is "dt~node".

Whenever we are using the Definitely Typed libraries (source = dt) we need to add the --global option to our command line so typings knows to resort to those legacy files. We also want to include the --save option so that our typings.json file is updated.

typings install --global --save dt~node
Now if you look back at one of your TS files you should see the require keyword is now recognised!

By looking through dependencies section of the package.json file we can see which libraries Yo has specified are needed for this skeleton site, and install the typings for each of them. To save you some time, just copy/paste the following lines into your terminal window.

typings install --global --save dt~express (fixes Request/Response)
typings install --global --save dt~express-serve-static-core
typings install --global --save dt~serve-static
typings install --global --save dt~mimetypings install --global --save dt~q
typings install --global --save dt~underscore
typings install --global --save dt~mongoose
typings install --global --save dt~serve-favicon
typings install --global --save dt~morgan
typings install --global --save dt~cookie-parser
typings install --global --save dt~body-parser
Now, some of the packages in the package.json are listed under the devDependencies section. When installing these we need to use --save-dev rather than just --save, this will ensure they go into the development environment's requirement list rather than the runtime list.
typings install --global --save-dev dt~should
typings install --global --save-dev dt~superagent
typings install --global --save-dev env~mocha
typings install --save-dev debug
Note that the final dependency "debug" does not have the --global option specified. This is because when you do a typings search for "debug" you will see there are two entries. Once has a source of npm, and the other has a source of dt (Definitely Typed project). The npm one is newer so we want to use that one, and since npm is the default source we don't need the prefix~ before the name, and we don't need to specify --global to tell typings it needs to look through the Definitely Typed repository.

2016-02-25

[Solved] MVCApplication Parser Error

I have this problem because I have to develop with VS running as administrator in order to use Local IIS hosting. When files are added (or generated by compiling) I think VS was setting the owner as Administrator, which IIS then cannot read. Start a command prompt as Administrator and type in the following
icacls c:\devpath\yourwebsite /grant everyone:(OI)(CI)F /T

2016-02-24

How to Create a Self Signed Certificate in IIS 7

I know I am going to want this link again in the future!