Another successful ASP.NET MVC 5 training at Manly Plastics, Inc. conducted by veteran ASP.NET trainer, Harold Javier, and senior developer, Carl Stephen Laredo.
dotNet From Manila
Hi, my name is Harold Javier. I am an ASP.NET (dotNet) trainer, coach, mentor, and consultant for more than 8 years. It is my mission to teach, educate, and train people about some simple solutions to common problems we experience either as a software developer or as a researcher on topics about ASP.NET Core, ASP.NET MVC, ASP.NET Web API, ASP.NET Web Form, and .NET (dotNet) technology in general.
08 January 2020
19 May 2019
ASP.NET Best Practices Training
We had another successful training in Quezon City on topics about ASP.NET MVC Best Practices conducted by Harold Javier, a veteran .NET trainer and developer, together with Carl Stephen Laredo.
It was attended by Direc Business Technology, Inc. technical and functional consultants, team leaders, system analysts, and software developers.
It was attended by Direc Business Technology, Inc. technical and functional consultants, team leaders, system analysts, and software developers.
28 March 2019
ASP.NET MVC 5 (Best Practices) Workshop
Due to high demand, I'm still conducting workshops and seminars on ASP.NET MVC 5 using Visual Studio 2013 with .NET Framework 4.5.1.
For the benefit of the attendees, below are the NuGet packages that I use during the ASP.NET MVC 5 live workshop:
ORM: Entity Framework version 6.2.0
install-package EntityFramework -Version 6.2.0
DI/IoC: Structuremap
install-package StructureMap.MVC5
Mapping: AutoMapper version 5.1.1
install-package AutoMapper -Version 5.1.1
And for the lazy trainees who always forget the correct format of the connectionString, you may copy then paste the below sample connectionString to your web.config just above the </configuration> end tag:
<connectionStrings>
<add name="YourDbConnectionString" connectionString="Data Source=YourDatabaseServerName;Initial Catalog=SampleDB;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
For the benefit of the attendees, below are the NuGet packages that I use during the ASP.NET MVC 5 live workshop:
ORM: Entity Framework version 6.2.0
install-package EntityFramework -Version 6.2.0
DI/IoC: Structuremap
install-package StructureMap.MVC5
Mapping: AutoMapper version 5.1.1
install-package AutoMapper -Version 5.1.1
And for the lazy trainees who always forget the correct format of the connectionString, you may copy then paste the below sample connectionString to your web.config just above the </configuration> end tag:
<connectionStrings>
<add name="YourDbConnectionString" connectionString="Data Source=YourDatabaseServerName;Initial Catalog=SampleDB;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
26 September 2018
ASP.NET Core MVC's Action Result naming changes
Working from version 1.1 to 2.1. I found this very handy:
Following methods on the
Controller
base class have been renamed for the sake of consistency and making them less verbose.
HttpUnauthorized => Unauthorized
HttpNotFound(and its overloads) => NotFound
HttpBadRequest(and its overloads) => BadRequest
HttpNotFound(and its overloads) => NotFound
HttpBadRequest(and its overloads) => BadRequest
Following action result types have also been renamed. The
Http
prefix has been removed.
Microsoft.AspNetCore.Mvc.HttpUnauthorizedResult => Microsoft.AspNetCore.Mvc.UnauthorizedResult
Microsoft.AspNetCore.Mvc.HttpOkResult => Microsoft.AspNetCore.Mvc.OkResult
Microsoft.AspNetCore.Mvc.HttpOkObjectResult => Microsoft.AspNetCore.Mvc.OkObjectResult
Microsoft.AspNetCore.Mvc.HttpNotFoundResult => Microsoft.AspNetCore.Mvc.NotFoundResult
Microsoft.AspNetCore.Mvc.HttpNotFoundObjectResult => Microsoft.AspNetCore.Mvc.NotFoundObjectResult
Microsoft.AspNetCore.Mvc.HttpStatusCodeResult = > Microsoft.AspNetCore.Mvc.StatusCodeResult
Microsoft.AspNetCore.Mvc.HttpOkResult => Microsoft.AspNetCore.Mvc.OkResult
Microsoft.AspNetCore.Mvc.HttpOkObjectResult => Microsoft.AspNetCore.Mvc.OkObjectResult
Microsoft.AspNetCore.Mvc.HttpNotFoundResult => Microsoft.AspNetCore.Mvc.NotFoundResult
Microsoft.AspNetCore.Mvc.HttpNotFoundObjectResult => Microsoft.AspNetCore.Mvc.NotFoundObjectResult
Microsoft.AspNetCore.Mvc.HttpStatusCodeResult = > Microsoft.AspNetCore.Mvc.StatusCodeResult
Source: a user named 'kichalla' from Github
Solving Error 500 (internal server error) when running a newly deployed ASP.NET Core WebAPI
I encountered an Error 500 when I first run the ASP.NET Core 2.1 Web API deployed on a Windows 2008 Server machine with IIS version 7.5.
When I checked the log (since I set stdoutLogEnabled="true"), I found an error that says:
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
CREATE DATABASE [SampleDb];
System.Data.SqlClient.SqlException (0x80131904): CREATE DATABASE permission denied in database 'master'.
I know it has something to do with the permission in the database.
The solutions below just worked for me:
When I checked the log (since I set stdoutLogEnabled="true"), I found an error that says:
fail: Microsoft.EntityFrameworkCore.Database.Command[20102]
Failed executing DbCommand (2ms) [Parameters=[], CommandType='Text', CommandTimeout='60']
CREATE DATABASE [SampleDb];
System.Data.SqlClient.SqlException (0x80131904): CREATE DATABASE permission denied in database 'master'.
I know it has something to do with the permission in the database.
The solutions below just worked for me:
- Connect to the database using SQL Server Management Studio.
- Click Security, then Logins
- Double click the user that will access your database. In my case it is NT AUTHORITY\NETWORK SERVICE
- Select the Server Roles and check the dbcreator, public, and sysadmin credentials.
24 September 2018
Error MSB3027 Could not copy "obj\Debug\netcoreapp2.1\ to "bin\Debug\netcoreapp2.1\
Could not copy "obj\Debug\netcoreapp2.1\ to "bin\Debug\netcoreapp2.1\
Have you experienced this error when you're trying to rebuild your application?
It looks like the IIS Express is "locking" the output when debugging the same project.
My initial solution was to wait for some time and close some running applications, then tried to rebuild again.
I worked for sometime, then same thing happened again when I tried to rebuild the application.
But when I finally close the Visual Studio and opened the same project and build it, it worked fine with no issue.
So far, that's my quick and easy way to resolve the issue. I'll try to update this post when I found a better approach in solving this problem.
Have you experienced this error when you're trying to rebuild your application?
It looks like the IIS Express is "locking" the output when debugging the same project.
My initial solution was to wait for some time and close some running applications, then tried to rebuild again.
I worked for sometime, then same thing happened again when I tried to rebuild the application.
But when I finally close the Visual Studio and opened the same project and build it, it worked fine with no issue.
So far, that's my quick and easy way to resolve the issue. I'll try to update this post when I found a better approach in solving this problem.
20 September 2018
Dapper ORM (A simple implementation) Part 1
I recommed the use of Dapper. Aside from it's developed by a good team from Stack Overflow, it was built with performance in mind. And on top of that, Dapper is lightweight and very fast compared to other ORMs.
You may install Dapper from the NuGet.
The implementation is so easy to do.
Here in my example, I'll show you how to get a list of users with the Query() extension method of Dapper to retrieve all the records from the User table in our UserDb database:
private readonly string connectionString = "Server=BDF_SERVER;Database=UserDb;Trusted_Connection=True;";
//To display all the users from the table
public List<User> Display_All_Users()
{
using (var con = new SqlConnection(connectionString))
{
string strRead = "SELECT * FROM User";
return con.Query<User>(strRead).ToList();
}
}
//To search a particular user from the table
public User Display_User_By_Id(int id)
{
using (var con = new SqlConnection(connectionString))
{
string strRead = "Select * From User WHERE Id = @Id"
return con.Query<User>(strRead, new { id }).SingleOrDefault();
}
}
You may install Dapper from the NuGet.
The implementation is so easy to do.
Here in my example, I'll show you how to get a list of users with the Query() extension method of Dapper to retrieve all the records from the User table in our UserDb database:
private readonly string connectionString = "Server=BDF_SERVER;Database=UserDb;Trusted_Connection=True;";
//To display all the users from the table
public List<User> Display_All_Users()
{
using (var con = new SqlConnection(connectionString))
{
string strRead = "SELECT * FROM User";
return con.Query<User>(strRead).ToList();
}
}
//To search a particular user from the table
public User Display_User_By_Id(int id)
{
using (var con = new SqlConnection(connectionString))
{
string strRead = "Select * From User WHERE Id = @Id"
return con.Query<User>(strRead, new { id }).SingleOrDefault();
}
}
16 September 2018
Database First (Reverse engineering to the existing database) in ASP.NET Core
If you have an existing database (for example in MS SQL server) and you want to "reverse engineer" to that existing database and create its database context in your ASP.NET Core project, one of the simple and faster ways to do it is by installing the following NuGet packages using the Package Manager:
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools
Install-Package Microsoft.EntityFrameworkCore.SqlServer.Design
Then, to create the models or database context of the existing database to a folder named Models, you can use the following command:
Scaffold-DbContext
“Server=Your_Server_Name;Database=SampleDb;Trusted_Connection=True;”
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models
This command will generate a DbContext and POCO of SampleDb from Your_Server_Name database to Models folder.
28 September 2017
How to get the MAC address of Any device on the network using C#
I once deployed a web application on a client that required to identify all the MAC addresses of different devices connected on the network. I can do arp -a command from command prompt, but I also created a short script to identify the MAC address of every device connected on the network using C#. Here's my code:
[System.Runtime.InteropServices.DllImport("iphlpapi.dll", ExactSpelling = true)]
private static extern int SendARP(int targetIp, int sourceIp, byte[] pcMacAddr, ref int macAddLength);
public static PhysicalAddress GetMacAddress(IPAddress ipAddress)
{
const int macAddressLength = 6;
int length = macAddressLength;
var macBytes = new byte[macAddressLength];
SendARP(BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0), 0, macBytes, ref length);
return new PhysicalAddress(macBytes);
}
[System.Runtime.InteropServices.DllImport("iphlpapi.dll", ExactSpelling = true)]
private static extern int SendARP(int targetIp, int sourceIp, byte[] pcMacAddr, ref int macAddLength);
public static PhysicalAddress GetMacAddress(IPAddress ipAddress)
{
const int macAddressLength = 6;
int length = macAddressLength;
var macBytes = new byte[macAddressLength];
SendARP(BitConverter.ToInt32(ipAddress.GetAddressBytes(), 0), 0, macBytes, ref length);
return new PhysicalAddress(macBytes);
}
14 August 2017
How to print content of the page using ASP.NET AjaxToolkit
I once had a requirement to print a portion of the page using AjaxToolkit. Below is my sample code to generate a printable simple report on button click:
<ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</ajaxToolkit:ToolkitScriptManager>
<script type="text/javascript">
function PrintPanel() {
var panel = document.getElementById("<%=Panel1.ClientID %>");
var printWindow = window.open('', '', 'height=500,width=1000');
printWindow.document.write('<html><head><title>My Sample Report</title></head>');
printWindow.document.write('<body style="font-size: 12px; font-family: Calibri">');
printWindow.document.write(panel.innerHTML);
printWindow.document.write('</body></html>');
printWindow.document.close();
setTimeout(function () {
printWindow.print();
}, 500);
return false;
}
</script>
<asp:Button ID="btnPrint" runat="server" Text="Print Report" OnClientClick="return PrintPanel();" Visible="False" />
<asp:Panel ID="Panel1" runat="server" CssClass="modalPopup" BackColor="#ffffff">
//All your HTML layout and elements, reports, GridView, etc. go here
</asp:Panel>
<ajaxToolkit:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</ajaxToolkit:ToolkitScriptManager>
<script type="text/javascript">
function PrintPanel() {
var panel = document.getElementById("<%=Panel1.ClientID %>");
var printWindow = window.open('', '', 'height=500,width=1000');
printWindow.document.write('<html><head><title>My Sample Report</title></head>');
printWindow.document.write('<body style="font-size: 12px; font-family: Calibri">');
printWindow.document.write(panel.innerHTML);
printWindow.document.write('</body></html>');
printWindow.document.close();
setTimeout(function () {
printWindow.print();
}, 500);
return false;
}
</script>
<asp:Button ID="btnPrint" runat="server" Text="Print Report" OnClientClick="return PrintPanel();" Visible="False" />
<asp:Panel ID="Panel1" runat="server" CssClass="modalPopup" BackColor="#ffffff">
//All your HTML layout and elements, reports, GridView, etc. go here
</asp:Panel>
How to migrate CSV to MS SQL Server database using SqlBulkCopy
Below is a sample code in migrating or importing as CSV file to SQL database:
void Migrate_CSV_File_To_Database()
{
if (FileUpload1.HasFile)
{
const string saveFolder = @"C:\temp\imported";
string filePath = Path.Combine(saveFolder, FileUpload1.FileName);
FileUpload1.SaveAs(filePath);
string connString = WebConfigurationManager.ConnectionStrings["YourConnectionString"].ConnectionString;
var excelConnString =
String.Format(
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;IMEX=1\"",
filePath);
//Create Connection to Excel work book
using (var excelConnection = new OleDbConnection(excelConnString))
{
//Create OleDbCommand to fetch data from Excel
const string strSelect = "SELECT [Column1], [Column2], [Column3], [Column4] FROM [Sheet1$]";
using (var cmd = new OleDbCommand(strSelect, excelConnection))
{
excelConnection.Open();
using (var dReader = cmd.ExecuteReader())
{
using (var sqlBulk = new SqlBulkCopy(connString))
{
//Give your Destination table name
sqlBulk.DestinationTableName = "Destination_Table_Name";
sqlBulk.WriteToServer(dReader);
}
}
excelConnection.Close();
}
}
}
}
void Migrate_CSV_File_To_Database()
{
if (FileUpload1.HasFile)
{
const string saveFolder = @"C:\temp\imported";
string filePath = Path.Combine(saveFolder, FileUpload1.FileName);
FileUpload1.SaveAs(filePath);
string connString = WebConfigurationManager.ConnectionStrings["YourConnectionString"].ConnectionString;
var excelConnString =
String.Format(
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0;IMEX=1\"",
filePath);
//Create Connection to Excel work book
using (var excelConnection = new OleDbConnection(excelConnString))
{
//Create OleDbCommand to fetch data from Excel
const string strSelect = "SELECT [Column1], [Column2], [Column3], [Column4] FROM [Sheet1$]";
using (var cmd = new OleDbCommand(strSelect, excelConnection))
{
excelConnection.Open();
using (var dReader = cmd.ExecuteReader())
{
using (var sqlBulk = new SqlBulkCopy(connString))
{
//Give your Destination table name
sqlBulk.DestinationTableName = "Destination_Table_Name";
sqlBulk.WriteToServer(dReader);
}
}
excelConnection.Close();
}
}
}
}
How to import GridView to Excel in ASP.NET WebForm with C#
I have a requirement to import a GridView data to MS Excel without using any third party library. The solutions are kinda old stuff actually and they're all over the net, but I still want to share it here on my blog for the benefit of my visitors.
A. First, you need to add VerifyRenderingInServerForm method to confirm that an HtmlForm control is rendered for the specified ASP.NET server control at run time.
public override void VerifyRenderingInServerForm(Control control)
{
}
B. Then, add the following sample codes to the button click event.
protected void btnConvertToExcel_Click(object sender, EventArgs e)
{
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("content-disposition", "attachment;filename=SalesReport.xls");
Response.Charset = "";
var sw = new StringWriter();
var hw = new HtmlTextWriter(sw);
gvSalesReport.AllowPaging = false;
//Call the method in viewing Sales Report in GridView
Get_Sales_Report();
for (int i = 0; i <= gvSalesReport.Rows.Count - 1; i++)
{
GridViewRow row = gvSalesReport.Rows[i];
//Change Color back to white
row.BackColor = System.Drawing.Color.White;
//Apply text style to each Row
row.Attributes.Add("class", "textmode");
//Apply style to Individual Cells of Alternating Row (optional)
if (i % 2 != 0)
{
row.Cells[0].Style.Add("background-color", "#C2D69B");
row.Cells[1].Style.Add("background-color", "#C2D69B");
row.Cells[2].Style.Add("background-color", "#C2D69B");
row.Cells[3].Style.Add("background-color", "#C2D69B");
}
}
gvSalesReport.RenderControl(hw);
//style to format numbers to string
const string style = "<style>.textmode{mso-number-format:\\@;}</style>";
Response.Write(style);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
}
A. First, you need to add VerifyRenderingInServerForm method to confirm that an HtmlForm control is rendered for the specified ASP.NET server control at run time.
public override void VerifyRenderingInServerForm(Control control)
{
}
B. Then, add the following sample codes to the button click event.
protected void btnConvertToExcel_Click(object sender, EventArgs e)
{
Response.ContentType = "application/vnd.ms-excel";
Response.AddHeader("content-disposition", "attachment;filename=SalesReport.xls");
Response.Charset = "";
var sw = new StringWriter();
var hw = new HtmlTextWriter(sw);
gvSalesReport.AllowPaging = false;
//Call the method in viewing Sales Report in GridView
Get_Sales_Report();
for (int i = 0; i <= gvSalesReport.Rows.Count - 1; i++)
{
GridViewRow row = gvSalesReport.Rows[i];
//Change Color back to white
row.BackColor = System.Drawing.Color.White;
//Apply text style to each Row
row.Attributes.Add("class", "textmode");
//Apply style to Individual Cells of Alternating Row (optional)
if (i % 2 != 0)
{
row.Cells[0].Style.Add("background-color", "#C2D69B");
row.Cells[1].Style.Add("background-color", "#C2D69B");
row.Cells[2].Style.Add("background-color", "#C2D69B");
row.Cells[3].Style.Add("background-color", "#C2D69B");
}
}
gvSalesReport.RenderControl(hw);
//style to format numbers to string
const string style = "<style>.textmode{mso-number-format:\\@;}</style>";
Response.Write(style);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
}
02 August 2017
Peachpie Error: ProjectName.msbuildproj(22,3): error MSB4020: The value "" of the "Project" attribute in element is invalid.
Just this morning while drinking 2 cups of my favorite Nescafe Decaf and Alaska Krem-Top, I created my first Peachpie project.
I'm using dotnet version 2.0.0-preview2-006497 and I started installing templates for peachpie by typing dotnet new -i Peachpie.Templates::* .
Then I began to create a new Peachpie console application by simply typing dotnet new peachpie-console. And I got a message that says The template "Peachpie console application" was created successfully.
But when I ran the dotnet restore command, I got the following error message:
ProjectName.msbuildproj(22,3): error MSB4020: The value "" of the "Project" attribute in element <Import> is invalid.
And obviously I cannot run the command dotnet run until I fix the build error.
I will try to find the reason what happened and I'll update this post as soon as I can.
----------------------------------------------------------------------------------------------------------------
Finally, I found a solution to this error!
I simply edited/replaced the default msbuildproj file with the following:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="**/*.php" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Peachpie.Compiler.Tools" Version="0.7.0-*" />
<PackageReference Include="Peachpie.NET.Sdk" Version="0.7.0-*" PrivateAssets="Build" />
</ItemGroup>
<!-- A temporary solution, import C# Visual Studio design time targets in order to be able to load the project in Visual Studio -->
<PropertyGroup>
<CSharpDesignTimeTargetsPath Condition="'$(CSharpDesignTimeTargetsPath)'==''">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.CSharp.DesignTime.targets</CSharpDesignTimeTargetsPath>
</PropertyGroup>
<Import Project="$(CSharpDesignTimeTargetsPath)" Condition="Exists('$(CSharpDesignTimeTargetsPath)')" />
</Project>
Then, I typed the dotnet restore ProjectName.msbuildproj command.
Once restore is completed, you can now run your application by typing dotnet run command.
I'm using dotnet version 2.0.0-preview2-006497 and I started installing templates for peachpie by typing dotnet new -i Peachpie.Templates::* .
Then I began to create a new Peachpie console application by simply typing dotnet new peachpie-console. And I got a message that says The template "Peachpie console application" was created successfully.
But when I ran the dotnet restore command, I got the following error message:
ProjectName.msbuildproj(22,3): error MSB4020: The value "" of the "Project" attribute in element <Import> is invalid.
And obviously I cannot run the command dotnet run until I fix the build error.
I will try to find the reason what happened and I'll update this post as soon as I can.
----------------------------------------------------------------------------------------------------------------
Finally, I found a solution to this error!
I simply edited/replaced the default msbuildproj file with the following:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="**/*.php" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Peachpie.Compiler.Tools" Version="0.7.0-*" />
<PackageReference Include="Peachpie.NET.Sdk" Version="0.7.0-*" PrivateAssets="Build" />
</ItemGroup>
<!-- A temporary solution, import C# Visual Studio design time targets in order to be able to load the project in Visual Studio -->
<PropertyGroup>
<CSharpDesignTimeTargetsPath Condition="'$(CSharpDesignTimeTargetsPath)'==''">$(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed\Microsoft.CSharp.DesignTime.targets</CSharpDesignTimeTargetsPath>
</PropertyGroup>
<Import Project="$(CSharpDesignTimeTargetsPath)" Condition="Exists('$(CSharpDesignTimeTargetsPath)')" />
</Project>
Then, I typed the dotnet restore ProjectName.msbuildproj command.
Once restore is completed, you can now run your application by typing dotnet run command.
20 July 2017
How do you render different layout in ASP.NET MVC
There are several ways to render different layout in ASP.NET MVC. I just give preference to the 2 ways below.
A. By defining the layout on the view. For example:
Placing the below code on top of Index.cshtml of AdminController
@{
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
then placing the below code on top of Index.cshtml of EmployeeController
@{
Layout = "~/Views/Shared/_EmployeeLayout.cshtml";
}
B. By identifying the controller and render the Layout per controller in a single _ViewStart file in the root directory of the Views folder. For example:
@{
var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
string layoutSelection = "";
if (controller == "Admin")
{
layoutSelection = "~/Views/Shared/_AdminLayout.cshtml";
}
else
{
layoutSelection = "~/Views/Shared/_EmployeeLayout.cshtml";
}
Layout = layoutSelection ;
}
A. By defining the layout on the view. For example:
Placing the below code on top of Index.cshtml of AdminController
@{
Layout = "~/Views/Shared/_AdminLayout.cshtml";
}
then placing the below code on top of Index.cshtml of EmployeeController
@{
Layout = "~/Views/Shared/_EmployeeLayout.cshtml";
}
B. By identifying the controller and render the Layout per controller in a single _ViewStart file in the root directory of the Views folder. For example:
@{
var controller = HttpContext.Current.Request.RequestContext.RouteData.Values["Controller"].ToString();
string layoutSelection = "";
if (controller == "Admin")
{
layoutSelection = "~/Views/Shared/_AdminLayout.cshtml";
}
else
{
layoutSelection = "~/Views/Shared/_EmployeeLayout.cshtml";
}
Layout = layoutSelection ;
}
14 July 2017
How to register and login a user using ASP.NET Identity and Owin with ASP.NET WebForm
I'll explain to you how to register a new user account and redirect the user to login page using ASP.NET Identity and OWIN.
Here are the simple steps that you may use.
First you need to create an empty WebForm application. In my example, I named it "IdentitySample".
Then, follow the below steps:
Step 1. Install the following NuGet packages:
Microsoft.AspNet.Identity.EntityFramework
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security.Cookies
Step 2. Add a Startup.cs class
using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;
[assembly: OwinStartup(typeof(IndentitySample.Startup))]
namespace IndentitySample
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login")
});
}
}
}
Step 3. Add connectionString in web.config file
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=dotnetguru;Initial Catalog=LoginDb;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
Step 4. Add a Registration page
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Register.aspx.cs" Inherits="IndentitySample.Register" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
<form id="form1" runat="server">
<div>
<h4 style="font-size: medium">Register a new user</h4>
<hr />
<div style="margin-bottom:10px">
<asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
<div>
<asp:TextBox runat="server" ID="UserName" />
</div>
</div>
<div style="margin-bottom:10px">
<asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
<div>
<asp:TextBox runat="server" ID="Password" TextMode="Password" />
</div>
</div>
<div style="margin-bottom:10px">
<asp:Label runat="server" AssociatedControlID="ConfirmPassword">Confirm password</asp:Label>
<div>
<asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" />
</div>
</div>
<div>
<div>
<asp:Button runat="server" OnClick="CreateUser_Click" Text="Register" />
</div>
</div>
<p>
<asp:Literal runat="server" ID="StatusMessage" />
</p>
</div>
</form>
</body>
</html>
Step 5. Modify Register.aspx.cs
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using System;
using System.Linq;
using System.Web;
namespace IndentitySample
{
public partial class Register : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void CreateUser_Click(object sender, EventArgs e)
{
// Default UserStore constructor uses the default connection string named: DefaultConnection
var userStore = new UserStore<IdentityUser>();
var manager = new UserManager<IdentityUser>(userStore);
var user = new IdentityUser() { UserName = UserName.Text };
IdentityResult result = manager.Create(user, Password.Text);
if (result.Succeeded)
{
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
var userIdentity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties() { }, userIdentity);
Response.Redirect("~/Login.aspx");
}
else
{
StatusMessage.Text = result.Errors.FirstOrDefault();
}
}
}
}
Step 6. Add a Login page
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="IndentitySample.Login" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
<form id="form1" runat="server">
<div>
<h4 style="font-size: medium">Log In</h4>
<hr />
<asp:PlaceHolder runat="server" ID="LoginStatus" Visible="false">
<p>
<asp:Literal runat="server" ID="StatusText" />
</p>
</asp:PlaceHolder>
<asp:PlaceHolder runat="server" ID="LoginForm" Visible="false">
<div style="margin-bottom: 10px">
<asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
<div>
<asp:TextBox runat="server" ID="UserName" />
</div>
</div>
<div style="margin-bottom: 10px">
<asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
<div>
<asp:TextBox runat="server" ID="Password" TextMode="Password" />
</div>
</div>
<div style="margin-bottom: 10px">
<div>
<asp:Button runat="server" OnClick="SignIn" Text="Log in" />
</div>
</div>
</asp:PlaceHolder>
<asp:PlaceHolder runat="server" ID="LogoutButton" Visible="false">
<div>
<div>
<asp:Button runat="server" OnClick="SignOut" Text="Log out" />
</div>
</div>
</asp:PlaceHolder>
</div>
</form>
</body>
</html>
Step 7. Modify the Login.aspx.cs
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using System;
using System.Web;
namespace IndentitySample
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (User.Identity.IsAuthenticated)
{
StatusText.Text = string.Format("Hello {0}!!", User.Identity.GetUserName());
LoginStatus.Visible = true;
LogoutButton.Visible = true;
}
else
{
LoginForm.Visible = true;
}
}
}
protected void SignIn(object sender, EventArgs e)
{
var userStore = new UserStore<IdentityUser>();
var userManager = new UserManager<IdentityUser>(userStore);
var user = userManager.Find(UserName.Text, Password.Text);
if (user != null)
{
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
var userIdentity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, userIdentity);
Response.Redirect("~/Login.aspx");
}
else
{
StatusText.Text = "Invalid username or password.";
LoginStatus.Visible = true;
}
}
protected void SignOut(object sender, EventArgs e)
{
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
authenticationManager.SignOut();
Response.Redirect("~/Login.aspx");
}
}
}
That's it!
Here are the simple steps that you may use.
First you need to create an empty WebForm application. In my example, I named it "IdentitySample".
Then, follow the below steps:
Step 1. Install the following NuGet packages:
Microsoft.AspNet.Identity.EntityFramework
Microsoft.Owin.Host.SystemWeb
Microsoft.Owin.Security.Cookies
Step 2. Add a Startup.cs class
using Microsoft.AspNet.Identity;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Owin;
[assembly: OwinStartup(typeof(IndentitySample.Startup))]
namespace IndentitySample
{
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Login")
});
}
}
}
Step 3. Add connectionString in web.config file
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=dotnetguru;Initial Catalog=LoginDb;Integrated Security=True"
providerName="System.Data.SqlClient" />
</connectionStrings>
Step 4. Add a Registration page
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Register.aspx.cs" Inherits="IndentitySample.Register" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
<form id="form1" runat="server">
<div>
<h4 style="font-size: medium">Register a new user</h4>
<hr />
<div style="margin-bottom:10px">
<asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
<div>
<asp:TextBox runat="server" ID="UserName" />
</div>
</div>
<div style="margin-bottom:10px">
<asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
<div>
<asp:TextBox runat="server" ID="Password" TextMode="Password" />
</div>
</div>
<div style="margin-bottom:10px">
<asp:Label runat="server" AssociatedControlID="ConfirmPassword">Confirm password</asp:Label>
<div>
<asp:TextBox runat="server" ID="ConfirmPassword" TextMode="Password" />
</div>
</div>
<div>
<div>
<asp:Button runat="server" OnClick="CreateUser_Click" Text="Register" />
</div>
</div>
<p>
<asp:Literal runat="server" ID="StatusMessage" />
</p>
</div>
</form>
</body>
</html>
Step 5. Modify Register.aspx.cs
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using System;
using System.Linq;
using System.Web;
namespace IndentitySample
{
public partial class Register : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void CreateUser_Click(object sender, EventArgs e)
{
// Default UserStore constructor uses the default connection string named: DefaultConnection
var userStore = new UserStore<IdentityUser>();
var manager = new UserManager<IdentityUser>(userStore);
var user = new IdentityUser() { UserName = UserName.Text };
IdentityResult result = manager.Create(user, Password.Text);
if (result.Succeeded)
{
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
var userIdentity = manager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties() { }, userIdentity);
Response.Redirect("~/Login.aspx");
}
else
{
StatusMessage.Text = result.Errors.FirstOrDefault();
}
}
}
}
Step 6. Add a Login page
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Login.aspx.cs" Inherits="IndentitySample.Login" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; font-size: small">
<form id="form1" runat="server">
<div>
<h4 style="font-size: medium">Log In</h4>
<hr />
<asp:PlaceHolder runat="server" ID="LoginStatus" Visible="false">
<p>
<asp:Literal runat="server" ID="StatusText" />
</p>
</asp:PlaceHolder>
<asp:PlaceHolder runat="server" ID="LoginForm" Visible="false">
<div style="margin-bottom: 10px">
<asp:Label runat="server" AssociatedControlID="UserName">User name</asp:Label>
<div>
<asp:TextBox runat="server" ID="UserName" />
</div>
</div>
<div style="margin-bottom: 10px">
<asp:Label runat="server" AssociatedControlID="Password">Password</asp:Label>
<div>
<asp:TextBox runat="server" ID="Password" TextMode="Password" />
</div>
</div>
<div style="margin-bottom: 10px">
<div>
<asp:Button runat="server" OnClick="SignIn" Text="Log in" />
</div>
</div>
</asp:PlaceHolder>
<asp:PlaceHolder runat="server" ID="LogoutButton" Visible="false">
<div>
<div>
<asp:Button runat="server" OnClick="SignOut" Text="Log out" />
</div>
</div>
</asp:PlaceHolder>
</div>
</form>
</body>
</html>
Step 7. Modify the Login.aspx.cs
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.Owin.Security;
using System;
using System.Web;
namespace IndentitySample
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (User.Identity.IsAuthenticated)
{
StatusText.Text = string.Format("Hello {0}!!", User.Identity.GetUserName());
LoginStatus.Visible = true;
LogoutButton.Visible = true;
}
else
{
LoginForm.Visible = true;
}
}
}
protected void SignIn(object sender, EventArgs e)
{
var userStore = new UserStore<IdentityUser>();
var userManager = new UserManager<IdentityUser>(userStore);
var user = userManager.Find(UserName.Text, Password.Text);
if (user != null)
{
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
var userIdentity = userManager.CreateIdentity(user, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = false }, userIdentity);
Response.Redirect("~/Login.aspx");
}
else
{
StatusText.Text = "Invalid username or password.";
LoginStatus.Visible = true;
}
}
protected void SignOut(object sender, EventArgs e)
{
var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;
authenticationManager.SignOut();
Response.Redirect("~/Login.aspx");
}
}
}
That's it!
13 July 2017
How to add friendly URL to your ASP.NET web application
First you need to install a NuGet package called Microsoft.AspNet.FriendlyUrl.
Then, add a class called RouteConfig.cs and make it similar to the codes below:
using System.Web.Routing;
using Microsoft.AspNet.FriendlyUrls;
namespace WebFormsIndentity
{
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
var settings = new FriendlyUrlSettings();
settings.AutoRedirectMode = RedirectMode.Permanent;
routes.EnableFriendlyUrls(settings);
routes.MapPageRoute("", "MyPage", "~/Page.aspx");
}
}
}
**Actually, you can add as many MapPageRoutes as you want in RegisterRoutes. JUst keep the first and second parameters unique.
Finally, in your Global Application class (Global.asax), add the following in the Application_Start() event:
protected void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
And TA-DA.... you now have an SEO-friendly URL!
Then, add a class called RouteConfig.cs and make it similar to the codes below:
using System.Web.Routing;
using Microsoft.AspNet.FriendlyUrls;
namespace WebFormsIndentity
{
public static class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
var settings = new FriendlyUrlSettings();
settings.AutoRedirectMode = RedirectMode.Permanent;
routes.EnableFriendlyUrls(settings);
routes.MapPageRoute("", "MyPage", "~/Page.aspx");
}
}
}
**Actually, you can add as many MapPageRoutes as you want in RegisterRoutes. JUst keep the first and second parameters unique.
Finally, in your Global Application class (Global.asax), add the following in the Application_Start() event:
protected void Application_Start(object sender, EventArgs e)
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
And TA-DA.... you now have an SEO-friendly URL!
11 July 2017
DB Context (ASP.NET MVC vs. ASP.NET Core MVC)
ASP.NET MVC
using System.Data.Entity;
public class ProfileContext : DbContext
{
public ProfileContext() : base("ProfileConnectionString")
{
}
public DbSet<Profile> Profiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Profile>().ToTable("Profile");
}
}
ASP.NET Core MVC
using Microsoft.EntityFrameworkCore;
public class ProfileContext : DbContext
{
public ProfileContext(DbContextOptions<ProfileContext> options) : base(options)
{
}
public DbSet<Profile> Profiles { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Profile>().ToTable("Profile");
}
}
using System.Data.Entity;
public class ProfileContext : DbContext
{
public ProfileContext() : base("ProfileConnectionString")
{
}
public DbSet<Profile> Profiles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Profile>().ToTable("Profile");
}
}
ASP.NET Core MVC
using Microsoft.EntityFrameworkCore;
public class ProfileContext : DbContext
{
public ProfileContext(DbContextOptions<ProfileContext> options) : base(options)
{
}
public DbSet<Profile> Profiles { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Profile>().ToTable("Profile");
}
}
Filtering a List of Results in ASP.NET MVC 5
Here's a simple example on how to filter results based on the given name:
Controller
public ActionResult Index(string searchValue)
{
var emp = db.Profiles.Select(y => y);
if (!String.IsNullOrEmpty(searchValue))
{
emp = emp.Where(y => y.Name.Contains(searchValue));
}
return View(emp);
}
View
@using (Html.BeginForm())
{
<p>
Search by name: @Html.TextBox("SearchValue")
<input type="submit" value="Search" />
</p>
}
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Age)
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
</tr>
}
</table>
Controller
public ActionResult Index(string searchValue)
{
var emp = db.Profiles.Select(y => y);
if (!String.IsNullOrEmpty(searchValue))
{
emp = emp.Where(y => y.Name.Contains(searchValue));
}
return View(emp);
}
View
@using (Html.BeginForm())
{
<p>
Search by name: @Html.TextBox("SearchValue")
<input type="submit" value="Search" />
</p>
}
<table class="table">
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.Age)
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
</tr>
}
</table>
Sorting a List of Results in ASP.NET MVC 5
Here's a simple example:
Controller
private ProfileContext db = new ProfileContext();
public ActionResult Index(string sortOrder)
{
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name" : "";
ViewBag.AgeSortParm = sortOrder == "Age" ? "age" : "Age";
var emp = db.Profiles.Select(y => y);
switch (sortOrder)
{
case "name":
emp = emp.OrderByDescending(y => y.Name);
break;
case "age":
emp = emp.OrderByDescending(y => y.Age);
break;
default:
emp = emp.OrderBy(y => y.Name);
break;
}
return View(emp);
}
View
<table class="table">
<tr>
<th>
@Html.ActionLink("Name", "Index", new { sortOrder = ViewBag.NameSortParm })
</th>
<th>
@Html.ActionLink("Age", "Index", new { sortOrder = ViewBag.AgeSortParm })
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
</tr>
}
</table>
Controller
private ProfileContext db = new ProfileContext();
public ActionResult Index(string sortOrder)
{
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name" : "";
ViewBag.AgeSortParm = sortOrder == "Age" ? "age" : "Age";
var emp = db.Profiles.Select(y => y);
switch (sortOrder)
{
case "name":
emp = emp.OrderByDescending(y => y.Name);
break;
case "age":
emp = emp.OrderByDescending(y => y.Age);
break;
default:
emp = emp.OrderBy(y => y.Name);
break;
}
return View(emp);
}
View
<table class="table">
<tr>
<th>
@Html.ActionLink("Name", "Index", new { sortOrder = ViewBag.NameSortParm })
</th>
<th>
@Html.ActionLink("Age", "Index", new { sortOrder = ViewBag.AgeSortParm })
</th>
</tr>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.Age)
</td>
</tr>
}
</table>
06 July 2017
When you connect to the database and it throws: "ArgumentNullException: Value cannot be null. Parameter name: connectionString"
Microsoft.EntityFrameworkCore.SqlServerDbContextOptionsExtensions.UseSqlServer(DbContextOptionsBuilder optionsBuilder, string connectionString, Action<SqlServerDbContextOptionsBuilder> sqlServerOptionsAction)
SampleProject.Startup.<ConfigureServices>b__3_0(DbContextOptionsBuilder options) in Startup.cs
It only means you're trying to connect to the database without first "building" the configuration of the appsettings.json with the hosting environment.
The solution to this is to add the following to your Startup class:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
SampleProject.Startup.<ConfigureServices>b__3_0(DbContextOptionsBuilder options) in Startup.cs
It only means you're trying to connect to the database without first "building" the configuration of the appsettings.json with the hosting environment.
The solution to this is to add the following to your Startup class:
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
.AddEnvironmentVariables();
Configuration = builder.Build();
}
05 July 2017
'No executable found matching command "dotnet-aspnet-codegenerator"'
When I created a new controller with the built in scaffolding, I got the following error:
'No executable found matching command "dotnet-aspnet-codegenerator"'
To resolve the issue, I just edited the .csproj file and added the following:
<ItemGroup> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" /> </ItemGroup>
Then, everything worked fine.
'No executable found matching command "dotnet-aspnet-codegenerator"'
To resolve the issue, I just edited the .csproj file and added the following:
<ItemGroup> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" /> </ItemGroup>
Then, everything worked fine.
04 July 2017
ArgumentNullException: Value cannot be null. Parameter name: connectionString
So I posted it.
It happened to me twice this morning.
In my first thought, I said, "What?"
On my second attempt, I still got the same error.
And I said to myself, "What the f*?"
Then, finally I found that in my appSettings.json, I misspelled the ConnectionStrings to ConnectionString.
Now, I realize that too much coffee is not a replacement to lack of sleep and not an excuse for stupidity, lol!
Anyway, I'm just having fun working on my dotNet Core project 😁
It happened to me twice this morning.
In my first thought, I said, "What?"
On my second attempt, I still got the same error.
And I said to myself, "What the f*?"
Then, finally I found that in my appSettings.json, I misspelled the ConnectionStrings to ConnectionString.
Now, I realize that too much coffee is not a replacement to lack of sleep and not an excuse for stupidity, lol!
Anyway, I'm just having fun working on my dotNet Core project 😁
03 July 2017
'EntityTypeBuilder' does not contain a definition for 'ToTable'
While utilizing the EF 7 with dotNet core apps, I got an error that says:
'EntityTypeBuilder<T>' does not contain a definition for 'ToTable' and no extension method 'ToTable' accepting a first argument of type 'EntityTypeBuilder<T>' could be found ....
Installing the Nuget package Microsoft.EntityframeworkCore.SqlServer solved the issue.
'EntityTypeBuilder<T>' does not contain a definition for 'ToTable' and no extension method 'ToTable' accepting a first argument of type 'EntityTypeBuilder<T>' could be found ....
Installing the Nuget package Microsoft.EntityframeworkCore.SqlServer solved the issue.
30 June 2017
'DbContextOptionsBuilder' does not contain a definition for 'UseSqlServer'
When you try to connect to SQL Server database using Entity Framework and you got the following error message:
'DbContextOptionsBuilder' does not contain a definition for 'UseSqlServer' and no extension method 'UseSqlServer' accepting a first argument of type 'DbContextOptionsBuilder' could be found .....
'DbContextOptionsBuilder' does not contain a definition for 'UseSqlServer' and no extension method 'UseSqlServer' accepting a first argument of type 'DbContextOptionsBuilder' could be found .....
A simple way to get around with this error is to simply add or install a NuGet package Microsoft.Entityframeworkcore.Sqlserver
19 June 2017
HTTP Error 403.14 - Forbidden
When I published my web application this morning, I got this Error:
Luckily, I remembered the one-liner script that I added to web.config 2 years ago when I experienced the same error when I published and deployed my ASP.NET MVC application for one of my clients.
Okay, to fix this error, simply add the script below to your web.config file:
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
Luckily, I remembered the one-liner script that I added to web.config 2 years ago when I experienced the same error when I published and deployed my ASP.NET MVC application for one of my clients.
Okay, to fix this error, simply add the script below to your web.config file:
<system.webServer>
<directoryBrowse enabled="true" />
</system.webServer>
16 June 2017
15 June 2017
Detect Changes Automatically with dotnet watch
Whenever you're running a .NET Core application and you want to detect source file changes and restart the app automatically, simply use dotnet watch command.
Just add Microsoft.DotNet.Watcher.Tools to the .csproj file like the one below:
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0-msbuild3-final" />
</ItemGroup>
Then, run the dotnet restore command to add the package to your project.
Next time you run your application, just add watch to your command like: dotnet watch run to detect changes and restart your application automatically.
Just add Microsoft.DotNet.Watcher.Tools to the .csproj file like the one below:
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0-msbuild3-final" />
</ItemGroup>
Then, run the dotnet restore command to add the package to your project.
Next time you run your application, just add watch to your command like: dotnet watch run to detect changes and restart your application automatically.
14 June 2017
Work as a Dev Coach for .NET projects
Just an ordinary day as a development coach of Grosvik Phil., Inc., a startup company in Makati City, Philippines.
13 June 2017
ASP.NET Core rocks!
Yeah, ASP.NET Core really rocks!!!
After topping the TechEmpower plaintext benchmarks in November 2016, ASP.NET Core 2 now offers more performance improvements by reducing application startup time once your app is published.
You may try ASP.NET Core 2.0.0-preview and see for yourself.
After topping the TechEmpower plaintext benchmarks in November 2016, ASP.NET Core 2 now offers more performance improvements by reducing application startup time once your app is published.
You may try ASP.NET Core 2.0.0-preview and see for yourself.
08 May 2017
How Do We Get The Parameter Value from a URL?
Here's a quick and easy way to read and display the paramater value from a URL.
Ex:
var sampleUri = new Uri("http://www.mysite.com/default.aspx?ID=21");
string getParam = HttpUtility.ParseQueryString(sampleUri.Query).Get("ID");
Ex:
var sampleUri = new Uri("http://www.mysite.com/default.aspx?ID=21");
string getParam = HttpUtility.ParseQueryString(sampleUri.Query).Get("ID");
20 April 2017
System.InvalidCastException: Specified cast is not valid.
When you try to map bigint in SQL to int in C#, you will get an error equivalent to "System.InvalidCastException: Specified cast is not valid."
You need to map the bigint to long, which is equal to 64-bit integer in C# or Int64, because Int32 cannot store the maximum value of bigint.
You need to map the bigint to long, which is equal to 64-bit integer in C# or Int64, because Int32 cannot store the maximum value of bigint.
19 April 2017
How To Find Duplicate Record in SQL
Whenever I need to delete duplicate records in database, I try to find them first and identify the number of times the same row occurs.
Here's a simple way to find them:
SELECT Name, Age, COUNT(*) AS NoOfDuplicateRecords
FROM Table_Name
GROUP BY Name, Age
HAVING COUNT(*) > 1
Here's a simple way to find them:
SELECT Name, Age, COUNT(*) AS NoOfDuplicateRecords
FROM Table_Name
GROUP BY Name, Age
HAVING COUNT(*) > 1
11 April 2017
How lock(obj) Method Works
I once had a requirement to generate a random integer number from let's say 0 to 10 million. Here's what I did:
public static int GetRandomNumber(int min, int max)
{
lock (obj)
{
//some codes for calling Random method is omitted for brevity
}
}
I used lock statement to ensure that the object was locked by the first thread and released the object first before another thread to lock the same object.
I think lock is more concise that using a monitor class in blocking the thread.
public static int GetRandomNumber(int min, int max)
{
lock (obj)
{
//some codes for calling Random method is omitted for brevity
}
}
I used lock statement to ensure that the object was locked by the first thread and released the object first before another thread to lock the same object.
I think lock is more concise that using a monitor class in blocking the thread.
10 April 2017
Uploading An Image File with Unique Filename and Save It In A Folder
I just have a requirement to upload an image file in a folder named "UploadedFiles" and replace its file extension from ".whateverFileExtension" to ".jpg".
And to ensure that each picture will have a unique (or at least have a higher probability of a unique filename), I will use SyncLock method and Random class to generate random number (ex. from 1 to 10,000,000) and assign the auto-generated number to every uploaded picture.
Below is my sample code:
<HTML>
<input type="file" id="fileUpload" runat="server" />
<input type="submit" id="btnUploadFile" runat="server" value="Upload" onserverclick="btnUploadFile_OnServerClick" />
<CODE BEHIND>
private string _myRandomNumber;
private static readonly Random Random = new Random();
private static readonly object SyncLock = new object();
public static int RandomNumber(int min, int max)
{
lock (SyncLock)
{
return Random.Next(min, max);
}
}
protected void btnUploadFile_OnServerClick(object sender, EventArgs e)
{
_myRandomNumber = RandomNumber(0, 10000000).ToString("D");
int newPictureId = Int32.Parse(_myRandomNumber);
string baseDirectory = Server.MapPath("~/UploadedFiles/");
fileUpload.PostedFile.SaveAs((baseDirectory + (newPictureId + ".jpg")));
}
07 April 2017
How Do You Validate Input Date Programmatically?
When validating a date, I recommend that you use both the client-side and the server side techniques. For client-side, you can use native JS or any JS framework available. For the server-side, you can do it programmatically such as the below sample:
<ASPX page>
Enter a date: <input type="date" id="txtExpirationDate" runat="server" required="" />
<p></p>
<label id="lblMessage" runat="server"></label>
<CODE BEHIND>
DateTime validDate;
if (DateTime.TryParse(txtExpirationDate.Value, out validDate))
{
//some code goes here
}
else
{
lblMessage.InnerText = "You entered an invalid date.";
}
<ASPX page>
Enter a date: <input type="date" id="txtExpirationDate" runat="server" required="" />
<p></p>
<label id="lblMessage" runat="server"></label>
<CODE BEHIND>
DateTime validDate;
if (DateTime.TryParse(txtExpirationDate.Value, out validDate))
{
//some code goes here
}
else
{
lblMessage.InnerText = "You entered an invalid date.";
}
05 April 2017
How To Use HTML's Map Area with Pure JavaScript
If you're looking for an easier way to create a clickable area/s in the image (or image map), you might consider using the HTML's <map> tag and JavaScript.
Example:
<!DOCTYPE html>
<html>
<head>
<title>
Sample Use of Map Area with JavaScript
</title>
<script>
function writeText(txt) {
document.getElementById("AboutTheLocation").innerHTML = txt;
}
</script>
</head>
<body>
<map name="targetLocation">
<area shape="poly" coords="74,261,49,250,80,103,117,113" onmouseover="writeText('My home is located somewhere here.')" onmouseout="writeText('')" />
<map name="targetLocation">
<area shape="circle" coords="124,58,8" onmouseover="writeText('My office is located somewhere here.')" onmouseout="writeText('')" />
<img src ="vs.png" alt="Visual Studio" usemap="#targetLocation" width="145" height="126" />
<p></p>
<p id="AboutTheLocation"></p>
</body>
</html>
Example:
<!DOCTYPE html>
<html>
<head>
<title>
Sample Use of Map Area with JavaScript
</title>
<script>
function writeText(txt) {
document.getElementById("AboutTheLocation").innerHTML = txt;
}
</script>
</head>
<body>
<map name="targetLocation">
<area shape="poly" coords="74,261,49,250,80,103,117,113" onmouseover="writeText('My home is located somewhere here.')" onmouseout="writeText('')" />
<map name="targetLocation">
<area shape="circle" coords="124,58,8" onmouseover="writeText('My office is located somewhere here.')" onmouseout="writeText('')" />
<img src ="vs.png" alt="Visual Studio" usemap="#targetLocation" width="145" height="126" />
<p></p>
<p id="AboutTheLocation"></p>
</body>
</html>
In Response.Redirect("URL"), Should We Use True or False?
Response.Redirect("URL", true);
or
Response.Redirect("URL", false);
Did you know that using true or false is just a matter of how you control the logic flow of your code? We use true to abort the thread so that nothing will execute once you redirect the page. Then, we use false when you don't want to abort the thread after the Response.Redirect executes.
For some developers, using true is considered a bad practice because it's a sign that you have no control on your code's logic and you're simply aborting the thread and the application will not continue when an error arises.
But the funny thing is that I've seen a lot of developers not putting either true or false whenever they use Response.Redirect and keep saying that using true is not a good practice. But the truth is that when you don't declare a false value, "true" is the default when you use Response.Redirect.
or
Response.Redirect("URL", false);
Did you know that using true or false is just a matter of how you control the logic flow of your code? We use true to abort the thread so that nothing will execute once you redirect the page. Then, we use false when you don't want to abort the thread after the Response.Redirect executes.
For some developers, using true is considered a bad practice because it's a sign that you have no control on your code's logic and you're simply aborting the thread and the application will not continue when an error arises.
But the funny thing is that I've seen a lot of developers not putting either true or false whenever they use Response.Redirect and keep saying that using true is not a good practice. But the truth is that when you don't declare a false value, "true" is the default when you use Response.Redirect.
04 April 2017
Should I go to Parameters.Add or to a simplified Parameters.AddWithValue?
For some developers, choosing between the two is just a matter of preferences because in fact there is no difference in terms of functionality between these two.
I disagree.
Providing only the type Parameters.AddWithValue, the compiler will just try to implicitly convert the input parameter to what is expected and it may cause you a performance issue.
I disagree.
Providing only the type Parameters.AddWithValue, the compiler will just try to implicitly convert the input parameter to what is expected and it may cause you a performance issue.
How To Add Google Map with Marker in Pure JavaScript
Okay, I said 'pure' JavaScript. Forgive me if I use a few CSS lines.
Here's my sample webpage displaying a Google map and our sample offices in Norway and in Makati City (Philippines):
<!DOCTYPE html>
<html>
<head>
<title>Sample Google Map with Marker</title>
<style type="text/css">
#place_map_here {
height: 500px;
width: 1000px;
}
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script>
function initialize() {
var pointDestinations = [
{
lat: 61.792135,
lon: 8.381478,
title: "Grosvik Norway",
description: "Norway office"
},
{
lat: 14.557985,
lon: 121.023870,
title: "Grosvik Phils.",
description: "Makati office"
}
];
var initialLocation = {
zoom: 2,
center: new google.maps.LatLng(61.792135, 8.381478),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("place_map_here"), initialLocation);
var infoAboutThePlace = new google.maps.InfoWindow({
content: ''
});
var y;
for (y = 0; y < pointDestinations.length; y++) {
var marker = new google.maps.Marker({
title: pointDestinations[y].title,
position: new google.maps.LatLng(pointDestinations[y].lat, pointDestinations[y].lon),
map: map
});
markerAndInformationBinder(marker, map, infoAboutThePlace, "<p>" + pointDestinations[y].description + "</p>");
}
}
function markerAndInformationBinder(marker, map, infoAboutThePlace, html) {
google.maps.event.addListener(marker, 'click', function () {
infoAboutThePlace.setContent(html);
infoAboutThePlace.open(map, marker);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="place_map_here"></div>
</body>
</html>
Here's my sample webpage displaying a Google map and our sample offices in Norway and in Makati City (Philippines):
<!DOCTYPE html>
<html>
<head>
<title>Sample Google Map with Marker</title>
<style type="text/css">
#place_map_here {
height: 500px;
width: 1000px;
}
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script>
function initialize() {
var pointDestinations = [
{
lat: 61.792135,
lon: 8.381478,
title: "Grosvik Norway",
description: "Norway office"
},
{
lat: 14.557985,
lon: 121.023870,
title: "Grosvik Phils.",
description: "Makati office"
}
];
var initialLocation = {
zoom: 2,
center: new google.maps.LatLng(61.792135, 8.381478),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("place_map_here"), initialLocation);
var infoAboutThePlace = new google.maps.InfoWindow({
content: ''
});
var y;
for (y = 0; y < pointDestinations.length; y++) {
var marker = new google.maps.Marker({
title: pointDestinations[y].title,
position: new google.maps.LatLng(pointDestinations[y].lat, pointDestinations[y].lon),
map: map
});
markerAndInformationBinder(marker, map, infoAboutThePlace, "<p>" + pointDestinations[y].description + "</p>");
}
}
function markerAndInformationBinder(marker, map, infoAboutThePlace, html) {
google.maps.event.addListener(marker, 'click', function () {
infoAboutThePlace.setContent(html);
infoAboutThePlace.open(map, marker);
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="place_map_here"></div>
</body>
</html>
03 April 2017
How To Enable Paging in ListView
I know it's a bit old, but there are newbies who still had difficulty in adding a pager in their ListView control. So I think that justifies why I should post this blog.
If for example you add a DataPager in you ListView's LayoutTemplate
<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" PageSize="5">
<Fields>
<asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="false" ShowPreviousPageButton="true" ShowNextPageButton="false" /> <asp:NumericPagerField ButtonType="Link" />
<asp:NextPreviousPagerField ButtonType="Link" ShowNextPageButton="true" ShowLastPageButton="false" ShowPreviousPageButton="false" />
</Fields>
</asp:DataPager>
If for example you add a DataPager in you ListView's LayoutTemplate
<asp:DataPager ID="DataPager1" runat="server" PagedControlID="ListView1" PageSize="5">
<Fields>
<asp:NextPreviousPagerField ButtonType="Link" ShowFirstPageButton="false" ShowPreviousPageButton="true" ShowNextPageButton="false" /> <asp:NumericPagerField ButtonType="Link" />
<asp:NextPreviousPagerField ButtonType="Link" ShowNextPageButton="true" ShowLastPageButton="false" ShowPreviousPageButton="false" />
</Fields>
</asp:DataPager>
First, you need to set the OnPagePropertiesChanging="OnPagePropertiesChanging" on your ListView properties like:
<asp:ListView ID="ListView1" runat="server" OnPagePropertiesChanging="OnPagePropertiesChanging">
Then, from code behind you can do the following:
protected void OnPagePropertiesChanging(object sender, PagePropertiesChangingEventArgs e)
{
(ListView1.FindControl("DataPager1") as DataPager).SetPageProperties(e.StartRowIndex, e.MaximumRows, false);
//call your method in displaying the list
}
31 March 2017
How To Validate User Input Using Native JavaScript
In the presence of numerous JS frameworks and 'drag n drop' features, I just found that some graduating students of computer science can't write a simple user input validation using a pure JavaScript. What even bothered me was that some web developers can't even write a simple JS script without searching from Google or without using the so-called 'copy-paste programming'!
Okay, I'll just share with you a very simple and neat way to validate a required text entry using our native JavaScript:
Name: <input type="text" id="txtName" /><br/>
<input type="button" id="btnSubmit" onclick ="javascript:validate()" value="Submit" />
<script type="text/javascript">
function validate()
{
if (document.getElementById("txtName").value=="")
{
alert("Name is required.");
document.getElementById("txtName").focus();
return false;
}
return true;
}
</script>
Okay, I'll just share with you a very simple and neat way to validate a required text entry using our native JavaScript:
Name: <input type="text" id="txtName" /><br/>
<input type="button" id="btnSubmit" onclick ="javascript:validate()" value="Submit" />
<script type="text/javascript">
function validate()
{
if (document.getElementById("txtName").value=="")
{
alert("Name is required.");
document.getElementById("txtName").focus();
return false;
}
return true;
}
</script>
28 March 2017
How To Pass Querystring From One Page to Another Using JavaScript
I used to pass QueryString from one ASP.NET page to another using Hyperlink control. But since I had a requirement to pass the Querystring using pure JavaScript, I used the following code:
<script type="text/javascript">
$(function () {
$("#btnSend").bind("click", function () {
var url = "SecondPage.aspx?name=" + encodeURIComponent($("#txtInput").val());
window.location.href = url;
});
});
</script>
Enter string message: <input type="text" id="txtInput"/>
<input type="button" id="btnSend" value="Submit" />
<script type="text/javascript">
$(function () {
$("#btnSend").bind("click", function () {
var url = "SecondPage.aspx?name=" + encodeURIComponent($("#txtInput").val());
window.location.href = url;
});
});
</script>
Enter string message: <input type="text" id="txtInput"/>
<input type="button" id="btnSend" value="Submit" />
27 March 2017
How To Disable Bootstrap Modal Window from Closing
In any ordinary day when I need to disable the bootstrap modal window from closing due to my client requirement, I simply make the backdrop to 'static' and set the keyboard property to 'false' like the below sample:
<script type="text/javascript">
$('#sampleModal').modal({
backdrop: 'static',
keyboard: false
});
</script>
<div class="modal fade" id="sampleModal" tabindex="-1" role="dialog" aria-labelledby="sampleModalLabel" aria-hidden="true">
//some text are omitted here for brevity....
</div>
<script type="text/javascript">
$('#sampleModal').modal({
backdrop: 'static',
keyboard: false
});
</script>
<div class="modal fade" id="sampleModal" tabindex="-1" role="dialog" aria-labelledby="sampleModalLabel" aria-hidden="true">
//some text are omitted here for brevity....
</div>
Autocomplete with Ajax and JSON
Autocomplete with Ajax and JSON is as simple as this:
In your ASPX page:
<script type="text/javascript">
$(function () {
$("[id$=txtLastNameSearch]").autocomplete({
source: function (request, response) {
$.ajax({
url: '<%=ResolveUrl("Home.aspx/GetLastName") %>',
data: "{ 'prefix': '" + request.term + "'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data.d, function(item) {
return {
label: item.split('-')[0],
val: item.split('-')[1]
}
}));
},
error: function (response) {
alert(response.responseText);
},
failure: function (response) {
alert(response.responseText);
}
});
},
select: function (e, i) {
$("[id$=LastName]").val(i.item.val);
},
minLength: 3
});
});
</script>
Enter Last Name: <asp:TextBox ID="txtLastNameSearch" runat="server" />
<asp:HiddenField ID="LastName" runat="server" />
And in your code behind:
[WebMethod]
public static string[] GetLastName(string prefix)
{
var lastName = new List<string>();
using (SqlConnection conn = new SqlConnection())
{
conn.ConnectionString = ConfigurationManager.ConnectionStrings["YourConnectionString"].ConnectionString;
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "SELECT LastName FROM tbl_Profile WHERE LastName LIKE @SearchText + '%'";
cmd.Parameters.AddWithValue("@SearchText", prefix);
cmd.Connection = conn;
conn.Open();
using (SqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
lastName.Add(sdr["LastName"].ToString());
}
}
conn.Close();
}
}
return lastName.ToArray();
}
05 March 2017
Unit Testing the ASP.NET WebForm (Part 2)
In Unit Testing the ASP.NET WebForm (Part 1), I showed you how to unit test the Create method in our data model or class. This time, I'll show you a simple way to unit test the Generic List<T> method in displaying records from the database and bind the result to GridView.
** Test Class **
[TestClass]
class ProfileTests
{
[TestMethod]
public void Get_All_Profile()
{
//Arrange
var profile = new List<Profile>();
//Act
var results = ProfileData.Get_All_Profile();
//Assert
Assert.IsTrue(profile.SequenceEqual(results));
Assert.IsNotNull(results);
}
}
** Data Model **
public static List<Profile> Get_All_Profile()
{
var profile = new List<Profile>();
using (var con = new SqlConnection(WebConfigurationManager.ConnectionStrings["ProfileConnectionString"].ConnectionString))
{
string strSelect = "SELECT Name, Age FROM Profile";
var cmd = new SqlCommand(strSelect, con);
con.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
var result = new Profile
{
Name = reader.GetString(0),
Age = reader.GetDecimal(1)
};
profile.Add(result);
}
reader.Close();
}
return profile;
}
** Business Model **
public class Profile
{
public int ProfileId { get; set; }
public string Name { get; set; }
public decimal Age { get; set; }
}
** Code Behind **
void Display_Profile()
{
Profiles = ProfileData.Get_All_Profile();
GridView1.DataSource = Profiles.ToList();
GridView1.DataBind();
}
** Test Class **
[TestClass]
class ProfileTests
{
[TestMethod]
public void Get_All_Profile()
{
//Arrange
var profile = new List<Profile>();
//Act
var results = ProfileData.Get_All_Profile();
//Assert
Assert.IsTrue(profile.SequenceEqual(results));
Assert.IsNotNull(results);
}
}
** Data Model **
public static List<Profile> Get_All_Profile()
{
var profile = new List<Profile>();
using (var con = new SqlConnection(WebConfigurationManager.ConnectionStrings["ProfileConnectionString"].ConnectionString))
{
string strSelect = "SELECT Name, Age FROM Profile";
var cmd = new SqlCommand(strSelect, con);
con.Open();
var reader = cmd.ExecuteReader();
while (reader.Read())
{
var result = new Profile
{
Name = reader.GetString(0),
Age = reader.GetDecimal(1)
};
profile.Add(result);
}
reader.Close();
}
return profile;
}
** Business Model **
public class Profile
{
public int ProfileId { get; set; }
public string Name { get; set; }
public decimal Age { get; set; }
}
** Code Behind **
void Display_Profile()
{
Profiles = ProfileData.Get_All_Profile();
GridView1.DataSource = Profiles.ToList();
GridView1.DataBind();
}
Unit Testing the ASP.NET WebForm (Part 1)
Unit testing an ASP.NET Webform gives us more challenging job than a loosely coupled MVC. In practice, we just unit test custom controls and the methods that perform actual logic. In doing so, we try to minimize the code behind and put all those logic in separate libraries or classes.
In my example below, I try to write a unit test (using MSTest) on a method that inserts a new record to the database:
** Test Class **
[TestClass]
class ProfileTests
{
[TestMethod]
public void Create_New_Profile_Should_Save_New_Record()
{
//Arrange
var content = new Profile { ProfileId = 1, Name = "Bob", Age = 21m};
//Act
var results = ProfileData.Create_New_Profile(content);
//Assert
Assert.IsNotNull(results);
}
}
** Data Model **
public class ProfileData
{
public static Profile Create_New_Profile(Profile profiles)
{
using (var con = new SqlConnection(WebConfigurationManager.ConnectionStrings["ProfileConnectionString"].ConnectionString))
{
string strInsert = "INSERT INTO Profile (Name, Age) VALUES(@Name, @Age)";
var cmd = new SqlCommand(strInsert, con);
cmd.Parameters.AddWithValue("@Name", profiles.Name);
cmd.Parameters.AddWithValue("Age", profiles.Age);
con.Open();
var profile = new Profile
{
Name = profiles.Name,
Age = profiles.Age
};
cmd.ExecuteNonQuery();
con.Close();
return profile;
}
}
}
** Business Model **
public class Profile
{
public int ProfileId { get; set; }
public string Name { get; set; }
public decimal Age { get; set; }
}
** Code Behind **
protected void btnSave_Click(object sender, EventArgs e)
{
var profile = new Profile
{
Name = txtName.Text,
Age = Decimal.Parse(txtAge.Text)
};
Profiles = ProfileData.Create_New_Profile(profile);
}
In my example below, I try to write a unit test (using MSTest) on a method that inserts a new record to the database:
** Test Class **
[TestClass]
class ProfileTests
{
[TestMethod]
public void Create_New_Profile_Should_Save_New_Record()
{
//Arrange
var content = new Profile { ProfileId = 1, Name = "Bob", Age = 21m};
//Act
var results = ProfileData.Create_New_Profile(content);
//Assert
Assert.IsNotNull(results);
}
}
** Data Model **
public class ProfileData
{
public static Profile Create_New_Profile(Profile profiles)
{
using (var con = new SqlConnection(WebConfigurationManager.ConnectionStrings["ProfileConnectionString"].ConnectionString))
{
string strInsert = "INSERT INTO Profile (Name, Age) VALUES(@Name, @Age)";
var cmd = new SqlCommand(strInsert, con);
cmd.Parameters.AddWithValue("@Name", profiles.Name);
cmd.Parameters.AddWithValue("Age", profiles.Age);
con.Open();
var profile = new Profile
{
Name = profiles.Name,
Age = profiles.Age
};
cmd.ExecuteNonQuery();
con.Close();
return profile;
}
}
}
** Business Model **
public class Profile
{
public int ProfileId { get; set; }
public string Name { get; set; }
public decimal Age { get; set; }
}
** Code Behind **
protected void btnSave_Click(object sender, EventArgs e)
{
var profile = new Profile
{
Name = txtName.Text,
Age = Decimal.Parse(txtAge.Text)
};
Profiles = ProfileData.Create_New_Profile(profile);
}
Subscribe to:
Posts (Atom)