Hi , we have to discuss about how to download a file from the database , we generally upload a file to database in binary form so how to download that file that is going to see here..
suppose if i upload a file and bind the file detail in Gridview or datalist there i have give the Download link - here i am passing the id of the specific row so using this is i will retrieve the file.
so we pass the id to other page to make the file as download.
If Not Request.QueryString("id") Is Nothing Then
Dim As New SqlCommand("Select * from where download_id like @id", con)
Dim ID As New SqlParameter("@ID", SqlDbType.SmallInt, 2)
ID.Value = Request.QueryString("id")
ID.Direction = ParameterDirection.Input
cmd.Parameters.Add(ID)
cmd.Connection = con
con.Open()
Dim dRE As SqlDataReader
dRE = cmd.ExecuteReader()
While dRE.Read()
Dim myTitle As String = dRE.GetString(4).ToString 'document title
Dim myType As String = dRE.GetValue(5).ToString 'document type
If myTitle = "None" Or myType = "None" Then
message.Text = "No Attachements Present !"
Exit Sub
Else
Dim myDoc = dRE.GetSqlBinary(3) 'document
Response.Buffer = True
Response.Clear()
Response.AddHeader("content-disposition", "attachment; filename=" & myTitle)
'application/octet-stream
Select Case myType.ToLower
Case "doc"
Response.ContentType = "application/msword"
Case "docx"
Response.ContentType = "application/msword"
Case "ppt"
Response.ContentType = "application/vnd.ms-powerpoint"
Case "xls"
Response.ContentType = "application/x-msexcel"
Case "htm"
Response.ContentType = "text/HTML"
Case "html"
Response.ContentType = "text/HTML"
Case "jpg"
Response.ContentType = "image/JPEG"
Case "gif"
Response.ContentType = "image/GIF"
Case "pdf"
Response.ContentType = "application/pdf"
Case Else
Response.ContentType = "text/plain"
End Select
Response.BinaryWrite(myDoc.Value)
Response.Flush()
Response.Close()
If myDoc.isNull Then
message.Text &= "Retrieving File: " _
& myTitle & "." & myType & " Size: NULL
"
Else
message.Text &= "Retrieving File: " _
& myTitle & "." & myType & " Size: " & myDoc.ToString() & "
"
End If
End If
End While
con.Dispose()
con = Nothing
cmdDownloadDoc.Dispose()
cmdDownloadDoc = Nothing
End If
End SubResize Image using asp.net Method - 1
Here We have to discuss, how to dynamically resize the images using asp.net , generally we used two image one as Thumbnail and another one is big image , so if you upload the big image , we can set the default height and width on code to resize that image , at the same while we upload small image , on resizing the image it will be stretched to the specified height and width and also not seen qualify of image is not good,
so here , we calculate the width , as per we resize the image
I would prefer this method.This is the First Method , for this place one fileupload control and button on you design form
Dim thumbWidth As Integer = 132Dim image As System.Drawing.Image = System.Drawing.Image.FromStream
(FileUpload1.PostedFile.InputStream)
'Create a System.Drawing.Bitmap with the desired width and height of the thumbnail.
Dim srcWidth As Integer = image.Width
Dim srcHeight As Integer = image.Height
Dim thumbHeight As Integer = (srcHeight / srcWidth) * thumbWidth
Dim bmp As New Bitmap(thumbWidth, thumbHeight)
'Create a System.Drawing.Graphics object from the Bitmap which we will use to draw the high quality scaled image
Dim gr As System.Drawing.Graphics = System.Drawing.Graphics.FromImage(bmp)
'Set the System.Drawing.Graphics object property SmoothingMode to HighQuality
gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality
'Set the System.Drawing.Graphics object property CompositingQuality to HighQuality
gr.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality
'Set the System.Drawing.Graphics object property InterpolationMode to High
gr.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High
'Draw the original image into the target Graphics object scaling to the desired width and height
Dim rectDestination As New System.Drawing.Rectangle(0, 0, thumbWidth, thumbHeight)
gr.DrawImage(image, rectDestination, 0, 0, srcWidth, srcHeight, GraphicsUnit.Pixel)
'Save to destination file
bmp.Save(Server.MapPath("~/images/" & FileUpload1.PostedFile.FileName))
' dispose / release resources
bmp.Dispose()
image.Dispose()If you have better solution, just tell me !
Get All Files from Directories and Sub-Directories - Vb.NET
Here i have to discuss about how to get all the files of Directories and SubDirectories.
Generally we know how to get the files from From directory
Vb.NET
Imports System.IO
Dim position as integer = 1
Public Sub GetFiles(ByVal path As String)
If File.Exists(path) Then
' This path is a file
ProcessFile(path)
ElseIf Directory.Exists(path) Then
' This path is a directory
ProcessDirectory(path)
End If
End Sub
' Process all files in the directory passed in, recurse on any directories
' that are found, and process the files they contain.
Public Sub ProcessDirectory(ByVal targetDirectory As String)
' Process the list of files found in the directory.
Dim fileEntries As String() = Directory.GetFiles(targetDirectory)
For Each fileName As String In fileEntries
ProcessFile(fileName)
Next
' Recurse into subdirectories of this directory.
Dim subdirectoryEntries As String() = Directory.GetDirectories(targetDirectory)
For Each subdirectory As String In subdirectoryEntries
ProcessDirectory(subdirectory)
Next
End Sub
' Insert logic for processing found files here.
Public Sub ProcessFile(ByVal path As String)
Dim fi As New FileInfo(path)
Response.Write("File Number " + position.ToString() + ". Path: " + path + "
")
position += 1
End Sub
Give the path like this
GetFiles("C:\Test\")
And there is a simple way to get all files like this
Dim di as new IO.DirectoryInfo("C:\uploadfiles")
Dim finfo as IO.FileInfo() = di.GetFiles("*.*",IO.SearchOption.AllDirectories)If you have better solution, just tell me !
Validation which accept( empty, numeric or Float values)
Now we have to discuss about the validationexpression ie:
the textbox should accept empty values , numeric ( float )
.Implementation Code :
^\d*\.?\d*$
HTML
<asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
<asp:RegularExpressionValidator ID="RegularExpressionValidator3"runat="server" ErrorMessage="Invalid format"ControlToValidate="TextBox3" ValidationExpression="^\d*\.?\d*$"ValidationGroup="d"></asp:RegularExpressionValidator>
<asp:Button ID="Button5" runat="server" Text="Button"ValidationGroup="d" />Matches
( ) -> empty value
4535
520.20
2.54
Non-Matches
21.0dfdf
47854
RpksIf you have better solution, just tell me !
Ajax Cascading DropDownList in GridView with database ASP.NET sample
There are several cases when you have two or three dropdowns in gridview and want second one (and third one) to be populated based on selection of first and second dropdownlist.
In this example i've implemented Ajax cascading drop down list in EditItemTemaplete of GridView for updation of records in grid by fetching data from database to populate dropdowns,I've also implemented ajax auto complete extender textbox in it to edit name field.
Make sure you have created ajax enabled website and installed ajax toolkit and ajax web extensions properly.
In this example gridview displays Name, City, and Country on page load.And City and Country field turns into cascading dropdown list when user clicks on Edit link
Ajax cascading dropdown extender uses webservice to fetch data from database and populate dropdowns, city dropdown is populated based on country selected in country dropdown.
Important points to remember
1. Put AjaxControlToolkit.dll in bin folder of your application.
2. Set EventValidation to false in page directive of your aspx page.
<%@ Page Language="C#" EnableEventValidation="false"AutoEventWireup="true" CodeFile="Default.aspx.cs"Inherits="_Default" %>3. If you are getting Error method 500 or 12031 than read this to resolve this error
4. Webservice must have the webmethod with following signature and exact parameters
[WebMethod]
public CascadingDropDownNameValue[] GetColorsForModel(
string knownCategoryValues,
string category)You can change the method name but return type must be CascadingDropDownNameValue[] with knownCategoryValues,category as parameters First of all add a new webservice and name it CascadingDropDown.asmx In code behind of this asmx file write following code.
Add these namespaces.
using System.Collections.Generic;using System.Configuration;using System.Data.SqlClient;using AjaxControlToolkit;using System.Collections.Specialized;
/// <summary>
/// Summary description for CascadingDropDown
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService()]
public class CascadingDropDown : System.Web.Services.WebService
{
//Create global Connection string
string strConnection = ConfigurationManager.ConnectionStrings
["dbConnectionString"].ConnectionString;
public CascadingDropDown () {
//Uncomment the following line if using designed components
//InitializeComponent();
}
/// <summary>
/// WebMethod to populate country Dropdown
/// </summary>
/// <param name="knownCategoryValues"></param>
/// <param name="category"></param>
/// <returns>countrynames</returns>
[WebMethod]
public CascadingDropDownNameValue[] GetCountries
(string knownCategoryValues, string category)
{
//Create sql connection and sql command
SqlConnection con = new SqlConnection(strConnection);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = System.Data.CommandType.Text;
cmd.CommandText = "Select * from Country";
//Create dataadapter and fill the dataset
SqlDataAdapter dAdapter = new SqlDataAdapter();
dAdapter.SelectCommand = cmd;
con.Open();
DataSet objDs = new DataSet();
dAdapter.Fill(objDs);
con.Close();
//create list and add items in it
//by looping through dataset table
List<CascadingDropDownNameValue> countryNames
= new List<CascadingDropDownNameValue>();
foreach (DataRow dRow in objDs.Tables[0].Rows)
{
string countryID = dRow["CountryID"].ToString();
string countryName = dRow["CountryName"].ToString();
countryNames.Add(new CascadingDropDownNameValue
(countryName, countryID));
}
return countryNames.ToArray();
}
[WebMethod]
public CascadingDropDownNameValue[] GetCities
(string knownCategoryValues, string category)
{
int countryID;
//this stringdictionary contains has table with key value
//pair of cooountry and countryID
StringDictionary countryValues =
AjaxControlToolkit.CascadingDropDown.
ParseKnownCategoryValuesString(knownCategoryValues);
countryID = Convert.ToInt32(countryValues["Country"]);
SqlConnection con = new SqlConnection(strConnection);
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Parameters.AddWithValue("@CountryID", countryID);
cmd.CommandText =
"Select * from City where CountryID = @CountryID";
SqlDataAdapter dAdapter = new SqlDataAdapter();
dAdapter.SelectCommand = cmd;
con.Open();
DataSet objDs = new DataSet();
dAdapter.Fill(objDs);
con.Close();
List<CascadingDropDownNameValue> cityNames =
new List<CascadingDropDownNameValue>();
foreach (DataRow dRow in objDs.Tables[0].Rows)
{
string cityID = dRow["CityID"].ToString();
string cityName = dRow["CityName"].ToString();
cityNames.Add(new CascadingDropDownNameValue
(cityName, cityID));
}
return cityNames.ToArray();
}
}Now in html source of aspx page I've put two dropdowns in Edit Item Templates of grid view
<EditItemTemplate>
<asp:DropDownList ID="ddlCountry" runat="server">
</asp:DropDownList><br />
<ajaxToolkit:CascadingDropDown ID="CascadingDropDown1"
runat="server"
Category="Country"
TargetControlID="ddlCountry"
PromptText="-Select Country-"
LoadingText="Loading Countries.."
ServicePath="CascadingDropDown.asmx"
ServiceMethod="GetCountries">
</ajaxToolkit:CascadingDropDown>
</EditItemTemplate>Here TargetControlID is id of dropdown on which cascading dropdown is to be implemented, Service path is path to webservice and ServiceMethod is method to fetch the data from databse and populate dropdown. You also need to add reference to webservice in script manager
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="CascadingDropDown.asmx" />
</Services>
</asp:ScriptManager>The complete html source is like this
<%@ Page Language="C#" EnableEventValidation="false"
AutoEventWireup="true" CodeFile="Default.aspx.cs"
Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="AutoComplete.asmx" />
<asp:ServiceReference Path="CascadingDropDown.asmx" />
</Services>
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False"
DataSourceID="SqlDataSource1"
OnRowUpdating="GridView1_RowUpdating">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:TemplateField HeaderText="ID" SortExpression="ID">
<ItemTemplate>
<asp:Label ID="lblID" runat="server"
Text='<%#Eval("ID") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:Label ID="lblID" runat="server"
Text='<%#Bind("ID") %>'>
</asp:Label>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Name"
SortExpression="Name">
<ItemTemplate>
<asp:Label ID = "lblName" runat="server"
Text='<%#Eval("Name") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtName" runat="server"
Text='<%#Bind("Name") %>' >
</asp:TextBox>
<ajaxToolkit:AutoCompleteExtender
runat="server"
ID="autoComplete1"
TargetControlID="txtName"
ServicePath="AutoComplete.asmx"
ServiceMethod="GetCompletionList"
MinimumPrefixLength="1"
CompletionInterval="10"
EnableCaching="true"
CompletionSetCount="12" />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Country"
SortExpression="Country">
<ItemTemplate>
<asp:Label ID="lblCountry" runat="server"
Text='<%#Eval("Country") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlCountry" runat="server">
</asp:DropDownList>
<ajaxToolkit:CascadingDropDown
ID="CascadingDropDown1"
runat="server"
Category="Country"
TargetControlID="ddlCountry"
PromptText="-Select Country-"
LoadingText="Loading Countries.."
ServicePath="CascadingDropDown.asmx"
ServiceMethod="GetCountries">
</ajaxToolkit:CascadingDropDown>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="City"
SortExpression="City">
<ItemTemplate>
<asp:Label ID="lblCity" runat="server"
Text='<%#Eval("City") %>'>
</asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlCity" runat="server"
OnSelectedIndexChanged="ddlCity_SelectedIndexChanged">
</asp:DropDownList><br />
<ajaxToolkit:CascadingDropDown
ID="CascadingDropDown2"
runat="server"
Category="City"
TargetControlID="ddlCity"
ParentControlID="ddlCountry"
PromptText="-Select City-"
LoadingText="Loading Cities.."
ServicePath="CascadingDropDown.asmx"
ServiceMethod="GetCities">
</ajaxToolkit:CascadingDropDown>
</EditItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
<div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:dbConnectionString %>"
SelectCommand="SELECT [ID], [Name], [City],[Country]
FROM [Location]"
UpdateCommand="Update Location set [Name] = @Name,
[City] = @City,[Country] = @Country
where ID = @ID">
<UpdateParameters>
<asp:Parameter Name="Name" />
<asp:Parameter Name="ID" />
<asp:Parameter Name="Country"/>
<asp:Parameter Name="City"/>
</UpdateParameters>
</asp:SqlDataSource>
</div>
</form>
</body>
</html>Finally write this code in code behind of aspx page to update record
protected void GridView1_RowUpdating
(object sender, GridViewUpdateEventArgs e)
{
//Find dropdown to get selected Item text
DropDownList ddlGridCountry = (DropDownList)
GridView1.Rows[e.RowIndex].FindControl("ddlCountry");
string strCountry =
ddlGridCountry.SelectedItem.Text.ToString();
DropDownList ddlGridCity = (DropDownList)
GridView1.Rows[e.RowIndex].FindControl("ddlCity");
string strCity =
ddlGridCity.SelectedItem.Text.ToString();
SqlDataSource1.UpdateParameters.Clear();
SqlDataSource1.UpdateParameters.Add
("Country", strCountry);
SqlDataSource1.UpdateParameters.Add("City", strCity);
}Hope this helps !
ASP.NET Add AutoNumber Column in GridView or DataList
Send Email using Gmail ASP.NET C# VB.NET
If you want to send email using your Gmail account or using Gmail's smtp server in ASP.NET application or if you don't have a working smtp server to send mails using your ASP.NET application or aspx page than sending e-mail using Gmail is best option.
First of all add below mentioned namespace in code behind of aspx page from which you want to send the mail.
Now write this code in click event of button
using System.Net.Mail;
C# code
protected void Button1_Click(object sender, EventArgs e)
{
MailMessage mail = new MailMessage();
mail.To.Add("jainamit.agra@gmail.com");
mail.To.Add("amit_jain_online@yahoo.com");
mail.From = new MailAddress("jainamit.agra@gmail.com");
mail.Subject = "Email using Gmail";
string Body = "Hi, this mail is to test sending mail"+
"using Gmail in ASP.NET";
mail.Body = Body;
mail.IsBodyHtml = true;
SmtpClient smtp = new SmtpClient();
smtp.Host = "smtp.gmail.com";
smtp.Credentials = new System.Net.NetworkCredential
("YourUserName@gmail.com","YourGmailPassword");
smtp.EnableSsl = true;
smtp.Send(mail);
}VB.NET code
Imports System.Net.Mail
Protected Sub Button1_Click
(ByVal sender As Object, ByVal e As EventArgs)
Dim mail As MailMessage = New MailMessage()
mail.To.Add("jainamit.agra@gmail.com")
mail.To.Add("amit_jain_online@yahoo.com")
mail.From = New MailAddress("jainamit.agra@gmail.com")
mail.Subject = "Email using Gmail"
String Body = "Hi, this mail is to test sending mail"+
"using Gmail in ASP.NET"
mail.Body = Body
mail.IsBodyHtml = True
Dim smtp As SmtpClient = New SmtpClient()
smtp.Host = "smtp.gmail.com"
smtp.Credentials = New System.Net.NetworkCredential
("YourUserName@gmail.com","YourGmailPassword")
smtp.EnableSsl = True
smtp.Send(mail)
End SubChange YourUserName@gmail.com to your gmail ID and YourGmailPassword to Your password for Gmail account and test the code.
Than you need to check your Gmail username and password.
Hope this helps
Integration Testing Your ASP.NET MVC Application
Let’s start with a quick recap:
- Unit tests test individual software components. They supply mocks or fake versions of dependencies (such as a database) so that the unit test doesn’t rely on any external code and any failures can be pinpointed exactly. Unit testing is central to Test Driven Development – the entire TDD process is driven by unit testing.
- Integration tests test your entire software stack working together. These tests don’t mock or fake anything (they use the real database, and real network connections) and are good at spotting if your unit-tested components aren’t working together as you expected. In general, it’s best to put most of your effort into building a solid suite of unit tests, and then adding a few integration tests for each major feature so you can detect any catastrophic incompatibilities or configuration errors before your customers do.
ASP.NET MVC famously has great support for unit testing. That’s well covered elsewhere on the web, so I won’t write more about it here. But what about integration testing?
These tools host a real web browser and automate a series of navigation steps, clicking on buttons and letting you write assertions about what should appear on the screen. Browser automation is fully capable of testing your JavaScript code just as easily as your business logic. However, there are also some drawbacks to browser automation:
- Browser automation test scripts are very fragile. As soon as you alter the HTML in your views, the tests may start failing and sometimes all need to be re-recorded. Many developers are happy with browser automation at first, but after a few months are sick of re-recording the tests or maintaining thousands of lines of scripts, and give up on it.
- Browser automation test scripts rely on parsing the generated HTML, which loses all the strongly-typed goodness of your MVC model objects.
Introducing MvcIntegrationTestFramework
What if you could write NUnit tests (or xUnit or whatever you prefer) that directly submit a URL, query string, cookies, request headers, etc., into your application – without needing the app to be hosted in any web server but still running in the real (non-mocked) ASP.NET runtime – and get back the response text to make assertions about? In fact, what if you also got back the ActionResult (e.g., a ViewResult) that was executed, a reference to any unhandled exception it threw, and could also write assertions about cookie values or the contents of Session? What if you could string together a series of test requests to simulate a user’s browsing session, checking that a whole feature area works from end to end?
Well, my friend, all this can be yours with MvcIntegrationTestFrameworkA Simple Integration Test Example
Consider the following action method:
public ActionResult Index()
{
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}You can write an integration for this using MvcIntegrationTestFramework as follows:
[Test]
public void Root_Url_Renders_Index_View()
{
appHost.SimulateBrowsingSession(browsingSession => {
// Request the root URL
RequestResult result = browsingSession.ProcessRequest("/");
// You can make assertions about the ActionResult...
var viewResult = (ViewResult) result.ActionExecutedContext.Result;
Assert.AreEqual("Index", viewResult.ViewName);
Assert.AreEqual("Welcome to ASP.NET MVC!", viewResult.ViewData["Message"]);
// ... or you can make assertions about the rendered HTML
Assert.IsTrue(result.ResponseText.Contains("<!DOCTYPE html"));
});
}This is pretty similar to a typical unit test for that action method, except that you also get accessto the finished rendered HTML, in case that interests you. Unlike a unit test, this integration testgoes through the entire request-processing pipeline, so it tests your routing configuration, yourcontroller factory, any dependencies your controller has, and even your view template.
[Test]
public void LogInProcess()
{
string securedActionUrl = "/home/SecretAction";
appHost.SimulateBrowsingSession(browsingSession => {
// First try to request a secured page without being logged in
RequestResult initialRequestResult = browsingSession.ProcessRequest(securedActionUrl);
string loginRedirectUrl = initialRequestResult.Response.RedirectLocation;
Assert.IsTrue(loginRedirectUrl.StartsWith("/Account/LogOn"), "Didn't redirect to logon page");
// Now follow redirection to logon page
string loginFormResponseText = browsingSession.ProcessRequest(loginRedirectUrl).ResponseText;
string suppliedAntiForgeryToken = MvcUtils.ExtractAntiForgeryToken(loginFormResponseText);
// Now post the login form, including the verification token
RequestResult loginResult = browsingSession.ProcessRequest(loginRedirectUrl,HttpVerbs.Post, new NameValueCollection
{
{ "username", "steve" },
{ "password", "secret" },
{ "__RequestVerificationToken", suppliedAntiForgeryToken }
});
string afterLoginRedirectUrl = loginResult.Response.RedirectLocation;
Assert.AreEqual(securedActionUrl, afterLoginRedirectUrl, "Didn't redirect back to SecretAction");
// Check that we can now follow the redirection back to the protected action, and are let in
RequestResult afterLoginResult = browsingSession.ProcessRequest(securedActionUrl);
Assert.AreEqual("Hello, you're logged in as steve", afterLoginResult.ResponseText);
});
}In this test, multiple requests are made as part of the same browsing session. The integration testing framework will preserve cookies (and therefore session state) from one request to the next, so you can test interaction with things like Forms Authentication and ASP.NET MVC’s AntiForgeryToken helpers.
This has advantages over browser automation in that (in my opinion) it’s easier to write this test – it’s concise, you don’t need to learn a browser scripting language, and you don’t need to rerecord the script if you restructure the HTML. You can make assertions at the HTML level, or you can make assertions at the ActionResult level, with fully strongly-typed access to any ViewData or Model values that were being supplied.
On the flip side, browser automation is still the only way to test your JavaScript.
Integration Testing Your Own ASP.NET MVC Application
To add these kinds of tests to your own ASP.NET MVC application, create a new class library project called MyApp.IntegrationTests or similar. Add a reference to MvcIntegrationTestFramework.dll, which you can get by downloading the demo project and compiling it, and also add a reference to your chosen unit testing framework (e.g., NUnit or xUnit).
Next, if you’re using NUnit, create a basic test fixture class as follows:
using MvcIntegrationTestFramework.Hosting;
using MvcIntegrationTestFramework.Browsing;
[TestFixture]
public class MyIntegrationTests
{
// Amend this path to point to whatever folder contains your ASP.NET MVC application
// (i.e., the folder that contains your app's main web.config file)
private static readonly string mvcAppPath = Path.GetFullPath(AppDomain.CurrentDomain.BaseDirectory + "\\..\\..\\..\\MyMvcApplication");
private readonly AppHost appHost = new AppHost(mvcAppPath);
}Also – and seriously you can’t skip this step – you must add a post-build step so that each time you compile, Visual Studio will copy the assemblies from your integration test project’s \bin folder into your main ASP.NET MVC application’s \bin folder. I’ll explain why this is necessary later.
The test fixture you just created tells MvcIntegrationTestFramework to find your ASP.NET MVC application at the specified disk location, and to host it (without using IIS or any other web server). The resulting AppHost object then provides an API for issuing requests to your application.
[TestFixture]public class MyIntegrationTests{ // Leave rest as before[Test] public void HomeIndex_DemoTests(){appHost.SimulateBrowsingSession(browsingSession => {RequestResult result = browsingSession.ProcessRequest("home/index");// Routing config should match "home" controllerAssert.AreEqual("home", result.ActionExecutedContext.RouteData.Values["controller"]);// Should have rendered the "index" viewActionResult actionResult = result.ActionExecutedContext.Result;Assert.IsInstanceOf(typeof(ViewResult), actionResult);Assert.AreEqual("index", ((ViewResult)actionResult).ViewName);// App should not have had an unhandled exceptionAssert.IsNull(result.ResultExecutedContext.Exception);}); }}Conclusion
Personally, I find this approach to integration testing more productive than browser automation in most cases, because the tests are fast to write and are less prone to break because of trivial HTML changes. I wouldn’t want to have thousands of integration tests, though – for one thing, they’d take ages to run – but end-to-end testing for key scenarios like logging in, registering, going through shopping carts, etc., proves pretty convincingly that the major functional areas of your app are working overall, leaving unit tests to prove the fine detail of each component.
If you have better solution, just tell me !