Mapping database objects to models – the Lambda way

< 1 min read Updated with statements that can be executed or deferred.

// Example models
public class SomeModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List Items { get; set; }
}
public class SomeOtherModel
{
    public int Id { get; set; }
    public string Text { get; set; }
}
//Expression mapper - not executed
public Expr<Func> Map_SomeTable_SomeModel_Expr()
{
    return x => new SomeModel
    {
        Id = x.Id,
        Name = x.Name,
        Items = db.SomeOtherTable.Where(y => y.SomeTableId == x.Id).Select(Map_SomeOtherTable_SomeOtherModel_Expr()).ToList()
    }
}

Localization in c#

2 min read Localization in C# is very straightforward. C# comes with Resource files, which are great because they can be easily translated, and C# can switch between them automatically.

First, add a new Resource File to your project. In my case, I called it SiteFields.resx. This will be the default language file, which in this case is English.

Next, we create a Localized Display Name Attribute, so we can leverage our ViewModels properly, instead of relying on text.

public class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
    public LocalizedDisplayNameAttribute(string resourceId) : base(GetMessageFromResource(resourceId))
    {
    }
    private static string GetMessageFromResource(string resourceId)
    {
        CultureInfo culture = null;
        if (HttpContext.Current.Session["CultureInfo"] != null)
            culture = (CultureInfo)HttpContext.Current.Session["CultureInfo"];
        else
            culture = CultureInfo.CurrentCulture;
        return Resources.SiteFields.ResourceManager.GetString(resourceId, culture);
    }
}

Domain Routes and using subdomains in MVC as routes

< 1 min read I came across this when trying to build a website that takes advantage of sub domains in a MVC project.
You can route subdomains in MVC to a particular controller, and specific actions.

In order to do this, you must make your website listen directly on the IP Address, and point a wildcard A record for all subdomains.
In IIS 7, under Bindings, add a binding for http or https, set the IP to the dedicated IP for the site, and leave the Host name empty.

In your DNS Server (GoDaddy or Windows DNS Server), add the following A records

Host: @ or (same as parent)
IP address: (your dedicated IP)
Host: *
IP address: (your dedicated IP)
NOTE: Not all DNS Servers have wildcard options

This will make your website listen for any subdomains on your site.

Reference the classes attached below, and add the following routes to your project

_routes.Add("BlogRouteProfile", new DomainRoute("{url}.example.com", "", new { controller = "Blog", action = "ViewBlog", url = "" }));
_routes.Add("BlogLatestPosts", new DomainRoute("{url}.example.com", "latest-posts", new { controller = "Blog", action = "BlogLatestPosts", url = "" }));
_routes.Add("BlogPost1", new DomainRoute("{url}.example.com", "rss", new { controller = "Blog", action = "BlogRss", url = "" }));
_routes.Add("BlogPost3", new DomainRoute("{url}.example.com", "pages/{pageName}", new { controller = "Blog", action = "BlogPageView", url = "" }));

In your controller, you can now define Actions, just as you normally would for a regular route.

public class BlogController : Controller
{
    public ActionResult BlogPageView(string url, string pageName)
    {
        return View();
    }
}

Accessing indesign server from C# via COM

2 min read I’ve done quite a bit of searching on InDesign Server, and according to the people at Adobe, C# isn’t “dynamic” enough for use with their API. But obviously, they were looking at Java documentation mislabeled C# or at some very old books. Anyway, a lot of things in their documentation are misleading, so I will attempt to get you started on the right path to using InDesign Server CS6 from C# via COM objects.

InDesign Server registers it’s COM objects when it starts up, and only makes them available in the context in which it was started up. I have yet to figure out why they do this, or how to get around it, but note that if you’re logged onto the computer with the same user twice and start it from one of them, the second instance can’t access the first, nor can it start its own InDesign instance. This information is very important if you’re trying to access it from a service or from within IIS.

Asuming everything went alright, you can now begin to create your project. You first need to add a COM reference to InDesignServer and then import

using InDesignServer;

Now to create the application and make a few calls.

InDesignServer.Application app;
InDesignServer.Document doc;
try
{
    app = new InDesignServer.Application();
    try
    {
        doc = app.Open(Path.Combine(@"C:temp", "inDesignDoc.indd"),
        InDesignServer.idOpenOptions.idDefault);
        doc.Export(InDesignServer.idExportFormat.idPDFType, Path.Combine(@"C:temp",
        "indesign.pdf"), Type.Missing, false, Type.Missing, false);
        doc.Close();
        doc = null;
    }
    catch {}
}
catch {}

C# Thumbnail

2 min read

using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
public class PhotoRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        requestContext.HttpContext.Response.Clear();
        //Cache the photo in the browser to avoid unnecessary requests.
        HttpCachePolicyBase cache = requestContext.HttpContext.Response.Cache;
        TimeSpan cacheDuration = TimeSpan.FromSeconds(86400);
        cache.SetCacheability(HttpCacheability.Public);
        cache.SetExpires(DateTime.Now.Add(cacheDuration));
        cache.SetMaxAge(cacheDuration);
        cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
        //Get the size and url of the photo
        string photoUrl = requestContext.RouteData.Values["photoUrl"].ToString();
        string size = requestContext.RouteData.Values["size"].ToString();
        //Set the content type of the response
        requestContext.HttpContext.Response.ContentType = GetContentType(photoUrl);
        Image img = null;
        Image source;
        bool resizedFile = false;
        //Check if the photo already exists resized on your HDD
        if (File.Exists(Path.Combine(@"C:MySiteContent", "Photos", size, photoUrl)))
        {
            img = Image.FromFile(Path.Combine(@"C:MySiteContent", "Photos", size, photoUrl));
            resizedFile = true;
        }
        else
        {
            try
            {
                //Try to get the photo from the HDD
                source = Image.FromFile(Path.Combine(@"C:MySiteContentPhotos", photoUrl));
            }
            catch
            {
                //If photo doesn't exist on your HDD, send back the default image placeholder
                source = Image.FromFile(Path.Combine(@"C:MySiteContentPhotos", "default.jpg"));
                resizedFile = true; //Used later so we don't store the placeholder
            }
            // Resize the image to completely fit into the size of the rectangle
            if (size == "thumb")
                img = Thumbnailer.FillImage(Thumbnailer.ResizeImage(source, new Size(119, 88)),
                      new Size(119, 88), Thumbnailer.Anchor.Center);
            // Resize and crop the image to completely fill the rectangle
            else if (size == "small")
                img = Thumbnailer.ResizeCrop(source, new Size(284, 205));
            // Resize the image to have a width of 516px
            else if (size == "large")
                img = Thumbnailer.ResizeImage(source,
                      Thumbnailer.GetNewSize(source.Size, new Size(516, 516),
                      Thumbnailer.ResizeMode.FixedWidth));
            // Default rezise for all images where size wasn't accounted for
            else
                img = Thumbnailer.ResizeImage(source,
                      Thumbnailer.GetNewSize(source.Size, new Size(400, 300),
                      Thumbnailer.ResizeMode.FixedWidth));
        }
        if (img != null)
        {
            if (GetContentType(photoUrl) == "image/png")
            {
                MemoryStream memImg = new MemoryStream();
                EncoderParameter qualityParam = new
                EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 1000L);
                ImageCodecInfo pngCodec = Thumbnailer.getEncoderInfo("image/png");
                EncoderParameters encoderParams = new EncoderParameters(1);
                encoderParams.Param[0] = qualityParam;
                if (!resizedFile)
                {
                    //This is the first time this photo has been viewed at this size, so we'll save
                    //it in a folder named after the size, so we don't have to resize it again later
                    if (!Directory.Exists(Path.Combine(@"C:MySiteContentPhotos", size)))
                        Directory.CreateDirectory(Path.Combine(@"C:MySiteContentPhotos", size));
                    img.Save(Path.Combine(@"C:MySiteContent", "Photos", size, photoUrl),
                    pngCodec, encoderParams);
                }
                img.Save(memImg, pngCodec, encoderParams);
                memImg.WriteTo(requestContext.HttpContext.Response.OutputStream);
                img.Dispose();
            }
            else
            {
                MemoryStream memImg = new MemoryStream();
                EncoderParameter qualityParam = new
                EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100L);
                ImageCodecInfo jpegCodec = Thumbnailer.getEncoderInfo("image/jpeg");
                EncoderParameters encoderParams = new EncoderParameters(1);
                encoderParams.Param[0] = qualityParam;
                if (!resizedFile)
                {
                    if (!Directory.Exists(Path.Combine(@"C:MySiteContent", "Photos", size)))
                        Directory.CreateDirectory(Path.Combine(@"C:MySiteContentPhotos", size));
                    img.Save(Path.Combine(@"C:MySiteContent", "Photos", size, photoUrl),
                    jpegCodec, encoderParams);
                }
                img.Save(memImg, jpegCodec, encoderParams);
                memImg.WriteTo(requestContext.HttpContext.Response.OutputStream);
                img.Dispose();
            }
        }
        requestContext.HttpContext.Response.End();
        return null;
    }
    private static string GetContentType(String path)
    {
        switch (Path.GetExtension(path))
        {
            case ".bmp": return "image/bmp";
            case ".gif": return "image/gif";
            case ".jpg": return "image/jpeg";
            case ".png": return "image/png";
            default: break;
        }
        return "";
    }
}

C# Serializable Dictionary

< 1 min read The Dictionary class included in C# isn’t serializable, so you can use the following Serializable Dictionary whenever you need to serialize your objects

[Serializable]
public class SerializableDictionary : Dictionary, IXmlSerializable, ISerializable
{
  #region Private Properties

  protected XmlSerializer ValueSerializer
  {
    get { return _valueSerializer ?? (_valueSerializer = new XmlSerializer(typeof(TVal))); }
  }

  private XmlSerializer KeySerializer
  { 
    get { return _keySerializer ?? (_keySerializer = new XmlSerializer(typeof(TKey)));}
  }

  #endregion


  #region Private Members

  private XmlSerializer _keySerializer;

  private XmlSerializer _valueSerializer;

  #endregion


  #region Constructors

  public SerializableDictionary()
  {
  }

  public SerializableDictionary(IDictionary dictionary) : base(dictionary) { }

  public SerializableDictionary(IEqualityComparer comparer) : base(comparer) { }

  public SerializableDictionary(int capacity) : base(capacity) { }

  public SerializableDictionary(IDictionary dictionary, IEqualityComparer comparer)
    : base(dictionary, comparer) { }

  public SerializableDictionary(int capacity, IEqualityComparer comparer)
    : base(capacity, comparer) { }

  #endregion


  #region ISerializable Members

  protected SerializableDictionary(SerializationInfo info, StreamingContext context)
  {
    int itemCount = info.GetInt32("itemsCount");

    for (int i = 0; i < itemCount; i++)
    {
      KeyValuePair kvp = (KeyValuePair)info.GetValue(String.Format(CultureInfo.InvariantCulture, "Item{0}", i), typeof(KeyValuePair));
      Add(kvp.Key, kvp.Value);
    }
  }

  void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
  {
    info.AddValue("itemsCount", Count);
    int itemIdx = 0; foreach (KeyValuePair kvp in this)
    {
      info.AddValue(String.Format(CultureInfo.InvariantCulture, "Item{0}", itemIdx), kvp, typeof(KeyValuePair));
      itemIdx++;
    }
  }

  #endregion


  #region IXmlSerializable Members

  void IXmlSerializable.WriteXml(XmlWriter writer)
  {
    foreach (KeyValuePair kvp in this)
    {
      writer.WriteStartElement("item");
      writer.WriteStartElement("key");
      KeySerializer.Serialize(writer, kvp.Key);
      writer.WriteEndElement();
      writer.WriteStartElement("value");
      ValueSerializer.Serialize(writer, kvp.Value);
      writer.WriteEndElement();
      writer.WriteEndElement();
    }
  }

  void IXmlSerializable.ReadXml(XmlReader reader)
  {
    if (reader.IsEmptyElement)
    {
      return;
    }

    // Move past container
    if (reader.NodeType == XmlNodeType.Element && !reader.Read())
      throw new XmlException("Error in De serialization of SerializableDictionary");

    while (reader.NodeType != XmlNodeType.EndElement)
    {
      reader.ReadStartElement("item");
      reader.ReadStartElement("key");
      TKey key = (TKey)KeySerializer.Deserialize(reader);
      reader.ReadEndElement();
      reader.ReadStartElement("value");
      TVal value = (TVal)ValueSerializer.Deserialize(reader);
      reader.ReadEndElement();
      reader.ReadEndElement();
      Add(key, value);
      reader.MoveToContent();
    }

    // Move past container
    if (reader.NodeType == XmlNodeType.EndElement)
    {
      reader.ReadEndElement();
    }
    else
    {
      throw new XmlException("Error in Deserialization of SerializableDictionary");
    }
  }

  System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
  {
    return null;
  }

  #endregion
}

Compiling code on the fly in C#

3 min read Compile and run code created on the fly from a string or file.

Compiler c = new Compiler();
StreamReader reader = new StreamReader(/*Path to my source file, optional*/);
string compilationsource = reader.ReadToEnd(); //read from file or create on-the-fly
CodeContainer result = new CodeContainer();
result.CompiledAssembly = c.Compile(compilationsource);
result.SourceCode = compilationsource;
result.Execute("MyMethod", new object[] { MyClass }); //Send in any parameters you need

A lot more functionality than presented above is possible.

C# CSV files

< 1 min read

CsvConfiguration conf = new CsvConfiguration();
conf.AllowComments = false;
conf.HasHeaderRecord = false;
List list = null;
StreamReader streamReader = new StreamReader(inputFilePath);
CsvReader csvReader = new CsvReader(streamReader, conf);
list = csvReader.GetRecords().ToList();
streamReader.Close();
streamReader.Dispose();

C# Reflection

< 1 min read C# Reflection copy every property of a class to another class with the same properties.

Let’s say you have to copy all the values of the properties of a class to another (maybe larger) class, but there’s no inheritance between them.
You can achieve this using reflection very simply.

foreach (var prop in item.GetType().GetProperties())
{
    var p2 = outputModel.GetType().GetProperty(prop.Name);
    p2.SetValue(outputModel, prop.GetValue(item, null), null);
}

MVC Execute code on each controller method

< 1 min read The “OnActionExecuting” method is fired before every Action in a MVC controller. You can use this method to set and retrieve variables that are useful throughout your session, such as the person’s name, their profile photo, etc.
The following is an example implementation of this method

public class HomeController : Controller
{
    protected override void OnActionExecuting(ActionExecutingContext ctx)
    {
        base.OnActionExecuting(ctx);
        using (Repository rep = new Repository())
        {
            if (Request.IsAuthenticated)
            {
                var profile = rep.GetProfileByID((Guid)Membership.GetUser().ProviderUserKey);
                ViewBag.Name = profile.DisplayName;
            }
        }
    }
    public ActionResult Index()
    {
        //your code
        return View();
    }
    //rest of your methods
}