Upload Files In RAZOR With jQuery Uploadify Plugin

A Few months back I wrote a post on how to use jQuery plugin Uploadify to upload single/multiple files without postback in ASP.NET. Now a few days back I was working on a demo project which is on MVC 3 Razor and I use the same plugin without any problems. But the files that are being uploaded are uploaded to the root folder instead of the folder I specified to upload the files. After a lot of head scratching, I was unable to find the actual problem as why the file was not being uploaded to the folder of ...
Shout it
Telerik – RadControls for WPF

Not in the Valley. Not funded. Not an overnight success. – with Joshua Baer

Joshua Baer isn't in Silicon Valley -- he prefers Austin. He didn't take outside funding -- his customers funded him. He wasn't an overnight success -- it took him 10 years. But...

FreeNAS Setup Part 1 – Installation and Initial Configuration

When Microsoft revealed that they planned on removing the wildly popular feature "Drive Extender" from the impending release of Windows Home Server 2011 (at the time it was code-named "Vail").  The reaction that ensued may very well be one of the biggest rejections to a Microsoft decision that I've seen to date, with many people going so far as saying that they would stop using Windows Home Server (WHS) if Drive Extender was indeed removed.  Honestly, I wasn't able to understand what the big deal about Drive Extenders removal was at this point because the finished product wasn't even out and to me, Microsoft is helping the economy by allowing 3rd Party vendors to fill in the gap left by Drive Extender.  As we all know, Microsoft, being true to form, did not hear the cries of it's loyal customers and went ahead with the changes anyways.  And while I still consider myself a loyal WHS fan and remain faithful that WHS 2011 will still remain on top in the "Media Server" arena for some time to come, I thought some of you might be interested in alternative options to WHS if you just can't get past the Drive Extender issue.

Enter FreeNAS

FreeNAS is a great solution for a Home Media Streaming Server NAS  combination and our very own John Reyes has written a complete guide to getting  yourself up and running with a FreeNAS server.  Beyond being an extremely robust NAS / media streamer solution, a great thing about FreeNAS is...it's Free!  Yes folks, you too can own your very own FreeNAS server by simply scavenging those parts from your old gaming rig, download the software, and follow John's step-by-step instructions!  Before you know it you'll have a home media server that in many ways rivals WHS 2011.

 

Will FreeNAS be able to fill the shoes of WHS 2011, or will WHS 2011 continue to thrive even without Drive Extender.  At least you have options!

Enjoy!

Tom 

NuGet Package of the Week #2 – MvcMailer sends mails with ASP.NET MVC Razor Views and Scaffolding

Have you implemented the NuGet Action Plan? Get on it, it'll take only 5 minutes: NuGet Action Plan - Upgrade to 1.1, Setup Automatic Updates, Get NuGet Package Explorer.

The Backstory: I was thinking since the NuGet .NET package management site is starting to fill up that I should start looking for gems (no pun intended) in there. You know, really useful stuff that folks might otherwise not find. I'll look for mostly open source projects, ones I think are really useful. I'll look at how they built their NuGet packages, if there's anything interesting about the way the designed the out of the box experience (and anything they could do to make it better) as well as what the package itself does.

MvcMailer sends mails with ASP.NET MVC Razor Views and Scaffolding

I just love the idea behind this NuGet package. This is effectively a port/reimagining of the Rails ActionMailer with an ASP.NET twist. It's wonderful for a number of reasons.

First, because (and this is an ingredient for all great pieces of software) we've all had this idea but never implemented it! I've been talking about writing this for six months. Of course, Talk is Cheap, Show Me The Code. I'm thrilled I never wrote it because it wouldn't have been this good.

Second, because the way that the author, Sohan, has implemented this really builds on existing technologies in a very "LEGO" way. Great open source apps often build on other great ones cleanly. He's really avoided duplication by separating concerns and focused on just the new functionality MvcMailer adds.

clip_image002

There comes a time in every project when you need to email a user. Traditionally it (almost always sucks). As Sohan points out, it usually looks like this:

StringBuilder mailBody = new StringBuilder();
mailBody.Append("<html><head><style type=\"text\css\">...</style></head>");
mailBody.Append("<body>")
mailBody.AppendFormat("Hi {0}<br/>", user.FirstName);
...
... XX lines of similar Appending unless it its done!
...
mailBody.Append("</body></html>");

If you're special, maybe you put a template text file somewhere and do a .Replace("{token}") but it still sucks.

Additionally, you want the ability to send not only rich HTML email but also plain text (or more likely, multipart) emails. Fortunately, with ASP.NET MVC we are already creating nice HTML template for output the user, just over HTTP. Why can't we do the same with email?

How MvcMailer Works and Why It's Cool

The MvcMailer NuGet Package is clever on a number of levels, truly. I mention this so that we (you and I, Dear Reader) might learn together. It's full of little gems and clever best-practices that we can use in our own NuGet packages.

In his install.ps1 - that's the PowerShell script that runs when you install a package - he has a little ReadMe in the form of a series of Write-Host commands. This is a simple, clever and effective way to get my attention. And it did!

Write-Host ---------------------------READ ME---------------------------------------------------
Write-Host
Write-Host Your default Mailer Scaffolder is set to $mailerScaffolder
Write-Host
Write-Host You can generate your Mailers and Views using the following Scaffolder Command
Write-Host
Write-Host "PM> Scaffold Mailer UserMailer Welcome,GoodBye"
Write-Host
Write-Host Edit the smtp configuration at web.config file before you send an email
Write-Host
Write-Host You can find more at: https://github.com/smsohan/MvcMailer/wiki/MvcMailer-Step-by-Step-Guide
Write-Host
Write-Host -------------------------------------------------------------------------------------

He also makes use of the version specific lib folders. There's a 40 folder underneath lib. That's because this package only works on .NET 4 and NuGet knows it because of the named lib folders. You can target Silverlight, etc with these folders.

The MvcMailer makes use of Steve Sanderson's excellent (and prescient) scaffolding system. Steve took the basic MvcScaffolding prototype and turned it into two packages, the MvcScaffolding one, and a base package called T4Scaffolding that isn't MVC specific. You can Get-Scaffolder and Set-Scaffolder and generate whatever you like, and he does.

If I type Get-Scaffolder, I see where MvcMailer has plugged in:

PM> Get-Scaffolder

Name Description Package
---- ----------- -------
Mailer.Aspx Scaffold ... MvcMailer 1.1
Mailer.Razor Scaffold ... MvcMailer 1.1
T4Scaffolding.CustomScaffolder Creates a... T4Scaffolding 0.9.7
T4Scaffolding.CustomTemplate Allows yo... T4Scaffolding 0.9.7
T4Scaffolding.EFDbContext Makes an ... T4Scaffolding 0.9.7
T4Scaffolding.EFRepository Creates a... T4Scaffolding 0.9.7

Now I can Scaffold out a Welcome and GoodBye mailer (or whatever, like Change Password, etc.

PM> Scaffold Mailer UserMailer Welcome,GoodBye
Added MvcMailer output 'Mailers\IUserMailer.cs'
Added MvcMailer output 'Mailers\UserMailer.cs'
Added MyScaffolder output 'Views\UserMailer\_Layout.cshtml'
Added MyScaffolder output 'Views\UserMailer\Welcome.cshtml'
Added MyScaffolder output 'Views\UserMailer\GoodBye.cshtml'

Ah, but I need both HTML and Text versions, so I'll do  it again -WithText:

PM> Scaffold Mailer UserMailer Welcome,GoodBye -WithText
Mailers\IUserMailer.cs already exists! Skipping...
Mailers\UserMailer.cs already exists! Skipping...
Views\UserMailer\_Layout.cshtml already exists! Skipping...
Views\UserMailer\Welcome.cshtml already exists! Skipping...
Views\UserMailer\GoodBye.cshtml already exists! Skipping...
Added MyScaffolder output 'Views\UserMailer\_Layout.text.cshtml' Added MyScaffolder output 'Views\UserMailer\Welcome.text.cshtml' Added MyScaffolder output 'Views\UserMailer\GoodBye.text.cshtml'

Very cool. Now I've got templates nicely organized as if they were Views for both HTML and Text for Welcome and GoodBye. I can take the generated code for my UserMail and extend it. For example, if I want to send some data to my mailer (I likely do) I'll change it to look like this:

public virtual MailMessage Welcome(string firstName, string email)
{
var mailMessage = new MailMessage{Subject = "Welcome"};

mailMessage.To.Add(email);
ViewBag.FirstName = firstName;
PopulateBody(mailMessage, viewName: "Welcome");

return mailMessage;
}

Then I can call this from a regular controller in response to an action. This could certainly be done on one line if you like that.

var mailer = new UserMailer();
var msg = mailer.Welcome(firstName: "Scott", email: "scottha@microsoft.com");
msg.Send();

I like named parameters.

NOTE: The Send() method is an extension method, and you need to make sure you have using Mvc.Mailer in your namespaces. This slowed me down a smidge until I figured it out.

Now, I don't want to setup my SMTP mail server, so I'll change the web.config to write emails out to a temp folder:

<system.net>
<mailSettings>
<!-- Method#1: Configure smtp server credentials -->
<!--<smtp from="some-email@gmail.com">
<network enableSsl="true" host="smtp.gmail.com" port="587" userName="some-email@gmail.com" password="valid-password" />
</smtp>-->
<!-- Method#2: Dump emails to a local directory -->
<smtp from="some-email@gmail.com" deliveryMethod="SpecifiedPickupDirectory">
<network host="localhost" />
<specifiedPickupDirectory pickupDirectoryLocation="c:\temp\"/>
</smtp>
</mailSettings>
</system.net>

When I execute /Home/SendWelcomeEmail, I've got a nice email sitting in my temp folder (note the Outlook Icon):

MvcMailerTempEmail

And here's my email. Note the user data passed in, in the form of my email and first name.

Welcome - Message (HTML)  (32)

I just love that this package exists and that it's such a great example of open source building on existing projects and plugging into existing conventions cleanly. It's also a testament to Steve's extensibility points  in T4Scaffolding and Andrew Nurse and friends in Razor as neither team had an idea this project was happening! Kudos to Sohan for this useful and polished project. I hope the community appreciates his work and supports him with bug fixes, improvements and more! Thank him in the comments and follow his project on GitHub!

One Other Clever Thing

Here's one other clever thing that Sohan does (borrowing from Steve Sanderson) He has to determine what your preferred View Engine is, so he counts the number of ASPX files and the number of Razor files and figures the one you have the most of is your preference.

### Copied from MvcScaffolding
function CountSolutionFilesByExtension($extension) {
$files = (Get-Project).DTE.Solution `
| ?{ $_.FileName } `
| %{ [System.IO.Path]::GetDirectoryName($_.FileName) } `
| %{ [System.IO.Directory]::EnumerateFiles($_, "*." + $extension, [System.IO.SearchOption]::AllDirectories) }
($files | Measure-Object).Count
}

function InferPreferredViewEngine() {
# Assume you want Razor except if you already have some ASPX views and no Razor ones
if ((CountSolutionFilesByExtension aspx) -eq 0) { return "razor" }
if (((CountSolutionFilesByExtension cshtml) -gt 0) -or ((CountSolutionFilesByExtension vbhtml) -gt 0)) { return "razor" }
return "aspx"
}

# Infer which view engine you're using based on the files in your project
### End copied

$mailerScaffolder = if ([string](InferPreferredViewEngine) -eq 'aspx') { "Mailer.Aspx" } else { "Mailer.Razor" }
Set-DefaultScaffolder -Name Mailer -Scaffolder $mailerScaffolder -SolutionWide -DoNotOverwriteExistingSetting

Very cool.

Related Links



© 2011 Scott Hanselman. All rights reserved.

Free Video Training: ASP.NET MVC 3 Features – Scott Guthrie’s Blog

A few weeks ago I blogged about a great ASP.NET MVC 3 video training course from Pluralsight that was made available for free for 48 hours for people to watch.  The feedback from the people that had a chance to watch it was really fantastic.  We also received feedback from people who really wanted to watch it – but unfortunately weren’t able to within the 48 hour window. The good news is that we’ve worked with Pluralsight to make the course available for free again until March 18th.  You can watch any o...
Shout it
Telerik – RadControls for WPF

HTML5-MVC application using VS2010 SP1 – IBloggable – implemented

This is my first attempt at creating HTML5 pages. VS 2010 allows working with HTML5 now (you just need to make a small change after installing SP1). So my Razor view is now a HTML5 page. I call this application - 5Commerce – (an over-simplified) HTML5 ECommerce site. So here’s the flow of the application:home page renders user enters first and last name, chooses a product and the quantity can enter additional instructions for the order place the order user is then taken to another page showing the order...
Shout it
Only $4.95/month – Windows 2008/ASP.NET 4 Hosting!

Using AppHarbor for Continuous Integration

I thought it would be interesting to use AppHarbor as a quick way to get some code with tests under a continuous integration environment. Along with this, if I could also use the AppHarbor deployed web site to serve that file, even better!

AppHarbor

What: If you haven't heard about AppHarbor yet, go check it out. They offer Git and Mercurial hosting that will also run unit tests (with various frameworks). You're able to deploy different versions of your site with a single click and they have SQL Server support.

Why: It's free and easy. It runs your tests. It lets you deploy any version of your code. It's getting better each day.

Continuous Integration

What: Why should I describe it when others can do so much better:

Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly. This article is a quick overview of Continuous Integration summarizing the technique and its current usage. - Martin Fowler

Why: Deliver your most current build through a web site by typing "git push AppHarbor master". It wont build your binary unless your tests pass. This means there's no way to push a new downloadable version of your code unless all tests pass; it's just nice and easy.

How to do this?

The code is super simple, you can download the assembly to do this from the application that actually does it. Visit http://cheap-ci.apphb.com.

Some Questions and Thoughts

I don't know if this is useful or not, but I wanted to try it. Let me know what I'm missing or doing wrong. Let me know if there's something to do better. The thought popped in my head the other day, and now that I have a proof of concept, I thought I should share.

Kick It on DotNetKicks.com

Website Speed Part 1: Write More Efficient CSS

Nu.1 in this series on how to speed up web pages on your server focuses on CSS with an 18 point plan on how to be efficient, fast & compliant.

JavaScript Modal Windows – TinyBox2

This update to the TinyBox modal window script brings a ton of new features and still clocks in under 5KB.

Reviewing OSS Project: Whiteboard Chat–setup belongs in the initializer

Originally posted at 3/8/2011

As a reminder, I am reviewing the problems that I found while reviewing the Whiteboard Chat project during one of my NHibernate’s Courses. Here is the method:

[Transaction]
[Authorize]
[HttpPost]
public ActionResult GetLatestPost(int boardId, string lastPost)
{
    DateTime lastPostDateTime = DateTime.Parse(lastPost);
    
    IList<Post> posts = 
        _postRepository
        .FindAll(new GetPostLastestForBoardById(lastPostDateTime, boardId))
        .OrderBy(x=>x.Id).ToList();

    //update the latest known post
    string lastKnownPost = posts.Count > 0 ? 
        posts.Max(x => x.Time).ToString()
        : lastPost; //no updates
    
    Mapper.CreateMap<Post, PostViewModel>()
        .ForMember(dest => dest.Time, opt => opt.MapFrom(src => src.Time.ToString()))
        .ForMember(dest => dest.Owner, opt => opt.MapFrom(src => src.Owner.Name));

    UpdatePostViewModel update = new UpdatePostViewModel();
    update.Time = lastKnownPost; 
    Mapper.Map(posts, update.Posts);

    return Json(update);
}

In this post, I want to focus on the usage of AutoMapper, in the form of Mapper.CreateMap() call.

It was fairly confusing to figure out why that was going on there. In fact, since I am not a regular user of AutoMapper, I assumed that this was the correct way of doing things, which bothered me. And then I looked deeper, and figured out just how troubling this thing is.

Usage of Mapper.CreateMap is part of the system initialization, in general. Putting it inside the controller method result in quite a few problems…

To start with, we are drastically violating the Single Responsibility Principle, since configuring the Auto Mapper really have very little to do with serving the latest posts.

But it actually gets worse, Auto Mapper assumes that you’ll make those calls at system initialization, and there is no attempt to make sure that those static method calls are thread safe.

In other words, you can only run the code in this action in a single thread. Once you start running it on multiple thread, you are open to race conditions, undefined behavior and plain out weirdness.

On the next post, I’ll focus on the security vulnerability that exists in this method, can you find it?