Querying Abstract Multi-Map Indexes in RavenDB (C#)

So… let’s say you have 2 similar classes in your system, like User & Person.

Now lets say we’d like to return those documents into a single list. In order to do this you simply need to define the “AbstractMultiMapIndex”, like so:

I call it the People index, (because Users are people too!)

After we’ve done that we need to create that index, like so (on App_Start):

 IndexCreation.CreateIndexes(typeof(PeopleIndex).Assembly, ds);

Now… all that’s left is creating an Action like so:

All this does, is execute the query on the index and return the results to the View (with a dynamic ViewBag)


See last post on Initializing RavenDB with StructureMap


Initializing RavenDB in MVC4 with StructureMap

I hear more and more .Net devs are starting to get into the world of NoSQL, partly in thanks to the insanely awesome product, RavenDb (from the builders of RhinoMocks and NHibernate Profiler). I feel pretty strongly this is one of the biggest contributions to .Net web developers since MVC. 

So, I want to share a very simple/clean way to initialize the RavenDB DocumentStore (on app start) and ALSO the DocumentSession (on each Http Request) using a popular IoC (Inversion of Control) container called StructureMap.

Here’s how it works:

1. Create a new MVC4 project (I’m using the empty template) and use NuGet to install the RavenDB client and StructureMap from the package manager console.

PM> Install-Package RavenDB.Client -pre 
PM> Install-Package StructureMap.MVC4

2. Even though RavenDb is very simple to install locally, try out RavenHQ and get yourself a free db. All you will need is the connection string (under ‘Manage’) after you create a db.

3. Add the RavenDb connection string to your web.config, like so:

 <add name="Raven" connectionString="Url=https://2.ravenhq.com/databases/your-db; ApiKey=your-api-key" />

4. Find the IoC.cs file and add these 2 “Initialize expressions”.

5. Now, just add a Controller which accepts IDocumentSession in the constructor and you’re all set. Like so:

I personally don’t mind having the IDocumentSession in each of my controllers if the project isn’t too large. But there are some other ways to handle this, like a base controller or a ActionFilter, but I may have a forthcoming post on that as well.

If you have any feedback why you like\dislike this approach, I would love to hear your thoughts.

Remember, keep it simple…but not simpler.


Using CloudMine to log PageViews with ASP.Net MVC

I’ve used a few services in the past to do site “event tracking” (ie Google Analytics)  but most didn’t give me all the data and control I need to easily track what was needed… (mostly user identity stuff). Another big difference is that this is all done server-side, which has it’s pros\cons as well. 

Anyway, here’s how I did it using CloudMine's backend service in ~20 lines of code.

Step1. Add this Action Filter to your MVC application (ie Global.asax.cs)

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
    public class UserTrackingAttribute : ActionFilterAttribute
        public static readonly string appId = "your CloudMine app Id";
        public static readonly string appSecret = "your CloudMine app Secret";

        class PageRequest
            public int PageId { get; set; }
            public Double Created { get; set; }
            public string Url { get; set; }
            public string UserName { get; set; }
            public string UserIP { get; set; }
            public string Controller { get; set; }
            public string Action { get; set; }

        public override void OnResultExecuting(ResultExecutingContext context)
            PageRequest preq = new PageRequest
              Url = request.RawUrl, 
              UserIP = request.UserHostAddress, 
              UserName = context.HttpContext.User.Identity.Name, 
              Created = ExtensionMethods.JsonDate(DateTime.Now),
              Action = (string)context.RequestContext.RouteData.Values["action"], 
              Controller = (string)context.RouteData.Values["controller"],
              PageId = Convert.ToInt32(context.RouteData.Values["Id"]),
          using (var client = new WebClient())
           client.Headers.Add("X-CloudMine-ApiKey", appSecret);
           client.Headers.Add("Content-Type", "application/json");
           var serializer = new JavaScriptSerializer();
           var data = serializer.Serialize(preq);
           var payload = "{\"PV_" + DateTime.Now.Ticks + "\":" + data + "}";
           var bytes = Encoding.Default.GetBytes(payload);
           client.UploadDataAsync(new Uri("https://api.cloudmine.me/v1/app/" + appId + "/text"), "PUT", bytes);

Then… just add the filter attribute [UserTracking] to any controller action and you’re ready to start logging…in real-time. 

The full example project is on my GitHub…so go fork it.


Uploading an image with AWS SDK for .Net (C#)

I recently started using cloud-based hosting (AppHarbor.com) for my latest project (Mealtik.com) and I needed a remote storage solution for the images that would be uploaded by users. I was already familiar with Amazon’s Simple Storage service (AWS S3), but never actually built a .Net app that used this API for uploading images to S3.

So…here are the steps to simply get an image published\uploaded to S3.

1. First go get an account with AWS at http://aws.amazon.com/ and then go get your accessKey and SecretKey from your account.

2. Download the AWS SDK for .Net here: http://aws.amazon.com/sdkfornet/ and include the assembly AWSSDK.dll in your project.

3. Here’s the markup:
     <input type=”file” id=”fileUpload” name=”fileUpload” size=”23” />

4. Here’s the C#:

HttpPostedFileBase file = Request.Files[0];
if (file.ContentLength > 0) // accept the file
string accessKey = "XXXXXXXXXXX";
string secretKey = "122334XXXXXXXXXX";
AmazonS3 client;

using (client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey, secretKey))
PutObjectRequest request = new PutObjectRequest();
.WithKey("meals/test.jpg").InputStream = file.InputStream;
S3Response response = client.PutObject(request);

A few things to point out:
  1. I’m uploading my image (“test.jpg”) to folder (“meals”) which is in a bucket called “mealtik”.
  2. I’m setting the image permissions to “public read”.
  3. I’m using MVC, but the code should work for webforms as well.

As you can see, it’s pretty simple to do, but for some reason I couldn’t find an example of this anywhere on the interwebs. Hope this helps!