Deploying ASP MVC3 to shared hosting isn't always sunshine and lollipops. Though my beloved hosting company Arvixe is pretty cutting edge, it didn't have (and I didn't request) that they hop on MVC3 or its beta. Regardless, I went to deploy an MVC3 app and it blew up because of a variety of dependencies. As discovered in early MVC2 work, you have to set some assemblies to 'copy local' to get it to work on shared hosting.
The list of assemblies to set to copy local = true is:
- Microsoft.Web.Infrastructure
- System.Web.Helpers
- System.Web.Mvc
- System.Web.Razor
- System.Web.Webpages
- System.Web.WebPages.Deployment
- System.Web.Webpages.Razor
Drew Miller ( blog | twitter ) has a great breakdown on this : Click for Breakdown
I suppose the subject pulls no punches with what we're going to do. We are going to have simple form with a file upload and a button. Once we hit the button, whatever file was selected is going to ride the magic internet carpet and appear in an Amazon S3 bucket.
WebForm:
<asp:FileUpload ID="FileUpload1" runat="server" /><asp:Button ID="Button1" runat="server" Text="Send it dude" onclick="Button1_Click" />
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
Code behind:
protected void Button1_Click(object sender, EventArgs e)
{
string result = Program.GetServiceOutput();
Label1.Text = result;
}
Class file for AWSCalls;
using Amazon; // these are part of the AWSSDK.dll that you add to the project
using Amazon.S3;
using Amazon.S3.Model;
....
public static void SendFileToS3(string filename, Stream ImgStream)
{
string accessKey = "Access Key here!";
string secretAccessKey = "Secret Key goes here!";
string bucketName = "Bucket Name goes Here!";
string keyName = filename;
AmazonS3 client = Amazon.AWSClientFactory.CreateAmazonS3Client(accessKey, secretAccessKey);
PutObjectRequest request = new PutObjectRequest();
request.WithInputStream(ImgStream);
request.WithBucketName(bucketName);
request.WithKey(keyName);
request.StorageClass = S3StorageClass.ReducedRedundancy; //set storage to reduced redundancy
client.PutObject(request);
}
So there you have it! We take a file, throw it into a page.... and that page does a heave-ho to Amazon S3. It also goes the extra step to set it to ReducedRedundancy to save you a pretty penny.
With 'high availability' being a nicely stressed buzzword coupled with issues in the 'cloud', an issue can arise of what to do about your jquery references in the event that where you are hosting it is down? I won't dig into the reasons for using a CDN for jquery but will plug the usual - It will typically be cached by the time your site is hit if you use Google or Microsoft CDN as well as will likely be faster to load in general as a browser will thread out to load it (as opposed to if it is hosted under the current domain). I also have some links at the bottom for further reading on it. So, on to the failover.... and it is quite easy really since 1.4 :
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.4/jquery-ui.js"></script>
<script type="text/javascript">
if (typeof jQuery == 'undefined')
{
document.write(unescape("%3Cscript src='http://ajax.microsoft.com/ajax/jquery/jquery-1.4.4.min.js' type='text/javascript'%3E%3C/script%3E"));
document.write(unescape("%3Cscript src='http://ajax.microsoft.com/ajax/jquery/jqueryui-1.8.4.min.js' type='text/javascript'%3E%3C/script%3E"));
}
</script>
http://happyworm.com/blog/2010/01/28/a-simple-and-robust-cdn-failover-for-jquery-14-in-one-line/
http://weblogs.asp.net/jgalloway/archive/2010/01/21/using-cdn-hosted-jquery-with-a-local-fall-back-copy.aspx
http://stackoverflow.com/questions/1447184/microsoft-cdn-for-jquery-or-google-cdn
Trust me when I say I'm no stranger to abusing repeat methods in code behinds... however, it does reach a point where something has to give. When you reach that point, your solution is a 'helper' class.
Below is a quick/basic example of how to get started with helper classes.
In my solution, I created a folder called 'Helpers' and added a new class object called 'StringManip'.
Once that was completed, I added a few methods like:
public static string UpperString(string val)
{ return val.ToUpper(); }
In my code behind, I reference the class through a using statement:
using HelperClass.Helpers;
And then I can call the methods:
lbl_aspnet.Text = StringManip.UpperString(lbl_aspnet.Text);
If the above isn't enough to get you rolling.... then download the demo solution by Clicking Here
It seems like every place I go, companies are dropping an incredible amount money on an overpriced Verisign certificate which essentially proves nothing. I am not going to tirade on Verisign's prices, product, or just the general crappy nature of the company... but I will list alternatives:
The current ones I use and it rocks:
For http SSL I use: Start Com
For other services/protocols I tend to use:
CA Cert Org
I don't think cacert is any better/worse than startcom, I just mostly use cacert for internal stuff out of habit and I generally like the group.
Equally excellent CA's that are not free:
Dynadot.com
Rapidssl.com
Geotrust.com
So I've been working on a step by step on ELMAH and how to set it up for F5Compliant ... when today I came across Scott Mitchels tutorial on ASP.NET
http://www.asp.net/learn/hosting/tutorial-14-cs.aspx
One thing he seems to have left out is using SQLite. Since moving from my in house servers to online hosting, I am still often surprised by the DB limitations faced. Before I went with a hosted solution, it just felt commonplace to spin up a new DB for X project and go. With many shared hosting plans, one becomes a little miserly with their DB's as more DB's with the hosting plan incur more cost. SQLite seems to fill that void quite nicely. One thing to be aware of though is that SQLite requires full trust in order to run, so you will probably need to contact your hosting provider for them to set the permissions. I use SoftSysHosting and their team takes care of this incredibly fast which is nice.
On the main F5 page, I needed a way to adjust the CSS properties on the menu based on what is in a content page. Enter ASP.NET literals. Essentially a literal lives up to its name... it allows you to define literal html.
So, in the master I have:
<asp:Literal ID="lit_About" runat=server Text='<li><a href="About.aspx" title="About">About</a></li>' />
How do I manipulate that to trigger the proper CSS class you ask? By doing this in the code behind on the content page:
protected void Page_Load(object sender, EventArgs e)
{
Literal menucontrol = Page.Master.FindControl("lit_About") as Literal;
menucontrol.Text = "<li class='active'><a href='About.aspx' title='About'>About</a></li>";
}
Comments of late