Tuesday, November 30, 2010

What’s New in ASP.NET MVC 2

Since ASP.NET MVC 1 reached its final release in April 2009, the developer community has been hard at work applying it to every conceivable task (and a few inconceivable ones). Through experience, we’ve established best practices, new design patterns, and new libraries and tools to make ASP.NET MVC development more successful.
Microsoft has watched closely and has responded by embedding many of the community’s ideas into ASP.NET MVC 2. Plus, Microsoft noticed that certain common web development tasks were harder than expected in ASP.NET MVC 1, so it has invented new infrastructure to simplify these tasks.

Altogether, the new features in ASP.NET MVC 2 are grouped around the theme of streamlining
“enterprise-grade” web development. Here’s a rundown of what’s new:

• Areas give you a way to split up a large application into smaller sections (e.g., having a public area, an administrative area, and a reporting area). Each area is a separate package of controllers, views, and routing configuration entries, making them convenient to develop independently and even reuse between projects.

• Model metadata and templated view helpers are extensible mechanisms for describing the meaning of your data model objects (e.g., providing humanreadable descriptions of their properties) and then automatically generating sections of UI based on this metadata and your own design conventions.

• Validation is now far more sophisticated. Your model metadata can specify validation rules using declarative attributes (e.g., [Required]) or custom validators, and then the framework will apply these rules against all incoming data. It can also use the same metadata to generate JavaScript for client-side validation.

• Automatic HTML encoding (supported on .NET 4 only) means you can avoid cross-site scripting (XSS) vulnerabilities without remembering whether or not to HTML-encode each output. It knows whether you’re calling a trusted HTML helper, and will make the right encoding choice automatically.

• Asynchronous controllers are relevant if you must handle very large volumes of concurrent requests that each wait for external input/output operations (e.g., database or web service calls). These build on ASP.NET’s underlying IHttpAsyncHandler API, potentially boosting performance in such scenarios.

• HTTP method overriding is very neat if you’re exposing a REST-style interface to the Web with the full range of HTTP verbs such as PUT and DELETE. Clients that can’t issue these HTTP request types can now specify an override parameter, and then the framework will transparently accept that as the request’s HTTP verb.

• Strongly typed input helpers let you map input controls (e.g., text boxes or custom
templates) directly to your model objects’ properties with full IntelliSense and refactoring support.

• Child requests are a way to inject multiple extra independent sections into a page (e.g., a navigation menu or a “latest posts” list)—something that doesn’t otherwise fit easily into the MVC pattern. This is based on the RenderAction() mechanism previously included in the “MVC Futures” add-on for ASP.NET MVC 1.

Like any other version 2 product, there’s also a host of smaller improvements, including extra
extensibility options and performance optimizations. I will explain all the above areas one by one from my furture posts. Times up now!! Need to go to office.. catch u guys !! :)

ASP.NET Web Forms Vs ASP.NET MVC

You’ve already heard about the weaknesses and limitations in traditional ASP.NET Web Forms from my previous post (http://upulsgamage.blogspot.com/2010/11/whats-wrong-with-aspnet-web-forms.html). That doesn’t mean that Web Forms is dead, though;

Microsoft is keen to remind everyone that the two platforms go forward side by side, equally supported, and both are subject to active, ongoing development. In many ways, your choice between the two is a matter of development philosophy.

• Web Forms takes the view that UIs should be stateful, and to that end adds a
sophisticated abstraction layer on top of HTTP and HTML, using ViewState and postbacks to create the effect of statefulness. This makes it suitable for
drag-anddrop Windows Forms– style development, in which you pull UI widgets onto a canvas and fill in code for their event handlers.

• MVC embraces HTTP’s true stateless nature, working with it rather than
fighting against it. It requires you to understand how web applications actually work; but given that understanding, it provides a simple, powerful, and modern approach to writing web applications with tidy code that’s easier to extend and maintain over time, free of bizarre complications and painful limitations.

There are certainly cases where Web Forms is at least as good as, and probably better than, MVC. The obvious example is small, intranet-type applications that are largely about binding grids directly to database tables or stepping users through a wizard. Since you don’t need to worry about the bandwidth issues that come with ViewState, don’t need to be concerned with search engine optimization, and aren’t bothered about unit testing or long-term maintenance, Web Forms’ drag-and-drop development strengths outweigh its weaknesses.

On the other hand, if you’re writing applications for the public Internet, or larger intranet
applications (e.g., more than a few person-month’s work), you’ll be aiming for fast download speeds and cross-browser compatibility, built with higher-quality, well-architected code suitable for automated testing, in which case MVC will deliver significant advantages for you.

Saturday, November 27, 2010

Who Should Use ASP.NET MVC?

As with any new technology, its mere existence isn’t a good reason for adopting it (despite the natural tendencies of software developers). Let’s consider how the MVC Framework compares with its most obvious alternatives.

Comparisons with ASP.NET Web Forms
You’ve already heard about the weaknesses and limitations in traditional ASP.NET Web Forms from my previous post, and how ASP.NET MVC overcomes many of those problems. That doesn’t mean that Web Forms is dead, though; Microsoft is keen to remind everyone that the two platforms go forward side by side, equally supported, and both are subject to active, ongoing development.

In many ways, your choice between the two is a matter of development philosophy.

• Web Forms takes the view that UIs should be stateful, and to that end adds a
sophisticated abstraction layer on top of HTTP and HTML, using ViewState and
postbacks to create the effect of statefulness. This makes it suitable for drag-anddrop
Windows Forms–style development, in which you pull UI widgets onto a
canvas and fill in code for their event handlers.

• MVC embraces HTTP’s true stateless nature, working with it rather than fighting
against it. It requires you to understand how web applications actually work; but
given that understanding, it provides a simple, powerful, and modern approach to
writing web applications with tidy code that’s easier to extend and maintain over
time, free of bizarre complications and painful limitations.

There are certainly cases where Web Forms is at least as good as, and probably better than, MVC.
The obvious example is small, intranet-type applications that are largely about binding grids directly to database tables or stepping users through a wizard. Since you don’t need to worry about the bandwidth issues that come with ViewState, don’t need to be concerned with search engine optimization, and aren't bothered about unit testing or long-term maintenance, Web Forms’ drag-and-drop development strengths outweigh its weaknesses. On the other hand, if you’re writing applications for the public Internet, or larger intranet applications (e.g., more than a few person-month’s work), you’ll be aiming for fast download speeds and cross-browser compatibility, built with higher-quality, well-architected code suitable for automated
testing, in which case MVC will deliver significant advantages for you.

What’s Wrong with ASP.NET Web Forms?

Traditional ASP.NET Web Forms was a fine idea, and a thrilling prospect at first, but of course reality turned out to be more complicated. Over the years, real-world use of Web Forms uncovered a range of weaknesses:

• ViewState weight:
The actual mechanism of maintaining state across requests(ViewState) often results in giant blocks of data being transferred between client and server. It can reach hundreds of kilobytes in many real-world applications, and it goes back and forth with every request, frustrating site visitors with a long wait each time they click a button or try to move to the next page on a grid.
ASP.NET AJAX suffers this just as badly,1 even though bandwidth-heavy page updating is one of the main problems that Ajax is supposed to solve.

• Page life cycle:
The mechanism of connecting client-side events with server-side event handler code, part of the page life cycle, can be extraordinarily complicated and delicate. Few developers have success manipulating the control hierarchy at runtime without getting ViewState errors or finding that some event handlers mysteriously fail to execute.

• False sense of separation of concerns:
ASP.NET’s code-behind model provides a means to take application code out of its HTML markup and into a separate codebehind class. This has been widely applauded for separating logic and presentation, but in reality developers are encouraged to mix presentation code
(e.g., manipulating the server-side control tree) with their application logic (e.g., manipulating database data) in these same monstrous code-behind classes. Without better separation of concerns, the end result is often fragile and unintelligible.

• Limited control over HTML:
Server controls render themselves as HTML, but not necessarily the HTML you want. Prior to version 4, their HTML output usually failed to comply with web standards or make good use of CSS, and server controls generated unpredictable and complex ID values that are hard to access using JavaScript. These problems are reduced in ASP.NET 4.

• Leaky abstraction:
Web Forms tries to hide away HTML and HTTP wherever possible. While trying to implement custom behaviors, you’ll frequently fall out of the abstraction, forcing you to reverse-engineer the postback event mechanism or perform perverse acts to make it generate the desired HTML. Plus, all this abstraction can act as a frustrating barrier for competent web developers. For
example, rich client-side interactivity is made excessively difficult because all client-side state can be blown away at any moment by a postback.

• Difficulty applying automated tests:
When ASP.NET’s designers first set out their platform, they could not have anticipated that automated testing would become the mainstream part of software development that it is today. Not surprisingly, the tightly coupled architecture they designed is totally unsuitable for unit testing. Integration testing can be a challenge too, as I’ll explain in within next few days.

Thursday, November 25, 2010

How to download ".ZIP" file from FTP server and unzip it into a local folder!

I think you guys can easily understand the logic of below code to get good understanding of how to do it.

please go through the code sample and comment lines, if you have any further suggestion and explanations please send me [usgamage@gmail.com]


NOTE: Here I am using a third party ".dll" file named "ICSharpCode.SharpZipLib.Zip.dll" to unzip the folder.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using ICSharpCode.SharpZipLib.Zip;
using System.Collections;

namespace XMLFileDownloader
{
public class XMLFileDownloader
{
//Variable declarations for FTP login credentials to the FTP ServerURI
string ftpUSER = string.Empty;
string ftpPassword = string.Empty;
string ftpServerURI = string.Empty;
string LocDirPath = string.Empty;
string ZIPFileName = string.Empty;
bool deleteZipFile = false;
int Count = 0;

///
/// Method to get Configuration values from SSIS config File
///

///
///
public int ReadConfigData(string ConfigFile)
{
XmlDocument xmldoc = null;

try
{
xmldoc = new XmlDocument();
xmldoc.Load(ConfigFile);
XmlNodeList nodeList = xmldoc.DocumentElement.ChildNodes;

foreach (XmlElement element in nodeList)
{
if (element.Name == "Configuration")
{
switch (element.Attributes["Path"].InnerText)
{
case "ftpUSER": ftpUSER = element.ChildNodes[0].InnerText.ToString().Trim().Length != 0 ? element.ChildNodes[0].InnerText.ToString() : "";
break;
case "ftpPassword": ftpPassword = element.ChildNodes[0].InnerText.ToString().Trim().Length != 0 ? element.ChildNodes[0].InnerText.ToString() : "";
break;
case "ftpServerURI": ftpServerURI = element.ChildNodes[0].InnerText.ToString().Trim().Length != 0 ? element.ChildNodes[0].InnerText.ToString() : "";
break;
case "LocDirPath": LocDirPath = element.ChildNodes[0].InnerText.ToString().Trim().Length != 0 ? element.ChildNodes[0].InnerText.ToString() : "";
break;
case "ZIPFileName": ZIPFileName = element.ChildNodes[0].InnerText.ToString().Trim().Length != 0 ? element.ChildNodes[0].InnerText.ToString() : "";
break;
case "DeleteZIPFile": deleteZipFile = Convert.ToBoolean(element.ChildNodes[0].InnerText.ToString().Trim());
break;
}
}
}
}

catch (Exception Exception)
{
Console.WriteLine("Configuration file invalid" + Exception.Message);
}

return GetFileList();
}

///
/// Initiate config values
///

public int IniConfig(string ftpUser, string ftpPwd, string uri, string locFilelocation, bool deletefile)
{
ftpUSER = ftpUser;
ftpPassword = ftpPwd;
ftpServerURI = uri;
LocDirPath = locFilelocation;
deleteZipFile = deletefile;

int _totDownload = GetFileList();
if (_totDownload > 0)
{
ZipFiles();
}
return _totDownload;
}

///
/// Methos to Get Download .xml and .csv files into
/// the local directory
///

///
public int GetFileList()
{
string[] downloadFiles;
StringBuilder result = new StringBuilder();
WebResponse response = null;
StreamReader reader = null;
try
{
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpServerURI));
reqFTP.UseBinary = true;
reqFTP.Credentials = new NetworkCredential(ftpUSER, ftpPassword);
reqFTP.Method = WebRequestMethods.Ftp.ListDirectory;
reqFTP.Proxy = null;
reqFTP.KeepAlive = false;
reqFTP.UsePassive = true;
response = reqFTP.GetResponse();
reader = new StreamReader(response.GetResponseStream());

string line = reader.ReadLine();
while (line != null)
{
result.Append(line);
result.Append("\n");
line = reader.ReadLine();
}

if (result.ToString() != null)
{
result.Remove(result.ToString().LastIndexOf('\n'), 1);

downloadFiles = result.ToString().Split('\n');

foreach (string file in downloadFiles)
{
if (Path.GetExtension(file) == ".zip")
{
if (Download(file))
{
Count = Count + 1;
Console.WriteLine("Tot. Zip file Downloaded: " + Count);
}
}
}
}
}

catch (Exception ex)
{
if (reader != null)
{
reader.Close();
}
if (response != null)
{
response.Close();
}

Console.WriteLine(ex.Message);
;
}

finally
{
downloadFiles = null;
}

return Count;
}

///
/// This method list all ".zip" files and pass each filename fileunzip method
///

///
public void ZipFiles()
{
int totFiles = 0;
try
{
ArrayList _zipFileList = GenerateFileList(LocDirPath); // generate file list

if (_zipFileList.Count > 0)
{
foreach (string singleFile in _zipFileList)
{
UnZipFiles(singleFile);
totFiles = totFiles + 1;
Console.WriteLine("Total Files extracted: " + totFiles);
}
}
}
catch (Exception ex)
{
Console.WriteLine("Error in listing all '.ZIP' files into string array" + ex.Message);
}
}

///
/// This method list all .zip files in given directory
///

///
///
public static ArrayList GenerateFileList(string Dir)
{
ArrayList fils = new ArrayList();
bool Empty = true;

foreach (string file in Directory.GetFiles(Dir)) // add each file in directory
{
if (file.Contains(".zip"))
{
fils.Add(file);
Empty = false;
}
}

if (Empty)
{
if (Directory.GetDirectories(Dir).Length == 0)
// if directory is completely empty, add it
{
fils.Add(Dir + @"/");
}
}
return fils; // return file list
}

///
/// This method will extract the given .zip file into the local dir.
///

public void UnZipFiles(string zipPathAndFile)
{
ZipInputStream s = new ZipInputStream(File.OpenRead(zipPathAndFile));
ZipEntry theEntry;
string tmpEntry = String.Empty;
while ((theEntry = s.GetNextEntry()) != null)
{
string fileName = Path.GetFileName(theEntry.Name);
if (fileName != String.Empty)
{
if (theEntry.Name.IndexOf(".ini") < 0)
{
string[] _str = theEntry.Name.Split('/');
string _currentFile = _str[_str.Length - 1].ToString();

string fullPath = LocDirPath + "\\" + _currentFile;
fullPath = fullPath.Replace("\\ ", "\\");
string fullDirPath = Path.GetDirectoryName(fullPath);
if (!Directory.Exists(fullDirPath)) Directory.CreateDirectory(fullDirPath);
FileStream streamWriter = File.Create(fullPath);
int size = 2048;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
streamWriter.Close();
}
}
}
s.Close();
if (deleteZipFile)
File.Delete(zipPathAndFile);
}

///
/// Method to download individual file
///

///
public bool Download(string file)
{
bool isDownloaded = false;
try
{
string uri = ftpServerURI + "/" + file;
Uri serverUri = new Uri(uri);
if (serverUri.Scheme != Uri.UriSchemeFtp)
{
return isDownloaded;
}
FtpWebRequest reqFTP;
reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(ftpServerURI + "/" + file));
reqFTP.Credentials = new NetworkCredential(ftpUSER, ftpPassword);
reqFTP.KeepAlive = false;
reqFTP.Method = WebRequestMethods.Ftp.DownloadFile;
reqFTP.UseBinary = true;
reqFTP.Proxy = null;
reqFTP.UsePassive = true;
FtpWebResponse response = (FtpWebResponse)reqFTP.GetResponse();
Stream responseStream = response.GetResponseStream();
FileStream writeStream = new FileStream(LocDirPath + "\\" + file, FileMode.Create);
int Length = 2048;
Byte[] buffer = new Byte[Length];
int bytesRead = responseStream.Read(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = responseStream.Read(buffer, 0, Length);
}
writeStream.Close();
response.Close();

isDownloaded = true;
}

catch (WebException e)
{
Console.WriteLine(e.Message, "Download Error");
}
catch (Exception ex)
{
Console.WriteLine(ex.Message, "Download Error");
}

return isDownloaded;
}
}
}