MVC3 Retrieving the browser Url

Code Snippet
  1. Public Module MyUrlExtensions
  2.     <Extension()> _
  3.     Public Function UrlOriginal(ByVal request As HttpRequestBase) As Uri
  4.         Dim hostHeader As String = request.Headers(“host”)
  5.         Return New Uri(String.Format(“{0}://{1}{2}, request.Url.Scheme, hostHeader, request.RawUrl))
  6.     End Function
  7. End Module

Scaffhold views/controllers within n-tier solutions. EF Code first flavour.

I’ve been struggling for a while this morning, trying to use one of the most popular MVC tools features: the ability to generate a controller with the CRUD (Create, Read, Update, Delete) actions over a model. The generator will create the different views as well. Or better.. it should =) Everything works smoothly when you got one project only within your solution , including models, dal etc.

While if your app is layered into several projects, here’s a couple of things you should keep in mind in order to get the scaffholding working:

  • The project containing the model you want to scaffhold must include the configuration file with the connection string for your context.
  • The web project (from where you will create the scaffholded controller) not only it must have the config file with the connection string. The connectionstrings can’t be in separated config files (configSources)! Or you will end up getting this : The type initializer for ‘System.Data.Entity.Internal.AppConfig’ threw an exception. 

Last thing to keep in mind is to expose the DbSets instead of IDbSets in your DbContext or the code generator will not work. Happy scaffholding to everyone!

Easy Asynch emails in MVC 3

Here’s a workaround if you’re facing issues implementing the Smtp.SendAsync() method. It doesn’t require any change in your actions or controllers (like changing them to be AsycController).

If  you got one, you can implement the below in your service layer. The original code is in Vb.Net, like the project I am working on…sorry . Btw I’ve converted with one of the several tools online.

Code Snippet
public void SendEmail(MailManagerSettings mailManagerSettings, bool isAsynch)
{
    object smtp = new SmtpClient {
        Host = mailManagerSettings.Host,
        Port = mailManagerSettings.Port,
        EnableSsl = mailManagerSettings.EnableSSL,
        DeliveryMethod = mailManagerSettings.DeliveryMethod,
        Credentials = new NetworkCredential(mailManagerSettings.Username, mailManagerSettings.Password)
    };

    TriggerMailDelegate triggerHandler = new TriggerMailDelegate(smtp.Send);
    AsyncCallback sendCompleteCallback = new AsyncCallback(SendEmailCbk);

    // We send an email to each user in the ToAddress list

    foreach ( address in mailManagerSettings.ToAddress) {
        object message = new MailMessage(mailManagerSettings.Username, address) {
            Subject = mailManagerSettings.Subject,
            Body = mailManagerSettings.Body,
            IsBodyHtml = mailManagerSettings.IsBodyHtml
        };

        foreach ( attachment in _attachments) {
            message.Attachments.Add(new Attachment(attachment));
        }
        //Asynch send
        if ((isAsynch)) {
            triggerHandler.BeginInvoke(message, sendCompleteCallback, triggerHandler);
        } else {
            smtp.Send(message);
        }
    }

}

public void AddAttachment(string path)
{
    _attachments.Add(path);
}

private delegate void TriggerMailDelegate(System.Net.Mail.MailMessage message);

private static void SendEmailCbk(IAsyncResult result)
{
    TriggerMailDelegate sendHandler = (TriggerMailDelegate)result.AsyncState;
    //DO SOMETHING WHEN EMAIL IS SENT
    sendHandler.EndInvoke(result);
}

Moq a Vb.net Sub

While mocking a VB method I was getting the following error :

‘Public Function Setup(expression As System.Linq.Expressions.Expression(Of System.Action(Of EmailSender.IMailManager))) As Moq.Language.Flow.ISetup(Of EmailSender.IMailManager)’: Expression does not produce a value

Here’s the moq setup :

mailManager.Setup(Function(x) x.SendEmail(It.IsAny(Of MailManagerSettings))).Verifiable()

Because the SendEmail method is a Sub instead of a Function.

Let's replace the Setup target Function with a Sub and this will complile. (Sub lambda support is quite new though.)

Troubleshooting IIS 7.5 on Window 7

I’ve just installed IIS 7.5 on a machine with Windows 7. Of course the website I deployed didn’t work on the first attempt, here’s a few steps to fix the missing (or wrong) settings on the webserver. Before starting ensure the url you enter on the browser points to the deployed website. Main things to check :

  • The host file under C:\Windows\System32\drivers\etc  should have an entry for the website deployed.

host file

  • Assign the same url to the host name of your website under IIS.

host name
* Ensure you enter the site url including the port, es http://www.dev.mywebsite.com:8099

Once all the correct urls are been set on both iis and the host file, try access the site.

The same website working perfectly within the Visual Studio webserver, now on IIS, returns this error when trying to browse it:

HTTP Error 500.19 – Internal Server Error

Description: The requested page cannot be accessed because the related configuration data for the page is invalid.

Odd because the web.config haven’t changed. To fix it edit the applicationHost.config in the c:\Windows\system32\inetsrv\config folder  by changing the following key values:

  • <section name="handlers" overrideModeDefault="Deny" />
  • <section name="modules" allowDefinition="MachineToApplication" overrideModeDefault="Deny" />
For both the key change from Deny to Allow.
Another error you can get is :
HTTP Error 401.3 – Unauthorized: Access is denied due to an ACL set on the requested resource
Before assigning full persmissions to the user "Everyone" over your folders, check that the anonymous user is enabled for the site:
anonymous user
Even if enabled , check that the anonymous identity is assigned to the App pool instead than a specific user (right click anonymous authentication->Edit->Application Pool Identity).
anonymous application pool
At this point one of the last issues can be not be allowed to browse the site content : HTTP Error 403.14 – Forbidden  The Web server is configured to not list the contents of this directory.
On IIS, go to the Directory Browsing feature (next to the Authentication one) and enable browsing:
enable browsing
If you still can’t reach the website and you got a listing of the files instead of the home page, try registering the framework  , this because IIS have been installed after the framework.