Deploying our .NET 4.0 StackService service to IIS 6

Unfortunately the server I’m writing a ServiceStack service for is not only restricted to .NET 4.0 but also running IIS 6.0. I also need to deploy the service as a virtual directory off of the Default Web Site.

The first thing we want to do is publish/copy the files that make up our service to the IIS server.

Here’s the steps I took to get this working, obviously they may differ depending upon what access you have to the web server (and whether you deploy direct) etc.

  • From your ASP.NET/ServiceStack application, select the web service project and right mouse click.
  • Select Publish
  • Select Custom and set a profile name, mines “Files”, press OK
  • I’m going to copy the files across to the server myself, so for Publish Method, select File System and then enter a location to write your files to, click the next button
  • Leave the Configuration as Release
  • Press the Publish button

At this point the file location you selected will have the files required for the service.

Now if not already done as part of the publish steps, copy the files to the location you want to deploy them on your IIS 6.0 server. For example mine are in a folder named TestStack. Now we need to setup IIS to expose the service.

  • Open Internet Information Services (IIS) Manager or run %SystemRoot%\system32\inetsrv\iis.msc to open it
  • Expand the local computer node in the left hand tree view
  • Expand Web Sites
  • Right mouse click on the Default Web Site and select New | Virtual Directory
  • Press the Next button and enter an alias, i.e. TestStack in my case
  • Press Next and browse from IIS or enter the folder location of your service (you want the root, not the bin folder) in your browser and press next
  • Ensure Read and Run scripts (such as ASP) are checked and press Next
  • Click Finish

On the properties, Documents tab, uncheck the Enable default content page

Not sure the above is a requirement to get things working, but just happened to be something I set

On the Virtual Directory tab ensure the Execute Permissions is set to Scripts and Executables

On the ASP.NET page, ensure the ASP.NET version is 4.0.xxx

Now the virtual folder you be setup. If you’ve not got your service selected in the IIS Default Web Sites node, then select it and right mouse click, then select browse to see if all is working, or open your preferred browser and enter

http://<hostname>/StackService/metadata

If you are getting a 404 The page cannot be found error, then this might help

See Can’t get ServiceStack to work in IIS6 with HTTPS

The exact steps I took are listed below

  • Select the virtual directory in IIS, right mouse click and load the properties
  • From the Virtual Directory tab, press the Configuration button
  • Press Insert
  • From file explorer locate aspnet_isapi.dll for .NET 4.0, for example mine is located in %windir%\Microsoft.NET\Framework\v4.0.30319
  • Once located enter %windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll (replacing %windir% with you actual location) in the Executable textbox
  • Uncheck the Verify that file exists checkbox, then press OK
  • Press OK again and again until the properties dialog is closed

Now if you refresh or reload the URL for the virtual folder or again select Browse from IIS, the meta data from ServiceStack should be displayed.

Whilst this may be a fairly specific case, i.e. deployed to .NET 4.0 on IIS 6.0, I thought it might still be a useful post anyway.

.NET 4.0 compatible ServiceStack service

In my last post I outlined the creation of a ServiceStack web service, pretty much as per the current documentation on the ServiceStack website.

I’m now going to create a bare minimum service from scratch (i.e. not using the ServiceStack project templates). The reason for this is that I want to deploy a service to an old server box which doesn’t support .NET greater than 4.0. Out of the box the templates don’t work with older versions of .NET.

This post will concentrate on a .NET 4.0 compatible ServiceStack, but the same steps can be applied to a bare minimum .NET 4.6 service as well – obviously just change the .NET framework to suit.

We’ll recreate the Hello World implementation as per the ServiceStack templates in this example.

Note: I’m not aiming to create a “best practices” example of code, this literally will be the bare minimum set of code and projects to implement the demo Hello World service.

  • Create a ASP.NET Empty Web Application, setting the .NET framework to .NET 4 – my project is named TestStack
  • Using NuGet, install the ServiceStack packages – use the 4.0.24 versions. This version is required because of a PCL issue with subsequent versions supporting .NET 4.0 (see ServiceStack NuGet update 4.0.22 to 4.0.31 caused errors on deployment)
  • Add a C# class, named AppHost and include the following code
    using Funq;
    using ServiceStack;
    
    public class AppHost : AppHostBase
    {
       public AppHost()
          : base("TestStack", 
               typeof(MyServices).Assembly) 
       { 
       }
    
       public override void Configure(Container container)
       {
       }
    }
    
  • Now add another Class named MyServices and add the following code
    using ServiceStack;
    
    public class MyServices : Service
    {
       public object Any(Hello request)
       {
          return new HelloResponse 
          { 
             Result = "Hello, {0}!".Fmt(request.Name) 
          };
       }
    }
    
  • Add another Class name Hello and add the following code
    using ServiceStack;
    
    [Route("/hello/{Name}")]
    public class Hello : IReturn<HelloResponse>
    {
       public string Name { get; set; }
    }
    
  • Now add the last class, which is named HelloResponse and add the following code
    public class HelloResponse
    {
       public string Result { get; set; }
    }
    
  • Now add a Global Application Class, keep it named as Global and in the code behind, remove the existing class and methids and replace with the following
    public class Global : HttpApplication
    {
       protected void Application_Start(object sender, EventArgs e)
       {
          new AppHost().Init();
        }
    }
    
  • Finally we need to alter the Web.config to look like this
    <configuration>
      <system.web>
          <compilation debug="true" targetFramework="4.0" />
          <httpHandlers>
            <add path="*" type="ServiceStack.HttpHandlerFactory, ServiceStack" verb="*" />
          </httpHandlers>
          <pages controlRenderingCompatibilityVersion="4.0" />
        </system.web>
    
      <system.webServer>
        <modules runAllManagedModulesForAllRequests="true" />
        <validation validateIntegratedModeConfiguration="false" />
        <urlCompression doStaticCompression="true" doDynamicCompression="false" />
        <handlers>
          <add path="*" name="ServiceStack.Factory" type="ServiceStack.HttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
        </handlers>
      </system.webServer>
    
    </configuration>
    

Run the application via Visual Studio and you should see the metadata page showing the Hello operation. To double check the operation works simply change the URL in your preferred browser to

http://localhost:49810/Hello/World

Obviously change the port to the one supplied by iisexpress.

Implementing a client and services with ServiceStack

ServiceStack, is a lightweight framework for writing web services.

Getting Started

Let’s just create a “default” service and client first.

See Create your first WebService for information on creating your first service. I’ll replicate some of the steps here also…

  • Using Visual Studio, Tools | Extensions and Updated, search for ServiceStack templates and install (if not already installed)
  • Create a new ServiceStack ASP.NET Empty project (target .NET 4.6)
  • Build and run

By default this will create a service which accepts a Hello object and returns a HelloResponse (for reference, here’s those classes)

public class HelloResponse
{
   public string Result { get; set; }
}

[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
   public string Name { get; set; }
}

Note: The Hello class “implements” IReturn (which actually is just a marker interface, i.e. no methods) to give our client the ability to pass Hello objects (and hence have type safety etc.) to the service and inform the client what response to expect.

We can test the service using our web browser, for example my server is running on the localhost on port 50251, so typing the URL http://localhost:50251/Hello/Bob (note: the Route attribute defines the “route” to the specific method etc. hence you can see how this maps to the URL we used) will result in the Hello class being run with the argument Bob as the Name. The response will be displayed in the browser, along the lines of Result Hello, Bob!. This is the same result we’ll be expecting from our client app.

But how did we get the result “Hello, World!” from the server? This is where the MyService implementation in the generated server code comes in. When the server’s AppHost starts up it looks for services. These are then used to intercept/generate calls and responses. See the code below (copied from the generated code)

public class MyServices : Service
{
   public object Any(Hello request)
   {
      return new HelloResponse 
      { 
         Result = "Hello, {0}!".Fmt(request.Name) 
      };
   }
}

Let’s create a client app.

  • Create a Console application
  • From the Package Manager Console, run Install-Package ServiceStack.Client
  • Copy the Hello and HelloResponse classes from the service to the client
  • In the Main method add the following
    var client = new JsonServiceClient("http://localhost:50251/");
    var resp = client.GetAsync(new Hello { Name = "Bob" })
       .Success(tsk =>
       {
          Console.WriteLine(tsk.Result);
       })
       .Error(e =>
       {
          Console.WriteLine(e.Message);
       });
    
    Console.ReadLine();
    

For the client Api we could have called the service using

var resp = client.GetAsync<HelloResponse>("/hello/World");

if preferred, and this will do away for the need for the Hello class in the client.

NUnit’s TestCaseSourceAttribue

When we use the TestCaseAttribute with NUnit tests, we can define the parameters to be passed to a unit test, for example

[TestCase(1, 2, 3)]
[TestCase(6, 3, 9)]
public void Sum_EnsureValuesAddCorrectly1(double a, double b, double result)
{
   Assert.AreEqual(result, a + b);
}

Note: In a previous release the TestCaseAttribute also had Result property, but this doesn’t seem to be the case now, so we’ll expect the result in the parameter list.

This is great, but what if we want our data to come from a dynamic source. We obviously cannot do this with the attributes, but we could using the TestCaseSourceAttribute.

In it’s simplest form we could rewrite the above test like this

[Test, TestCaseSource(nameof(Parameters))]
public void Sum_EnsureValuesAddCorrectly(double a, double b, double result)
{
   Assert.AreEqual(result, a + b);
}

private static double[][] Parameters =
{
   new double[] { 1, 2, 3 },
   new double[] { 6, 3, 9 }
};

an alternative to the above is to return TestCaseData object, as follows

[Test, TestCaseSource(nameof(TestData))]
public double Sum_EnsureValuesAddCorrectly(double a, double b)
{
   return a + b;
}

private static TestCaseData[] TestData =
{
   new TestCaseData(1, 2).Returns(3),
   new TestCaseData(6, 3).Returns(9)
};

Note: In both cases, the TestCaseSourceAttribute expects a static property or method to supply the data for our test.

The property which returns the array (above) doesn’t need to be in the Test class, we could have a separate class, such as

[Test, TestCaseSource(typeof(TestDataClass), nameof(TestData))]
public double Sum_EnsureValuesAddCorrectly(double a, double b)
{
   return a + b;
}

class TestDataClass
{
   public static IEnumerable TestData
   {
      get
      {
         yield return new TestCaseData(1, 2).Returns(3);
         yield return new TestCaseData(6, 3).Returns(9);
      }
   }
}

Extended or unit test capabilities using the TestCaseSource

If we take a look at NBench Performance Testing – NUnit and ReSharper Integration we can see how to extend our test capabilities using NUnit to run our extensions. i.e. with NBench we want to create unit tests to run performance tests within the same NUnit set of tests (or separately but via the same test runners).

I’m going to recreate a similar set of features for a more simplistic performance test.

Note: this code is solely to show how we can create a similar piece of testing functionality, it’s not mean’t to be compared to NBench in any way, plus NUnit also has a MaxTimeAttribute which would be sufficient for most timing/performance tests.

Let’s start by creating an attribute which will use to detect methods which should be performance tested. Here’s the code for the attribute

[AttributeUsage(AttributeTargets.Method)]
public class PerformanceAttribute : Attribute
{
   public PerformanceAttribute(int max)
   {
      Max = max;
   }

   public int Max { get; set; }
}

The Max property defines a max time (in ms) that a test method should take. If it takes longer than the Max value, we expect a failing test.

Let’s quickly create some tests to show how this might be used

public class TestPerf : PerformanceTestRunner<TestPerf>
{
   [Performance(100)]
   public void Fast_ShouldPass()
   {
      // simulate a 50ms method call
      Task.Delay(50).Wait();
   }

   [Performance(100)]
   public void Slow_ShouldFail()
   {
      // simulate a slow 10000ms method call
      Task.Delay(10000).Wait();
   }
}

Notice we’re not actually marking the class as a TestFixture or the methods as Tests, as the base class PerformanceTestRunner will create the TestCaseData for us and therefore the test methods (as such).

So let’s look at that base class

public abstract class PerformanceTestRunner<T>
{
   [TestCaseSource(nameof(Run))]
   public void TestRunner(MethodInfo method, int max)
   {
      var sw = new Stopwatch();
      sw.Start();
      method.Invoke(this, 
         BindingFlags.Instance | BindingFlags.InvokeMethod, 
         null, 
         null, 
         null);
      sw.Stop();

      Assert.True(
         sw.ElapsedMilliseconds <= max, 
         method.Name + " took " + sw.ElapsedMilliseconds
      );
   }

   public static IEnumerable Run()
   {
      var methods = typeof(T)
         .GetMethods(BindingFlags.Public | BindingFlags.Instance);
      
      foreach (var m in methods)
      {
         var a = (PerformanceAttribute)m.GetCustomAttribute(typeof(PerformanceAttribute));
         if (a != null)
         {
            yield return 
               new TestCaseData(m, a.Max)
                     .SetName(m.Name);
         }
      }
   }
}

Note: We’re using a method Run to supply TestCaseData. This must be public as it needs to be accessible to NUnit. Also we use SetName on the TestCaseData passing the method’s name, hence we’ll see the method as the test name, not the TestRunner method which actually runs the test.

This is a quick and dirty example, which basically locates each method with a PerformanceAttribute and yields this to allow the TestRunner method to run the test method. It simply uses a stopwatch to check how long the test method took to run and compares with the setting for Max in the PerformanceAttribute. If the time to run the test method is less than or equal to Max, then the test passed, otherwise it fails with a message.

When run via a test runner you should see a node in the tree view showing TestPerf, with a child of PerformanceTestRunner.TestRunner, then child nodes below this for each TestCaseData ran against the TestRunner, we’ll see the method names Fast_ShouldPass and Slow_ShouldFail – and that’s it, we’ve reused NUnit, the NUnit runners (such as ReSharper etc.) and created a new testing capability, the Performance test.

Auto generating test data with Bogus

I’ve visited this topic (briefly) in the past using NBuilder and AutoFixture.

When writing unit tests it would be useful if we can create objects quickly and with random or better still semi-random data.

When I say semi-random, what I mean is that we might have some type with an Id property and we know this Id can only have a certain range of values, so we want a value generated for this property within that range, or maybe we would like to have a CreatedDate property with some data that resembles n years in the past, as opposed to just random date.

This is where libraries such as Faker.Net and Bogus come in – they allow us to generate objects and data, which meets certain criteria and also includes the ability to generate data which “looks” like real data. For example, first names, jobs, addresses etc.

Let’s look at an example – first we’ll see what the “model” looks like, i.e. the object we want to generate test data for

public class MyModel
{
   public string Name { get; set; }
   public long Id { get; set; }
   public long Version { get; set; }
   public Date Created { get; set; }
}

public struct Date
{
   public int Day { get; set; }
   public int Month { get; set; }
   public int Year { get; set; }
}

The date struct was included because this mirrors a similar type of object I get from some web services and because it obviously requires certain constraints, hence seemed a good example of writing such code.

Now let’s assume that we want to create a MyModel object. Using Bogus we can create a Facker object and apply constraints or assign random data to. Here’s an example implementation

var modelFaker = new Faker<MyModel>()
   .RuleFor(o => o.Name, f => f.Name.FirstName())
   .RuleFor(o => o.Id, f => f.Random.Number(100, 200))
   .RuleFor(o => o.Version, f => f.Random.Number(300, 400))
   .RuleFor(o => o.Created, f =>
   {
      var date = f.Date.Past();
      return new Date { Day = date.Day, Month = date.Month, Year = date.Year };
   });

var myModel = modelFaker.Generate();

Initially we create the equivalent of a builder class, in this case the Faker. Whilst we can generate a MyModel without all the rules being set, the rules allow us to customize what’s generated to something more meaningful for our use – especially when it comes to the Date type. So in order, the rules state that the Name property on MyModel should resemble a FirstName, the Id is set to a random value within the range 100-200, likewise the Version is constrained to the range 300-400 and finally the Created property is set by generating a past date and assigning the day, month and year to our Date struct.

Finally we Generate an instance of a MyModel object via the Faker builder class. An example of the values supplied by the Faker object are shown below

Created - Day = 12, Month = 7, Year = 2016
Id - 116
Name - Gwen
Version - 312

Obviously this code only works for classes with a default constructor. So what do we do if there’s no default constructor?

Let’s add the following to the MyModel class

public MyModel(long id, long version)
{
   Id = id;
   Version = version;
}

Now we simply change our Faker to look like this

var modelFaker = new Faker<MyModel>()
   .CustomInstantiator(f => 
      new MyModel(
         f.Random.Number(100, 200), 
         f.Random.Number(300, 400)))
   .RuleFor(o => o.Name, f => f.Name.FirstName())
   .RuleFor(o => o.Create, f =>
   {
      var date = f.Date.Past();
      return new Date { Day = date.Day, Month = date.Month, Year = date.Year };
   });

What if you don’t want to create a the whole MyModel object via Faker, but instead, you just want to generate a valid looking first name for the Name property? Or what if you are already using something like NBuilder but want to just use the Faker data generation code?

This can easily be achieved by using the non-generic Faker. Create an instance of it and you’ve got access to the same data, so for example

var f = new Faker();

myModel.Name = f.Name.FirstName();

References

Bogus for .NET/C#

RabbitMQ in Docker

As part of a series of posts on running some core types of applications in Docker, its time to run up a message queue. Let’s try the Docker RabbitMQ container.

To run, simply use the following

docker run -d --hostname my-rabbit --name some-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3

If you’d like to use the RabbitMQ management tool, then run this instead (which runs RabbitMQ and the management tool)

docker run -d --hostname my-rabbit --name some-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3-management

Note: default login for the management UI is via a web browser using http://host:15672 obviously replacing the host with your server IP address. The default login and password are guest/guest.

From Visual Studio, create two test applications, one for sending messages and the second for receiving messages (mine are both console application) and using NuGet, add RabbitMQ.Client to them both. I’m going to just duplicate the code from the RabbitMQ tutorial here. So the application for sending messages should look like this

static void Main(string[] args)
{
   var factory = new ConnectionFactory
   {
      HostName = "localhost",
      Port = AmqpTcpEndpoint.UseDefaultPort
   };
   using (var connection = factory.CreateConnection())
   {
      using (var channel = connection.CreateModel())
      {
         channel.QueueDeclare("hello", false, false, false, null);

         var message = "Hello World!";
         var body = Encoding.UTF8.GetBytes(message);

         channel.BasicPublish(String.Empty, "hello", null,body);
         Console.WriteLine(" [x] Sent {0}", message);
      }
   }
   Console.ReadLine();
}

The receiver code looks like this

static void Main(string[] args)
{
   var factory = new ConnectionFactory
   {
      HostName = "localhost",
      Port = AmqpTcpEndpoint.UseDefaultPort
   };
   using (var connection = factory.CreateConnection())
   {
      using (var channel = connection.CreateModel())
      {
         channel.QueueDeclare("hello", false, false, false,null);

         var consumer = new EventingBasicConsumer(channel);
         consumer.Received += (model, ea) =>
         {
            var body = ea.Body;
            var message = Encoding.UTF8.GetString(body);
            Console.WriteLine(" [x] Received {0}", message);
         };
         channel.BasicConsume("hello", true, consumer);

         Console.WriteLine("Press [enter] to exit.");
         Console.ReadLine();
      }
   }
}

Obviously localhost should be replaced with the host name/ip address of the Docker server running RabbitMQ.

Redis service and client

Redis is an in memory store/cache, key/value store. Luckily there’s a Docker image for this.

Let’s run an instance of Redis via Docker on an Ubuntu server

docker run --name myredis -d -p 6379:6379 redis

Oh, how I love Docker (and ofcourse the community who create these images). This will run Redis and return immediately to your host’s command prompt (i.e. we do not go into the instance of Redis).

To run the redis client we’ll need to switch to the instance of the Docker container running Redis and then run the redis command line interface, thus

docker exec -it myredis bash
redis-cli

We’ll use this CLI later to view data in the cache.

C# client

There are several Redis client libraries available for .NET/C#, I’m going to go with ServiceStack.Redis, mainly because I’ve been using ServiceStack recently. So create a Console application, add the nuget packages for ServiceStack.Redis and now add the following code

public class Person
{
   public string FirstName { get; set; }
   public string LastName { get; set; }
}

class Program
{
   static void Main(string[] args)
   {
      var client = new RedisClient("redis://xxx.xxx.xxx.xxx:6379");
      client.Add("1234", new Person {FirstName = "Scooby", LastName = "Doo"});
      client.Save();
   }
}

Obviously change xxx.xxx.xxx.xxx to your server ip address.

This code will simply write the Person object to the store against the key 1234. If you have the redis-cli running then you can type

get 1234

this should result in the following result

"{\"FirstName\":\"Scooby\",\"LastName\":\"Doo\"}"

Ofcourse, we now need to use the ServiceStack.Redis client to read our data back. Just use this

var p = client.Get<Person>("1234");

Security

By default Redis has no security set up, hence we didn’t need to specify a user name and password. Obviously in a production environment we’d need to implement such security (or if using Redis via a cloud provider such as Azure).

For our instance we can secure Redis as a whole using the command AUTH. So from redis-cli run

CONFIG SET requirepass "password"
AUTH "password"

If you run AUTH “password” and get Err Client sent AUTH, but no password is set you’ll need the CONFIG line, otherwise the AUTH line should work fine. Our client application will need the following changes to the URL

var client = new RedisClient("redis://password@xxx.xxx.xxx.xxx:6379");

To remove the password (if you need to) simple type the following from the redis-cli

CONFIG SET requirepass ""

References

https://github.com/ServiceStack/ServiceStack.Redis

MongoDB revisited

As I’m busy setting up my Ubuntu server, I’m going to revisit a few topics that I’ve covered in the past, to see whether there are changes to working with various servers. Specifically I’ve gone Docker crazy and want to run these various server in Docker.

First up, let’s see what we need to do to get a basic MongoDB installation up and running and the C# client to access it (it seems some things have changes since I last did this).

Getting the server up and running

First off we’re going to get the Ubuntu server setup with an instance of MongoDB. So let’s get latest version on mongo for Docker

docker pull mongo:latest

this will simply download the latest version of the MongoDB but not run it. So our next step is to run the MongoDB Docker instance. By default the port MongoDB uses is 27017, but this isn’t available to the outside world. So we’re going to want to map this to a port accessible to our client machine(s). I’m going to use port 28000 (there’s no specific reason for this port choice). Run the following command from Ubuntu

docker run -p 28000:27017 --name my-mongo -d mongo

We’ve mapped MongoDB to the previously mentioned port and named the instance my-mongo. This will run MongoDB in the background. We can now look to write a simple C# client to access the instance.

Interactive Shell

Before we proceed to the client, we might wish to set-up users etc. in MongoDB and hence run its shell. Now running the following

docker exec -t my-mongo mongo

Didn’t quite work as expected, whilst I was placed inside the MongoDB shell, commands didn’t seem to run.

Note: This could be something I’m missing here, but when pressing enter, the shell seemed to think I was about to add another command.

To work with the shell I found it simpler to connect to the Docker instance using bash, i.e.

docker exec -t my-mongo bash

then run

mongo

to access the shell.

I’m not going to set up any users etc. at this point, we’ll just used the default setup.

Creating a simple client

Let’s fire up Visual Studio 2015 and create a console application. Then using NuGet add the MongoDB.Driver by MongoDB, Inc. Now add the following code to your Console application

public class Person
{
   public ObjectId Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public int Age { get; set; }
}

class Program
{
static void Main(string[] args)
{
   var client = new MongoClient("mongodb://xxx.xxx.xxx.xxx:28000");
   var r = client.GetDatabase("MyDatabase");
   var collection = r.GetCollection<Person>("People");
   collection.InsertOne(new Person 
   { 
      FirstName = "Scooby", 
      LastName = "Doo", 
      Age = 27 
   });
}

Obviously replace the xxx.xxx.xxx.xxx with the IP address of your server (in my case my Ubuntu server box), the port obviously matches the port we exposed via Docker. You don’t need to “create” the database explicitly via the shell or a command, you can just run this code and it’ll create MyDatabase then the table People and then insert a record.

Did it work?

Hopefully your Console application just inserted a record. There should have been no timeout or other exception. Ofcourse we can use the Console application, for example

var client = new MongoClient("mongodb://xxx.xxx.xxx.xxx:28000");
var r = client.GetDatabase("MyDatabase");
var collection = r.GetCollection<Person>("People");
foreach (var p in collection.FindSync(_ => true).ToList())
{
   Console.WriteLine($"{p.FirstName} {p.LastName}");                
}

I’m using the synchronous methods to find and create the list, solely because my Console application is obviously pretty simple, but the MongoDB driver library offers Async versions of these methods as well.

The above code will write out Scooby Doo as the only entry in our DB, so all worked fine. How about we do the same thing using the shell.

If we now switch back to the server and if its not running, run the MongoDB shell as previously outlined. From the shell run the following

use MyDatabase
db.People.find()

We should now see a single entry

{ 
  "_id" : ObjectId("581d9c5065151e354837b8a5"), 
  "FirstName" : "Scooby", 
  "LastName" : "Doo", 
  "Age" : 27 
}

Just remember, we didn’t set this instance of MongoDB up to use a Docker Volume and hence when you remove the Docker instance the data will disappear.

So let’s quickly revisit the code to run Mongo DB within Docker and fix this. First off exit back to the server’s prompt (i.e. out of the Mongo shell and out of the Docker bash instance).

Now stop my-mongo using

docker stop my-mongo

You can restart mongo at this point using

docker start my-mongo

and your data will still exist, but if you run the following after stopping the mongo instance

docker rm my-mongo

and execute Mongo again the data will have gone. If we add a volume command to the command line argument, and so we will execute the following

docker run -p 28000:27017 -v mongodb:/data/mongodb --name my-mongo -d mongo

the inclusion of the /v will map the mongodb data (/data/mongodb) to the volume on the local machine named mongodb. By default this is created in /var/lib/docker/volumes, but ofcourse you could supply a path to an alternate location

Remember, at this point we’re still using default security (i.e. none), I will probably create a post on setting up mongo security in the near future

.NET Core

This should be a pretty short post, just to outline using .NET core on Linux/Ubuntu server via Docker.

We could look to install .NET core via apt-get, but I’ve found it so much simpler running up a Docker container with .NET core already implemented in, so let’s do that.

First up, we run

docker run -it microsoft/dotnet:latest

This is an official Microsoft owned container. The use of :latest means we should get the latest version each time we run this command. The -it switch switches us straight into the Docker instance when it’s started, I/e/ into bash.

Now this is great if you’re happy to lose any code within the Docker image when it’s removed, but if you want to link into your hosts file system it’s better to run

docker run -it -v /home/putridparrot/dev:/development microsoft/dotnet:latest

Where /home/putridparrot/dev on the left of the colon, is a folder on your host/server filesystem and maps to a folder inside the Docker instance which will be named development (i.e. it acts like a link/shortcut).

Now when you are within the Docker instance you can save files to the host (and vice/versa) and they’ll persist beyond the life of the Docker instance and also allow us a simply means of copying files from, say a Windows machine into the instance of dotnet on the Linux server.

And that literally is that.

But let’s write some code and run it to prove everything is working.

To be honest, you should go and look at Install for Windows (or one of the installs for Linux or Mac) as I’m pretty much going to recreate the documentation on running dotnet from these pages

To run the .NET core framework, this includes compiling code, we use the command

dotnet

Before we get going, .NET core is very much a preview/RC release, so this is the version I’m currently using (there’s no guarantee this will work the same way in a production release), running

dotnet --version

we get version 1.0.0-preview2-003131.

Let’s create the standard first application

Now, navigate to home and then make a directory for some source code

cd /home
mkdir HelloWorld
cd /HelloWorld

yes, we’re going to write the usual, Hello World application, but that’s simply because the dotnet command has a built in “new project” which generates this for us. So run

dotnet new

This creates two files, Program.cs looks like this

using System;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

nothing particularly interesting here, i.e. its a standard Hello World implementation.

However a second file is created (which is a little more interesting), the project.json, which looks like this

{
  "version": "1.0.0-*",
  "buildOptions": {
    "debugType": "portable",
    "emitEntryPoint": true
  },
  "dependencies": {},
  "frameworks": {
    "netcoreapp1.0": {
      "dependencies": {
        "Microsoft.NETCore.App": {
          "type": "platform",
          "version": "1.0.1"
        }
      },
      "imports": "dnxcore50"
    }
  }
}

Now, we need to run the following from the same folder as the project (as it will use the project.json file)

dotnet restore

this will restore any packages required for the project to build. To build and run the program we use

dotnet run

What are the dotnet cmd options

Obviously you can run dotnet –help and find these out yourself, but just to give a quick overview, this is what you’ll see as a list of commands

Common Commands:
  new           Initialize a basic .NET project
  restore       Restore dependencies specified in the .NET project
  build         Builds a .NET project
  publish       Publishes a .NET project for deployment (including the runtime)
  run           Compiles and immediately executes a .NET project
  test          Runs unit tests using the test runner specified in the project
  pack          Creates a NuGet package

.NET Core in Visual Studio 2015

Visual Studio (2015) offers three .NET core specific project templates, Class Library, Console application and ASP.NET Core.

References

https://docs.microsoft.com/en-us/dotnet/articles/core/tutorials/using-with-xplat-cli
https://docs.asp.net/en/latest/getting-started.html
https://docs.microsoft.com/en-us/dotnet/articles/core/tools/project-json

Hosting a github like service on my Ubuntu server

I was thinking it would be cool to host some private git repositories on my Ubuntu server. That’s where Gogs comes in.

Sure I could have created a git repository “manually” but why bother when Gogs comes in a docker instance as well (and I love Docker).

Excellent documentation is available on the Gogs website or via Docker for Gogs on GitHub. But I will be recreating the bare essentials here so I know what worked for me.

First off, we’re going to need to create a Docker volume. For those unfamiliar with Docker, data is stored in the instance of Docker and therefore lost when it shuts down. To allow data to persist beyond the life of the Docker instance, we create a Docker volume.

So first up, I just used the default Docker volume location using

docker volume create --name gogs-data

On my Ubuntu installation, this folder is created within /var/lib/docker.

Next up we’ll simply run

docker run --name=gogs -p 10022:22 -p 10080:3000 -v gogs-data:/data gogs/gogs

This command will download/install an instance of gogs and it will be available on port 10080 of the server. The instance will connect it’s data through to our previously created volume using the -v switch.

From your chosen web browser, you can display the Gogs configuration web page using http://your-server:10080.

As I didn’t have MySQL or PostgresSQL set-up at the time of installation, I simply chose SQLite from the database options shown on the configuration page.

That’s pretty much it – you’ll need to create a user login for your account and then you can start creating repositories.

I’m not sure if I’m doing something wrong, but I noticed that when you want to clone a repository, Gogs says I should clone

http://localhost:3000/mark/MyApp.git

Obviously localhost is no use from a remote machine and also 3000 seems to be incorrect, and should be 10080 (as specified in the run command).