Daniel Little: Coding Blog

A blog about the web and technology [javascript, Mvc, Asp.net, C#] by Daniel [Lavinski]
RSS
04/29 2013

Testing emails in .NET

Testing emails can sometimes be a bit challenging. smtp4dev is a small program that intercepts all received emails so you can quickly send and view emails from any application that uses it as the SMTP server.

For a .NET application just add this to the config file.

<mailSettings>
    <smtp>
        <network host="localhost"/>
    </smtp>
</mailSettings>

Now all emails that the application sends will appear for your viewing pleasure in the email list (pictured below).

Comments
04/20 2013

Loading Settings From web.config

It’s always a good idea to be as consistent as possible when you’re writing code. So when you’re using settings from a configuration file it’s a good idea to avoid sprinkling ConfigurationManager.AppSettings["MySetting"] around the codebase, especially if you’ve making multiple calls to it.

A great way to provide consistency and to remove this duplication is to create a settings class either one static global one or multiple instance classes which I’ll then manage with dependency injection. Then I load all the settings from configuration into that class on start up.

I’ve also written a little library that makes use of reflection to make this even easier.

Once my settings are in my config file

<?xml version="1.0" encoding="utf-8" ?>
<configuration>   
    <appSettings>
        <add key="Domain" value="example.com" />
        <add key="PagingSize" value="30" />
        <add key="Invalid.C#.Identifier" value="test" />
    </appSettings>
</configuration>

I make a static or instance class depending on my needs. For simple applications with only a few settings one static class is fine.

private static class Settings
{
    public string Domain { get; set; }

    public int PagingSize { get; set; }

    [Named("Invalid.C#.Identifier")]
    public string ICID { get; set; }

}

Then using my library call either Inflate.Static or Inflate.Instance and the cool thing is I can use any key value source.

using Fire.Configuration;

Inflate.Static( typeof(Settings), x => ConfigurationManager.AppSettings[x] );


var settings = new SpecificSettings();

Inflate.Instance( settings, x => ConfigurationManager.AppSettings[x] );

All the code for this is in bitbucket at https://bitbucket.org/Lavinski/fire

There is even a nuget package http://nuget.org/packages/Fire/

Install-Package Fire
Comments
04/10 2013

Wildcards hostname in your hosts file

If you’ve ever wanted to setup a wildcard entry in your hosts file so you don’t have to add an entry for every IIS binding you’ll be happy to know there is a way.

The trick however is not to use the hosts file but a local DNS proxy instead. Acrylic DNS is a free and open source which you can download here. You use it in much the same way you would use a hosts file.

Stackoverflow has a great answer detailing how to set it up:

Configuring Acrylic DNS Proxy

To configure Acrylic DNS Proxy, install it from the above link then go to:

  1. Start
  2. Programs
  3. Acrilic DNS Proxy
  4. Config
  5. Edit Custom Hosts File

Add the folowing lines on the end of the file:

127.0.0.1   *.localhost
127.0.0.1   *.local

Restart the Acrilic DNS Proxy service:

  1. Start
  2. Programs
  3. Acrilic DNS Proxy
  4. Config
  5. Restart Acrilic Service

You will also need to adjust your DNS setting in you network interface settings:

  1. Start
  2. Control Panel
  3. Network and Internet
  4. Network Connections
  5. Local Area Connection Properties
  6. TCP/IPv4

Set “Use the following DNS server address”:

Preferred DNS Server: 127.0.0.1
Comments
03/20 2013

Multiple https bindings in IIS7 for developers

When working with websites that require https (SSL) developers always ending up facing the problem: Why can’t you use hostnames with https. This is because hostname is encrypted so IIS needs to establish the SSL connection before it can even read the hostname.

However we can get around this problem by making use of a wildcard certificate. Then it won’t matter what the hostname is and we can happily use SSL on all our internal dev sites.

You can’t actually use IIS to setup a wildcard certificate so I’ll be using a bit of Powershell to move things along.

The first step is to create the self signed certificate. Any clients will also have to trust this certificate.

$cert = New-SelfSignedCertificate -DnsName "*.company.internal" -CertStoreLocation cert:\LocalMachine\My
Export-Certificate -Cert $cert -FilePath "company.internal.cer"

$password = ConvertTo-SecureString -String "SecretHeHe" -Force –AsPlainText
Export-PfxCertificate -Cert $cert -FilePath "company.internal.pfx" -Password $password

Next add the bindings to IIS, this script will add a http and https binding for each combination of site and environment.

$sites = @(
    "website"
)

$envs = @(
    "test",
    "stage"
)

Import-Module WebAdministration
foreach ($name in $sites) {

    foreach ($env in $envs) {
        $name = "$name ($env)"

        $siteName = "$name ($env)"
        New-WebBinding -Name $siteName -Port 80 -Protocol http -HostHeader "$env.$name.company.internal"
        New-WebBinding -Name $siteName -Port 443 -Protocol https -HostHeader "$env.$name.company.internal"
    }
}

Just one thing left, setup IIS to use the certificate. To do that open IIS and import the certificate. Then select the open one of the https bindings and select the certificate (it won’t matter which one, any site on that port will use it).

Comments
03/08 2013

Properties Visual Studio passes to MSBuild

It always takes me ages to kind what properties Visual Studio makes available to the MSBuild project files so here’s the full set.

$(RemoteMachine) 
 
Set to the value of the Remote Machine property on the Debug property page. See Changing Project Settings for a C/C++ Debug Configuration for more information.
 

$(Configuration) 
 
The name of the current project configuration (for example, "Debug").
 

$(Platform) 
 
The name of current project platform (for example, "Win32").
 

$(ParentName) 
 
(Deprecated.) Name of the item containing this project item. This will be the parent folder name, or project name.
 

$(RootNameSpace) 
 
The namespace, if any, containing the application.
 

$(IntDir) 
 
Path to the directory specified for intermediate files relative to the project directory. This path should have a trailing slash. This resolves to the value for the Intermediate Directory property.
 

$(OutDir) 
 
Path to the output file directory, relative to the project directory. This path should have a trailing slash. This resolves to the value for the Output Directory property.
 

$(DevEnvDir) 
 
The installation directory of Visual Studio 2010 (defined as drive + path); includes the trailing backslash '\'.
 

$(InputDir) 
 
(Deprecated; migrated.) The directory of the input file (defined as drive + path); includes the trailing backslash '\'. If the project is the input, then this macro is equivalent to $(ProjectDir).
 

$(InputPath) 
 
(Deprecated; migrated.) The absolute path name of the input file (defined as drive + path + base name + file extension). If the project is the input, then this macro is equivalent to $(ProjectPath).
 

$(InputName) 
 
(Deprecated; migrated.) The base name of the input file. If the project is the input, then this macro is equivalent to $(ProjectName).
 

$(InputFileName) 
 
(Deprecated; migrated.) The file name of the input file (defined as base name + file extension). If the project is the input, then this macro is equivalent to $(ProjectFileName).
 

$(InputExt) 
 
(Deprecated; migrated.) The file extension of the input file. It includes the '.' before the file extension. If the project is the input, then this macro is equivalent to $(ProjectExt).
 

$(ProjectDir) 
 
The directory of the project (defined as drive + path); includes the trailing backslash '\'.
 

$(ProjectPath) 
 
The absolute path name of the project (defined as drive + path + base name + file extension).
 

$(ProjectName) 
 
The base name of the project.
 

$(ProjectFileName) 
 
The file name of the project (defined as base name + file extension).
 

$(ProjectExt) 
 
The file extension of the project. It includes the '.' before the file extension.
 

$(SolutionDir) 
 
The directory of the solution (defined as drive + path); includes the trailing backslash '\'.
 

$(SolutionPath) 
 
The absolute path name of the solution (defined as drive + path + base name + file extension).
 

$(SolutionName) 
 
The base name of the solution.
 

$(SolutionFileName) 
 
The file name of the solution (defined as base name + file extension).
 

$(SolutionExt) 
 
The file extension of the solution. It includes the '.' before the file extension.
 

$(TargetDir) 
 
The directory of the primary output file for the build (defined as drive + path); includes the trailing backslash '\'.
 

$(TargetPath) 
 
The absolute path name of the primary output file for the build (defined as drive + path + base name + file extension).
 

$(TargetName) 
 
The base name of the primary output file for the build.
 

$(TargetFileName) 
 
The file name of the primary output file for the build (defined as base name + file extension).
 

$(TargetExt) 
 
The file extension of the primary output file for the build. It includes the '.' before the file extension.
 

$(VSInstallDir) 
 
The directory into which you installed Visual Studio 2010. 

This property contains the version of the targeted Visual Studio, which might be different that the host Visual Studio. For example, when building with $(PlatformToolset) = v90, $(VSInstallDir) contains the path to the Visual Studio 2008 installation.
 

$(VCInstallDir) 
 
The directory into which you installed Visual C++ 2010. 

This property contains the version of the targeted Visual C++, which might be different that the host Visual Studio. For example, when building with $(PlatformToolset) = v90, $(VCInstallDir) contains the path to the Visual C++ 2008 installation.
 

$(FrameworkDir) 
 
The directory into which the .NET Framework was installed.
 

$(FrameworkVersion) 
 
The version of the .NET Framework used by Visual Studio. Combined with $(FrameworkDir), the full path to the version of the .NET Framework use by Visual Studio.
 

$(FrameworkSDKDir) 
 
The directory into which you installed the .NET Framework. The .NET Framework could have been installed as part of Visual Studio 2010 or separately.
 

$(WebDeployPath) 
 
The relative path from the web deployment root to where the project outputs belong. Returns the same value as RelativePath.
 

$(WebDeployRoot) 
 
The absolute path to the location of . For example, c:\inetpub\wwwroot.
 

$(SafeParentName) 
 
(Deprecated.) The name of the immediate parent in valid name format. For example, a form is the parent of a .resx file.
 

$(SafeInputName) 
 
(Deprecated.) The name of the file as a valid class name, minus file extension.
 

$(SafeRootNamespace) 
 
(Deprecated.) The namespace name in which the project wizards will add code. This namespace name will only contain characters that would be permitted in a valid C++ identifier.
 

$(FxCopDir) 
 
The path to the fxcop.cmd file. The fxcop.cmd file is not installed with all Visual C++ editions.

Source: http://msdn.microsoft.com/en-us/library/c02as0cs.aspx

Comments
02/14 2013

Switch from ‘Entity Framework Linq’ to ‘Linq to Objects’ with AsEnumerable

Most people know what when writing a Linq query with Entity Framework that until that query is enumerated it won’t call out to the database. Sometimes it’s necessary to do some more work with the results such as use a method as part of the projection.

var result =
    from people in Context.People
    where people.DateOfBirth < twentyYearsAgo
    select people;

function GetAge(DateTime dateOfBirth) { ...

This is where AsEnumerable comes in. This generic function allows you to switch from the IQueryable source to IEnumerable which will use Linq to Objects. Using AsEnumerable instead of ToList allows us to still delay the execution of the query until it’s needed.

var query =
    from people in Context.People
    where people.DateOfBirth < twentyYearsAgo
    select people;

var result =
    from people in query.AsEnumerable()
    select GetAge(people.DateOfBirth);

You could do the same thing by casting to the IEnumerable type but for anonymous objects you’ll find you need to use AsEnumerable anyway to infer the type from the query.

Comments
02/01 2013

Using ProviderName to get the database connection

When setting your connection string in a .NET config file you can make use of the providerName attribute by using DbProviderFactories.GetFactory and passing it the provider name.

var connectionStringSettings = ConfigurationManager.ConnectionStrings["DefaultConnection"];
connection = DbProviderFactories.GetFactory(connectionStringSettings.ProviderName).CreateConnection();
connection.ConnectionString = connectionStringSettings.ConnectionString;
connection.Open();
Comments
01/21 2013

Entity Framework and Foreign key constraint may cause cycles or multiple cascade paths

Today I ran into the Foreign key constraint may cause cycles or multiple cascade paths issue for the first time. The first thing to note is the error isn’t actually from Entity Framework it’s from SQL Server.

Introducing FOREIGN KEY constraint 'ConstraintName' on table 'TableName' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

I was however using EF5 Code First so I fist needed to figure out why my model was giving me back this error. The error message itself pointed me to the Schema table referring to the Project table. Note my schema looks a bit like this:

Project { Id, Name }
Schema { Id, ProjectId, ... }
Node { Id, ProjectId, ... }

As you can see there are two relationships to the Projects table, which is usually fine. The issue comes from the fact that EF using the OneToManyCascadeDeleteConvention convention my default. Which was not what I wanted for these two relationships.

My EF model takes the convention and attribute approach, I try to avoid the fluent API to keep everything in the one place. However there is currently no attribute to turn off cascade delete.

Here is how to do it using the fluent API:

internal sealed class SchemaConfiguration : EntityTypeConfiguration<Schema>
{

    public SchemaConfiguration()
    {
        this
            .HasRequired(x => x.Project)
            .WithMany()
            .WillCascadeOnDelete(false);
    }
}

/// <summary>
/// Model Creating Event Handler.
/// </summary>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new NodeConfiguration());
}

Need more help

Comments
01/11 2013

Ninject and Singletons in the WebAPI with Scopes

The new Activation Blocks in Ninject are great for automatically resolving dependencies in the request scope. However they suffer from one flaw which is they don’t respect Constant or Singletons in fact they ignore the scope completely!

In my application I needed a reference my dependency injection container in one of my objects. This would end up throwing Error loading Ninject component ICache at the end of the request because now I had two kernels. Not good at all however I still had hope.

Luckily there is one type of binding the ActivationBlock can’t ignore. The ToMethod binding. So now I can make a small ScopedResolver class which I can then inject into my class instead.

Binding

kernel.Bind<ScopedResolver>().ToMethod(x => {
    return new ScopedResolver((IActivationBlock)x.GetScope());
});

ScopedResolver

public class ScopedResolver
{
    IActivationBlock resolver;

    public ScopedResolver(IActivationBlock resolver)
    {
        this.resolver = resolver;
    }

    public T TryGet<T>()
    {
        return resolver.TryGet<T>();
    }

}
Comments
07/25 2012

SharePoint WebConfig Modifications

Example for adding or removing a webconfig modification in SharePoint 2010.

private void UpdateWebConfig(string name, string path, string owner, SPWebConfigModification.SPWebConfigModificationType type, string value, SPWebApplication app, bool removeModification)
{

    if (removeModification) {
        var removals = app.WebConfigModifications.Where(item => item.Name == name).ToList();

        foreach (var item in removals) {
            app.WebConfigModifications.Remove(item);
        }

    } else {

        SPWebConfigModification modification = new SPWebConfigModification();
        modification.Name = name;
        modification.Path = path;
        modification.Owner = owner;
        modification.Sequence = 0;
        modification.Type = type;
        modification.Value = value;

        app.WebConfigModifications.Add(modification);
    }

    app.Update();
    app.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
}

Usage:

UpdateWebConfig(
    "add[@name='handlerName']",
    "configuration/system.webServer/handlers",
    "FeatureName",
    SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode,
    "<add name='handlerName' verb='*' path='service.axd' type='Namespace, Assembily, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0x0xx00000x00xx0' />",
    webApplication,
    false   
);
Comments
1 of 3 Next