Monday, October 16, 2017

Ajax.ActionLink() not redirecting to ActionResult with Ajax Attribute

Given that I have this code in my .cshtml page using Ajax.ActionLink() that calls a controller method using Ajax request:
@Ajax.ActionLink("Select", "TaskListing", new { id = item.TaskID }, 
   new AjaxOptions(){ 
    HttpMethod = "GET",
    UpdateTargetId = "taskListing",
    InsertionMode = InsertionMode.Replace
})
And the controller method called by the Ajax ActionLink is decorated with Ajax attribute.
[HttpGet]
[AjaxOnly(true)]
[ActionName("TaskListing")]
public ActionResult TaskListing_Ajax(int id = -1)
{
 var projects = projRep.GetAllProjects();
 var model = new TaskAndTaskViewModel();
 model.Task = te.Tasks.FirstOrDefault(t => t.TaskID == id);
 model.SelectList = from p in projRep.GetAllProjects()
        select new SelectListItem
        {
         Selected = (p.ProjectID == Convert.ToInt32(model.Task.ProjectID)),
         Text = p.ProjectName.ToString(),
         Value = p.ProjectID.ToString()
        };

 return PartialView("TaskForm", model);
}
Normally, the request would push through. If does not proceed, maybe you have not added the Microsoft JQuery Unobtrusive Ajax to your project. Downloading and installing the said package(Microsoft JQuery Unobtrusive Ajax) via NuGet might fix the problem.

Sunday, October 8, 2017

Read .NET configuration files using NameValueSectionHandler and AppSettingsSection Types

Hello all,
I've read from a tutorial NameValueCollection and .NET Configuration Files which targets .NET 1.0/1.1 regarding type NameValueSectionHandler. I intend to explore more on applying this concept to recent versions of .NET frameworks. Upon doing some diggings, I came up with two options. First is using NameValueSectionHandler type and the other one is AppSettingsSections. To begin with, I have this App.config file with XML elements scriptsfiles and docfiles all registered in configSections.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="scriptfiles" type="System.Configuration.NameValueSectionHandler"/>
    <section name="docfiles" type="System.Configuration.AppSettingsSection"/>
  </configSections>
  <scriptfiles>
    <add key="C:\batchfiles\2017" value="*.bat" />
    <add key="C:\vbs\2017" value="*.vbs" />
  </scriptfiles>
  <docfiles>
    <add key="C:\applicants\2017" value="*.doc" />
    <add key="C:\officemanuals\2017" value="*.pdf" />
  </docfiles>
  <startup> 
      <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
  </startup> 
</configuration>
If you noticed, each sections are declared with different types specifically NameValueSectionHandler and AppSettingsSection and node structures are similar. To read the element with type NameValueSectionHandler we use the ConfigurationManager.GetSection() method.
C# Code
private static void ReadNameValueSectionHandler()
{
 Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);            
 NameValueCollection scriptFiles = (NameValueCollection)ConfigurationManager.GetSection(config.GetSection("scriptfiles").SectionInformation.SectionName);
 foreach (var item in scriptFiles.AllKeys)
 {
  Console.WriteLine(String.Format("Key:{0}, value:{1}", item, scriptFiles[item]));
 }
}
For the element with AppSettingsSection type we simply cast the ConfigurationSection object to AppSettingsSection.
C# Code
private static void ReadAppSettingsSection()
{
 Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
 ConfigurationSection section = config.GetSection("docfiles");
 var scriptSettings = ((AppSettingsSection)section).Settings;    

 foreach (var item in scriptSettings.AllKeys)
 {
  Console.WriteLine(String.Format("Key:{0}, value:{1}", item, scriptSettings[item].Value));
 }
}

Saturday, October 7, 2017

Cannot convert type 'System.Configuration.ConfigurationSection' to 'System.Collections.Specialized.NameValueCollection'

Good evening!
I've tried casting the config object to NameValueCollection using .NET Framework 4.5.2 of Visual Studio 2015 which I read from a tutorial on how to read config files using type NameValueSectionHandler. However, as I use the code below to cast the ConfigurationSection object to NameValueCollection,
C# Code
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
NameValueCollection scriptFiles = (NameValueCollection)config.GetSection("scriptfiles");
I get an error which is the title of this post. It seems that the code was applicable to older versions of .NET Framework and not the recent ones.
After doing some research, I found out that the workaround is to use ConfigurationManager.GetSection() in which the parameter passed is the SectionName of the config object instead of directly casting the ConfigurationSection object returned by the config.GetSection() method.
C# Code
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);            
NameValueCollection scriptFiles = (NameValueCollection)ConfigurationManager.GetSection(config.GetSection("scriptfiles").SectionInformation.SectionName);            
Output That's it!

Friday, October 6, 2017

Call Stored Procedures from Entity Framework in ASP.NET MVC

Good day!
Here's an ASP.NET MVC example of a CRUD(Create/Update/Delete) application using stored procedures and Entity Framework 6.First, you need to perform steps 1-3 from this link Call Stored Procedures from Entity Framework 6 in C# (Part 1). For step 3, instead of creating a console application use ASP.NET MVC Empty project. Once done, the code for the controller and views are shown below:
CustomersController
private CustomerEntities db = new CustomerEntities();

// GET: Customers
public ActionResult Index()
{
 return View(db.Database.SqlQuery<Customer>("GetAllCustomers").ToList());
}

// GET: Customers/Create
public ActionResult Create()
{
 return View();
}

// POST: Customers/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "CompanyName,ContactName,Address,Country,Phone")] Customer customer)
{
 if (ModelState.IsValid)
 {
  db.Database.ExecuteSqlCommand("EXEC dbo.InsertCustomer @CompanyName,@ContactName,@Address,@Country,@Phone",
   new SqlParameter("CompanyName",customer.CompanyName),
   new SqlParameter("ContactName", customer.ContactName),
   new SqlParameter("Address", customer.Address),
   new SqlParameter("Country", customer.Country),
   new SqlParameter("Phone", customer.Phone));

  return RedirectToAction("Index");
 }

 return View(customer);
}

// GET: Customers/Edit/5
public ActionResult Edit(int? id)
{
 if (id == null)
 {
  return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
 }
 Customer customer = db.Customers.Find(id);
 if (customer == null)
 {
  return HttpNotFound();
 }
 return View(customer);
}

// POST: Customers/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "CustomerID,CompanyName,ContactName,Address,Country,Phone")] Customer customer)
{
 if (ModelState.IsValid)
 {
  db.Database.ExecuteSqlCommand("EXEC dbo.UpdateCustomer @CustomerID,@CompanyName,@ContactName,@Address,@Country,@Phone",
    new SqlParameter("CustomerID", customer.CustomerID),
    new SqlParameter("CompanyName", customer.CompanyName),
    new SqlParameter("ContactName", customer.ContactName),
    new SqlParameter("Address", customer.Address),
    new SqlParameter("Country", customer.Country),
    new SqlParameter("Phone", customer.Phone));

  return RedirectToAction("Index");
 }
 return View(customer);
}

// GET: Customers/Delete/5
public ActionResult Delete(int? id)
{
 if (id == null)
 {
  return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
 }
 Customer customer = db.Customers.Find(id);
 if (customer == null)
 {
  return HttpNotFound();
 }
 return View(customer);
}

// POST: Customers/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
 db.Database.ExecuteSqlCommand("EXEC dbo.DeleteCustomer @CustomerID",
   new SqlParameter("CustomerID", id));

 return RedirectToAction("Index");
}
Index.cshtml
<div class="container">
    <h2>Customer List</h2>

    <p>
        @Html.ActionLink("Create New", "Create", "Customers", new { @class = "btn btn-primary" })
    </p>
    <table class="table table-bordered table-condensed">
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.CompanyName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.ContactName)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Address)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Country)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Phone)
            </th>
            <th>
                <span>Action</span>
            </th>
        </tr>

        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.CompanyName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ContactName)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Address)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Country)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Phone)
                </td>
                <td>
                    @Html.ActionLink("Edit", "Edit", new { id = item.CustomerID }, new { @class = "btn btn-info" })
                    @Html.ActionLink("Delete", "Delete", new { id = item.CustomerID }, new { @class = "btn btn-warning" })
                </td>
            </tr>
        }

    </table>

</div>
Create.cshtml
@using (Html.BeginForm()) 
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Customer Entry Form</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        <div class="form-group">
            @Html.LabelFor(model => model.CompanyName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.CompanyName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.CompanyName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ContactName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ContactName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ContactName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Address, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Address, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Country, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Country, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Country, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Phone, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Phone, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Phone, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn  btn-primary" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
Edit.cshtml
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>Edit Customer Record</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.CustomerID)

        <div class="form-group">
            @Html.LabelFor(model => model.CompanyName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.CompanyName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.CompanyName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.ContactName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.ContactName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.ContactName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Address, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Address, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Country, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Country, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Country, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Phone, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Phone, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Phone, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-primary" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>
Delete.cshtml
<div class="container">
    <h4>Are you sure you want to delete this?</h4>
    <hr />
    <dl class="dl-horizontal">
        <dt>
            @Html.DisplayNameFor(model => model.CompanyName)
        </dt>

        <dd>
            @Html.EditorFor(model => model.CompanyName, new { htmlAttributes = new { @class = "form-control", @readonly = "true", @style = "background-color:white;" } })
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.ContactName)
        </dt>

        <dd>
            @Html.EditorFor(model => model.ContactName, new { htmlAttributes = new { @class = "form-control", @readonly = "true", @style = "background-color:white;" } })
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Address)
        </dt>

        <dd>
            @Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "form-control", @readonly = "true", @style = "background-color:white;" } })
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Country)
        </dt>

        <dd>
            @Html.EditorFor(model => model.Country, new { htmlAttributes = new { @class = "form-control", @readonly = "true", @style = "background-color:white;" } })
        </dd>

        <dt>
            @Html.DisplayNameFor(model => model.Phone)
        </dt>

        <dd>
            @Html.EditorFor(model => model.Phone, new { htmlAttributes = new { @class = "form-control", @readonly = "true", @style = "background-color:white;" } })
        </dd>

    </dl>

    @using (Html.BeginForm()) {
        @Html.AntiForgeryToken()

        <div class="form-actions no-color">
            <input type="submit" value="Delete" class="btn btn-danger" /> 
            @Html.ActionLink("Back to List", "Index", null, new { @class = "btn btn-primary"})
        </div>
    }
</div>
Expected Output
Source code: CallStoredProcedureWithASPMVC in Github

Wednesday, October 4, 2017

Call Stored Procedures from Entity Framework 6 in C# (Part 2)

In this second part of the series on how to call stored procedures from Entity Framework 6, I will demonstrate on executing them using context.Database methods. To accomplish this, you need to perform steps 1 through 3 from this article Call Stored Procedures from Entity Framework 6 in C#.
If you're done, the codes for the CRUD(Create, Update and Delete) functionalities are presented below.
private static CustomerEntities ce = new CustomerEntities();

private static void InsertCustomer()
{
 try
 {
  var result = ce.Database.ExecuteSqlCommand("EXEC dbo.InsertCustomer @CompanyName,@ContactName,@Address,@Country,@Phone",
   new SqlParameter("CompanyName", "TNT Bookstore"),
   new SqlParameter("ContactName", "Mr T."),
   new SqlParameter("Address", "Lincoln Village"),
   new SqlParameter("Country", "UK"),
   new SqlParameter("Phone", "42333"));

  if (result == 1)
  {
   Console.WriteLine("Insert Record Successful!");
  }
 }
 catch (Exception e)
 {
  //do something here
 }
}

private static void UpdateCustomer()
{
 try
 {                
  var result = ce.Database.ExecuteSqlCommand("EXEC dbo.UpdateCustomer @CustomerID, @CompanyName,@ContactName,@Address,@Country,@Phone",
   new SqlParameter("CustomerID", 12),
   new SqlParameter("CompanyName", "TNT Bookstore"),
   new SqlParameter("ContactName", "Mr M."),
   new SqlParameter("Address", "New Orleans"),
   new SqlParameter("Country", "USA"),
   new SqlParameter("Phone", "43567"));

  if (result == 1)
  {
   Console.WriteLine("Update Record Successful!");
  }
 }
 catch (Exception)
 {
  //do something here
 }
}

private static void DeleteCustomer()
{
 try
 {
  var result = ce.Database.ExecuteSqlCommand("EXEC dbo.DeleteCustomer @CustomerID",
   new SqlParameter("CustomerID", 12));
  if (result == 1)
  {
   Console.WriteLine("Delete Record Successful!");
  }
 }
 catch (Exception)
 {
  //do something here
 }
}

private static void GetAllCustomers()
{
 var results = ce.Database.SqlQuery<Customer>("GetAllCustomers", "").ToList();
 foreach (var item in results)
 {
  Console.WriteLine("ID:{0}, Company Name:{1}, Contact:{2}, Address: {3}, Country: {4}, Phone:{5}",
   item.CustomerID, item.CompanyName, item.ContactName, item.Address, item.Country, item.Phone);
  Console.Write("\n\n");
 }
}

Monday, October 2, 2017

Call Stored Procedures from Entity Framework 6 in C# (Part 1)

Hello,
Here's a tutorial on how to call stored procedures from Entity Framework 6.0 through the context object using the stored procedure name. In the second part of the series, I'll demonstrate how to call the stored procedures using methods like ExecuteSqlCommand() and SqlQuery() from context.Database class. To start with here are the steps to complete this example.
Step 1
Add a Customers table in your database with fields.
=> CustomerID (int and identity set to true)
=> CompanyName(nvarchar)
=> ContactName(nvarchar)
=> Address(nvarchar)
=> Country(nvarchar)
=> Phone(nvarchar)
Step 2
Create stored procedures that will perform insert, update, delete and get all records operations.
Insert
ALTER Procedure [dbo].[InsertCustomer](@CompanyName nvarchar(40), 
 @ContactName nvarchar(30), 
 @Address nvarchar(60),
 @Country nvarchar(15),
 @Phone nvarchar(24))
As
Begin
 Insert Into dbo.Customers (CompanyName, ContactName, [Address], Country, Phone) 
  values (@CompanyName, @ContactName, @Address, @Country, @Phone)
End
Update
ALTER Procedure [dbo].[UpdateCustomer]
   (@CustomerID int,
    @CompanyName nvarchar(40), 
 @ContactName nvarchar(30), 
 @Address nvarchar(60),
 @Country nvarchar(15),
 @Phone nvarchar(24))
As
Begin
 Update dbo.Customers
   Set CompanyName = @CompanyName,
    ContactName  = @ContactName,
    [Address] = @Address,
    Country = @Country,
    Phone = @Phone
 where CustomerID = @CustomerID 
End
Delete
ALTER Procedure [dbo].[DeleteCustomer]
   (@CustomerID int)
As
Begin
 Delete from dbo.Customers where CustomerID = @CustomerID 
End
Get All Customers
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER Procedure [dbo].[GetAllCustomers]
As
Begin
 Select * from dbo.Customers 
End
Step 3
Create a console application and then add an ADO.NET Entity Model. Set the Entity Framework version to 6.0. Include the Customers table and the stored procedures which will be called by code. Step 4
In your console application project, create a context object and then add methods that will call the stored procedures. In the example code below, the stored procedures are executed directly using the context object. The parameters are also supplied with dummy records for testing purposes.
private static CustomerEntities ce = new CustomerEntities();

static void Main(string[] args)
{
 GetAllCustomers();
 //InsertCustomer();
 //UpdateCustomer();
 //DeleteCustomer();
 Console.ReadLine();
}
  
private static void InsertCustomer()
{
 try
 {
  int result = ce.InsertCustomer("BCD", "Mike", "Manila", "Philippines", "999-0001");
  if (result == 1)
  {
   Console.WriteLine("Insert Record Successful!");
  }
 }
 catch (Exception e)
 {
  //do something here
 }
}

private static void UpdateCustomer()
{
 try
 {
  int result = ce.UpdateCustomer(4, "Jerang", "Lara", "Kuala Lumpur", "Malaysia", "333-3333");
  if (result == 1)
  {
   Console.WriteLine("Update Record Successful!");
  }
 }
 catch (Exception e)
 {
  //do something here
 }
}

private static void DeleteCustomer()
{
 try
 {
  int result = ce.DeleteCustomer(4);
  if (result == 1)
  {
   Console.WriteLine("Delete Record Successful!");
  }
 }
 catch (Exception e)
 {
  //do something here
 }
}
  
private static void GetAllCustomers()
{
 var results = ce.GetAllCustomers().ToList();
 foreach (var item in results)
 {
  Console.WriteLine("ID:{0}, Company Name:{1}, Contact:{2}, Address: {3}, Country: {4}, Phone:{5}",
   item.CustomerID, item.CompanyName, item.ContactName, item.Address, item.Country, item.Phone);
  Console.Write("\n\n");
 }
}

Cheers! :-)

Tuesday, September 12, 2017

Navigation Properties In Entity Framework Using Database First Approach

Good day!

Here's a simple step by step tutorial on exploring the Navigation Properties of EF using the DB approach.
According to MSDN, Navigation properties provide a way to navigate an association between two entity types. Every object can have a navigation property for every relationship in which it participates. Navigation properties allow you to navigate and manage relationships in both directions, returning either a reference object (if the multiplicity is either one or zero-or-one) or a collection (if the multiplicity is many). You may also choose to have one-way navigation, in which case you define the navigation property on only one of the types that participates in the relationship and not on both.
Given the description, this example demonstrates the concept using two tables Employees and Dependents wherein you search for a particular employee and you can access the related dependents of that employee. To start with, just perform the steps given below.
Step 1. Create two tables Employees and Dependents. Then create a diagram linking the two tables through employee id.
Step 2. Populate the two tables with fictitious information which will be used with the project.
Step 3. Create an empty ASP.NET MVC project and add an ADO.NET Entity Model that connects the Employees and Dependents tables.
Step 4. Add a view model class that will be used by the view as it's data source.
public class EmployeeDependentsViewModel
{
 public List<Dependent> Dependents { get; set; }
}
Step 5. The codes for the controller(handle post activity) and view(display search data) are as follows.
Controller
private OrganizationEntities entities;
private EmployeeDependentsViewModel empViewModel;
[HttpPost]
public ActionResult Search(FormCollection form)
{
 if (!string.IsNullOrEmpty(form["Search"]))
 {
  string search = form["Search"];
  empViewModel.Dependents = new List<Dependent>();
  empViewModel.Dependents = entities.Employees.FirstOrDefault(x => x.EmpName == search).Dependents.ToList();

  try
  {
   if (empViewModel.Dependents != null)
   {
    return View("Index", empViewModel);
   }
  }
  catch (Exception ex)
  {
   //todo exception
  }
 }
 return View("Index");           
}
View
@model NavigationPropertiesDemo.Models.EmployeeDependentsViewModel

<h2>Index</h2>
<div class="container">
    <div class="row">
        @using (Html.BeginForm("Search", "Home", FormMethod.Post))
        {
            @Html.AntiForgeryToken()
            
            <div class="form-horizontal">
                <div class="form-group">
                    <span class="control-label col-md-2">Search Employee</span>
                    @Html.TextBox("Search", null, new { @class = "form-control col-md-10" })
                </div>
                <div class="form-group">
                    <div class="col-md-offset-2 col-md-10">
                        <input type="submit" value="Search" class="btn btn-primary" />
                        <input type="button" value="Cancel" class="btn btn-primary" />
                    </div>
                </div>
            </div>
        }       
    </div>
    <div class="row">
       
        @if (Model != null)
        {
            <h3>List Of Dependents</h3>
            <table class="table  table-bordered">
                <tr>
                    <th>
                        @Html.DisplayName("Name")
                    </th>
                    <th>
                        @Html.DisplayName("Age")
                    </th>
                </tr>

                @foreach (var item in @Model.Dependents)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(model => item.DependentName)
                        </td>
                        <td>
                            @Html.DisplayFor(model => item.Age)
                        </td>                        
                    </tr>
                }

            </table>
        }       
    </div>
</div>
Sample Output given the search for employee John,the application will show the employee's dependents using Navigation properties from the controller code below.
empViewModel.Dependents = entities.Employees.FirstOrDefault(x => x.EmpName == search).Dependents.ToList();

Sunday, September 10, 2017

Pivot DataTable Using LINQ

Hello,
A question was brought up in the forums on how to Pivot a DataTable object here.The OP has already a solution with reference to this link Cross Tab / Pivot from Data Table. An alternative solution is to utilize the features of LINQ using group by statement to achieve the desired output. This solution consists of few lines of code compared with the solution from the forum post.
C# Code
 var query = (from students in dt.AsEnumerable()
  group students by students.Field<string>("StudID") into g
  select new
  {
   StudID = g.Key,
   Eng = g.Where(c => c.Field<string>("SubSht") == "Eng").Sum(c => c.Field<double>("Score")),
   Fre = g.Where(c => c.Field<string>("SubSht") == "Fre").Sum(c => c.Field<double>("Score")),
   Mat = g.Where(c => c.Field<string>("SubSht") == "Mat").Sum(c => c.Field<double>("Score")),
  }).ToList();

VB.NET Code
Dim query = (From students In dt.AsEnumerable
     Group students By ID = students.Field(Of String)("StudID") Into g = Group
     Select New With {
         Key ID,
         .Eng = g.Where(Function(c) c.Field(Of String)("SubSht") = "Eng").Sum(Function(c) c.Field(Of Double)("Score")), _
         .Fre = g.Where(Function(c) c.Field(Of String)("SubSht") = "Fre").Sum(Function(c) c.Field(Of Double)("Score")), _
         .Mat = g.Where(Function(c) c.Field(Of String)("SubSht") = "Mat").Sum(Function(c) c.Field(Of Double)("Score"))
     }).OrderBy(Function(tkey) tkey.ID).ToList()

Thursday, September 7, 2017

Function <anonymous method> doesn't return a value on all code paths (Action Statement)

Hello,
Given the code statement below, the code throws an exception such as anonymous method does not return a value on all code paths.
If txtEmployeeHireDate.IsHandleCreated Then
 If txtEmployeeHireDate.InvokeRequired Then
  BeginInvoke(New Action(Function()
     txtEmployeeHireDate.Text = objEmployee.HireDate
     End Function))
 End If
End If
The code that's inside the BeginInvoke() statement does not necessarily returns a value since I only assigned an object's property value to the textbox control. In order to resolve this, either return a null value or a false value inside the Action delegate.
If txtEmployeeHireDate.IsHandleCreated Then
 If txtEmployeeHireDate.InvokeRequired Then
  BeginInvoke(New Action(Function()
     txtEmployeeHireDate.Text = objEmployee.HireDate
     Return Nothing 'added this statement to fix issue
     End Function))
 End If
End If
Another solution is to use Sub() which does not return a value instead of Function().
If txtEmployeeHireDate.IsHandleCreated Then
 If txtEmployeeHireDate.InvokeRequired Then
  BeginInvoke(New Action(Sub()
     txtEmployeeHireDate.Text = objEmployee.HireDate
     End Sub))
 End If
End If
C# Code
if (txtEmployeeHireDate.IsHandleCreated) {
 if (txtEmployeeHireDate.InvokeRequired) {
  BeginInvoke(new Action(() => { txtEmployeeHireDate.Text = objEmployee.HireDate; }));
 }
}

Wednesday, July 12, 2017

Calling Web API not working in AngularJS using $http service

When calling ASP.NET Web API service inside the solution, I encountered an issue that is 404 not found. Given that this issue persists, I tried adding a forward slash before the url in the Ajax call which works.
AngularJS
$http({
        //url: "EmployeeRoute/GetAll", //404 error
 url: "/EmployeeRoute/GetAll",
 dataType: 'json',
 method: 'POST',
 data: GetAll,
 headers: {
  "Content-Type": "application/json"
 }
}).then(function (resp) {
 if (typeof resp.data === 'object') {
  return resp.data;
 } else {
  return $q.reject(response.data);
 }
}, function (err) {
 return $q.reject(err.data);
});
I also make sure that the WebApiConfig.Register method gets executed in Global.asax.cs.
Global.asax.cs
protected void Application_Start(object sender, EventArgs e)
{
 GlobalConfiguration.Configure(WebApiConfig.Register);
}

Monday, July 10, 2017

AngularJS $http service returns html instead of JSON string

Good day!
I've been trying to consume an ASP.NET Web Method using AngularJS $http service and all I get from the response is the html page source instead of string data. After investigating and doing some searching, the workaround is to set the responseType to json and pass an empty data to the Web Method given that the Web Method has no parameter.
var myapp = angular.module('myApp', []);
myapp.controller('ctrl', function ($scope, $http) {
 $http({
  url: "63MakeAjaxCallAndReturnJSONWebService.aspx/HelloWorld",
  dataType: 'json',
  method: "POST",
  responseType: 'json',
  data: {},
  headers: { "Content-Type": "application/json;" }
 }).then(function (response) {
  $scope.value = response.data.d;
 });
});
And also declare the Web Method as static.
[WebMethod()]
public static string HelloWorld()
{
 return "Hello World!";
}

Saturday, July 8, 2017

ASP.NET 4.5 Has Not Been Registered on the Web Server (Visual Studio 2012)

This issue "ASP.NET 4.5 Has Not Been Registered on the Web Server" occurred when I opened an asp.net application built with Visual Studio 2012 recently when I installed Visual Studio 2015 in my laptop with a Windows 8 operating system. Given that this happens I assume that some settings may have been updated or corrupted by the recent version of VS. The solutions I have tried included registering asp.net through Visual Studio command tools with no effect.
After searching through the web, I found a solution which is to download the hotfix for VS 2012 here Unexpected dialog box appears when you open projects in Visual Studio 2012 after you install the .NET Framework 4.5.3. After downloading and installing the hotfix, the issue was resolved.

Thursday, July 6, 2017

Custom DateTimePicker Control With Background Color and Icon

Hello
Here's a custom DateTimePicker with background color and image icon instead of using the ComboBoxRenderer class. The icon is an image that is added to the project as part of it's resource. The adding of icon is processed through the WndProc method while the setting of background color is handled in the OnPaint() event. Notice that in the constructor, the SetStyle()'s parameters are ControlStyles.UserPaint so that the control paints itself and true to apply the specified style to the control.
public class DateTimePickerWithBackground : DateTimePicker
{
 private Bitmap _bmp;

 enum BorderSize
 {
  One = 1,
  Two = 2
 };

 public DateTimePickerWithBackground()
 {
  _bmp = new Bitmap(ClientRectangle.Height, ClientRectangle.Width);
  this.SetStyle(ControlStyles.UserPaint, true);
 }

 protected override void WndProc(ref Message m)
 {
  base.WndProc(ref m);
  if (m.Msg == 0xf) //WM_PAINT message
  {   
   Graphics g = Graphics.FromHwnd(m.HWnd);
   g.DrawImage(_bmp, ClientRectangle.Width - Convert.ToInt32(9 * ClientRectangle.Width / 100), 2);
   g.Dispose();
  }
 }

 protected override void OnPaint(PaintEventArgs e)
 {
  base.OnPaint(e);
  e.Graphics.FillRectangle(new SolidBrush(Color.LawnGreen), ClientRectangle);
  ControlPaint.DrawBorder(e.Graphics, ClientRectangle,
          Color.LightGray, (int)BorderSize.One, ButtonBorderStyle.Solid,
          Color.LightGray, (int)BorderSize.One, ButtonBorderStyle.Solid,
          Color.LightGray, (int)BorderSize.One, ButtonBorderStyle.Solid,
          Color.LightGray, (int)BorderSize.One, ButtonBorderStyle.Solid);
  TextRenderer.DrawText(e.Graphics, Text, Font, Rectangle.FromLTRB(0, 0, Width - Height, Height), 
   SystemColors.ControlText);
  Image img = Properties.Resources.calendar_picker;
  _bmp = new Bitmap(img, new Size(img.Width, img.Height));
 }
}
Output
The source is available in Github. :-)

Wednesday, July 5, 2017

Load Images in a Windows Form Custom Control

Good day!
Often times when developing custom controls you will add images or icons to enhance the UI through the Bitmap class. But when getting the image from file using Image.FromFile(AppDomain.CurrentDomain.BaseDirectory + @"\calendar.png") you may encounter issues such as "path is null" since the path pointed by the BaseDirectory isn't the executable path. A simple workaround is to set the path of the image using hardcoded like Image.FromFile(@"C:\Images\ProjectX\calendar.png"). While this is acceptable, it is ugly to look at and may cause potential issues once the image has been transferred to another location. An accepted solution is to add the image as a project resource then reference it in the custom control code. To accomplish that, here are the steps.
* Right Click on the Project -> Properties
* In Resources, select Add Resource Dropdown -> Add Existing File
- Choose the image or icon to be used as resource. Once done, it will resemble as the photo below.
* In your custom control code, you can access the resource using Properties.Resources.Resource_Name
protected override void OnPaint(PaintEventArgs e)
{
 base.OnPaint(e);
 Image img = Properties.Resources.calendar_picker;
 bmp = new Bitmap(img, new Size(img.Width, img.Height));
}

Done! :-)

Tuesday, July 4, 2017

MVVM Basics with TextBlock Control

Hello,
This post is based on the article Understanding the basics of MVVM design pattern. The author demonstrated the basics of MVVM using TextBlock controls. However, the code samples have several issues and in order for the sample application to work, I revise them with the following changes.
BindableBase.cs - since SetProperty method uses T in it's parameter, you also need to reference T in your classname.
public class BindableBase<T> : INotifyPropertyChanged
{
   ...
}
MainPageViewModel.cs - update the code in the constructor to bind a single object to the TextBlock controls.
public class MainPageViewModel : BindableBase<Book>
{
 private Book _book;

 public Book Book
 { 
  get
  {
   return _book;
  } 
  set
  {
   SetProperty(ref _book, value);
  } 
 }
 
 public MainPageViewModel()
 {           
  Book = new Book()
  {
   Title = "Harry Potter",
   Author = "J. K. Rowling",
   Category = "Young-adult fiction",
   Language = "English"
  };
 }
}
XAML - Prefix the properties with the classname when binding it with the control
<TextBlock x:Name="bookTitle" HorizontalAlignment="Left" TextWrapping="Wrap" Grid.Row="0" Width="500" Text="{Binding Book.Title}" />


Hope it helps! :-)

Tuesday, June 27, 2017

Export ASP.NET GridView To Excel and Preserve Leading Zeros

Hi,
There was a question raised on how to export data from ASP.NET Gridview to Microsoft Excel and preserve leading zeros of numeric values. A workaround that we have is to insert an   character before the cell value if that value starts with zero (0). So if the value starts with zero such as 0001, the result would be " 0001". Thus when exported to Excel, the leading zero is kept.
cell.Text = string.Format("&nbsp;{0}", cell.Text);
A suggested solution is to insert a Tab character ( ) but this fails on some occasions. After doing some research, replacing the tab character with &ensp; or &emsp; would also fix the issue.
cell.Text = string.Format("&ensp;{0}", cell.Text);
//or
cell.Text = string.Format("&emsp;{0}", cell.Text);

ASP.NET GridView Export Excel Report
Cheers!

Sunday, June 25, 2017

WPF DataGrid Databinding using MVVM Pattern

Hello,

I've been developing WPF applications before but not having applied the MVVM design pattern and have been wanting to create a simple program that loads data into the DataGrid control. According to Wikipedia, the components of an MVVM pattern are:
Model
Model refers either to a domain model, which represents real state content (an object-oriented approach), or to the data access layer, which represents content (a data-centric approach).
View
As in the MVC and MVP patterns, the view is the structure, layout, and appearance of what a user sees on the screen.
View model
The view model is an abstraction of the view exposing public properties and commands. Instead of the controller of the MVC pattern, or the presenter of the MVP pattern, MVVM has a binder. In the view model, the binder mediates communication between the view and the data binder.The view model has been described as a state of the data in the model.
Binder
Declarative data and command-binding are implicit in the MVVM pattern. In the Microsoft solution stack, the binder is a markup language called XAML.
Given the explanations above, here's the code that applies a plain MVVM approach.
ViewModel (CustomerViewModel.cs)
The model used here is the Northwind Customer
public class CustomerViewModel : ViewModelBase
    {
        private ObservableCollection<Customer> _cusGridData;
        private NorthwindEntities _context;

        public CustomerViewModel()
        {
            _context = new NorthwindEntities();
            LoadInitialData();
        }

        private void LoadInitialData(){
            CustomerData = new ObservableCollection<Customer>(from c in _context.Customers select c);
        }

        public ObservableCollection<Customer> CustomerData
        {
            get 
            { 
                return _cusGridData; 
            }
            set
            {
                _cusGridData = value;
                OnPropertyChanged("CustomerData");
            }
        }
    }
View (XAML)
<Window x:Class="WPFMVVMDataGrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:ViewModel="clr-namespace:WPFMVVMDataGrid"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <ViewModel:CustomerViewModel/>
    </Window.DataContext>
    <Grid>
        <DataGrid ItemsSource="{Binding Path=CustomerData}" x:Name="dgCustomer"
             AutoGenerateColumns="False"
             SelectionMode="Single"
             SelectionUnit="FullRow"
             GridLinesVisibility="Horizontal"
             CanUserDeleteRows="True"
             CanUserAddRows="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="Name" Width="SizeToCells" MinWidth="125" Binding="{Binding CustomerID}" />
                <DataGridTextColumn Header="Age" Width="SizeToCells" MinWidth="200" Binding="{Binding ContactName}"/>
                <DataGridTextColumn Header="Description" Width="SizeToCells" MinWidth="200" Binding="{Binding Address}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
For the details on how MVVM works see this thread WPF Having Trouble with binding a Datagrid control on load

Source Code: DataGridMVVMWPF In Github

Cheers! :-)

Monday, June 5, 2017

Disable button in AngularJS using ng-disabled on it's first page load in ASP.NET MVC

Hello,
One might notice that during page load of an ASP.NET MVC application, the button with ng-disabled attribute and have values such as $invalid or $dirty does not disable the button. Thus, this will enable the user to submit the form with empty values to the controller method. In order to disable the button on page load, add $pristine values in the ng-disabled attribute such as the code below.
Original Code
<input type="submit" id="btnAddEmployee" class="btn btn-primary" value="Save" ng-click="Save()" 
 ng-disabled="AddEmp.fname.$dirty && AddEmp.fname.$invalid
     || AddEmp.lname.$dirty && AddEmp.lname.$invalid
     || AddEmp.salary.$dirty && AddEmp.salary.$invalid" />
Modified code with $pristine
<input type="submit" id="btnAddEmployee" class="btn btn-primary" value="Save" ng-click="Save()" 
 ng-disabled="AddEmp.fname.$dirty && AddEmp.fname.$invalid || AddEmp.fname.$pristine
     || AddEmp.lname.$dirty && AddEmp.lname.$invalid || AddEmp.lname.$pristine
     || AddEmp.salary.$dirty && AddEmp.salary.$invalid || AddEmp.salary.$pristine" />

Saturday, June 3, 2017

$location.path() method not reloading new data in ASP.NET MVC Web API with AngularJS

Hello,
I was trying to integrate AngularJS into a simple ASP.NET MVC Web API application with Save functionality. Basically, when you have finished posting data the next logic will be to redirect the user to the display all page. However, I stumbled into an issue in which the $location service does not reload data.
According to the docs,the $location service allows you to change only the URL; it does not allow you to reload the page. So after placing breakpoints in the Api Controller, I noticed that the GetAll() method is called first next is the Save() method. The solution to this dilemma is to transfer the $location.path() method inside the success function so that the Save() method in the Api Controller is executed first.
Code With Issue: $location.path() is outside the success function.
 $scope.Add = function () {
  $http({ method: "POST", data: $scope.employee, url: "/api/employees" })
  .then(function (response) {
   $scope.employees = response.data;
   $scope.employee = {
    "FirstName": "",
    "LastName": "",
    "Age": "",
    "Salary": ""
   };   
  });
  $location.path('/allemployees'); 
}
Fix: $location.path() is inside the success function.
$scope.Add = function () {
  $http({ method: "POST", data: $scope.employee, url: "/api/employees" })
  .then(function (response) {
   $scope.employees = response.data;
   $scope.employee = {
    "FirstName": "",
    "LastName": "",
    "Age": "",
    "Salary": ""
   };
   $location.path('/allemployees'); 
  });  
}

Cheers! :-)

Wednesday, May 17, 2017

Adding ASP.NET 5 Templates to VS 2015

Good day!
One might notice that the ASP.NET 5 templates are not visible when creating a new Web Application Project in Visual Studio 2015 given that this is a fresh installation of the software. So to add the ASP.NET 5 Templates, download the ASP.NET 5 run-time tools Microsoft ASP.NET and Web Tools 2015 (RC) – Visual Studio 2015 and proceed with the setup. Restart your machine afterwards.
That's it.. :-)

This version of Visual Studio requires the April 2014 update to Windows 8.1 (VS 2015)

Hello,
Now that I've got the time to install Visual Studio 2015 Enterprise on my laptop with Windows 8.1 Operating System I decided to give it a go. That's when the moment I opened the installer file, an issue pops out of the screen with the description "This version of Visual Studio requires the April 2014 update to Windows 8.1 and Windows Server 2012 R2 known as KB2919355".
The solution to this issue can easily be found at stackoverflow. But missing the links of the packages needed to resolve the problem. A step by step example is presented below.
1. Download update package 2919442 and install update to your pc. This is the pre-requisite update of package 2919355
   x86
   x64
2. Download update package 2919355 and install update to your pc.
   x86
   x64
3. After those updates have been installed, restart the computer for the updates to take effect.
Cheers! :-)

Monday, May 1, 2017

How to Post JSON data with WebRequest in .NET

Hello,
There was a question on how to post a JSON data using the WebRequest class given that using Ajax, the post data would look like this.
data: '{ "age": "78", "weight": "51" }'
In .NET, you need to store the JSON data into a string object and escape those double quotes before passing it to the WebRequest object.
C#.NET
string postData = "{ \"age\": \"78\", \"weight\": \"51\" }";
VB.NET
Dim postData As String = "{ ""age"": ""78"", ""weight"": ""51"" }"

Cheers! :-)

Wednesday, April 12, 2017

Sorting of <li> elements using jQuery sort() not working (refresh page only) in ASP.NET

Given the simple sorting code below which changes the order of <li> elements to ascending order and assuming that the text content of each li elements are numbers.
$(function () {
 $('#sortList').click(function (e) {
  // Select all the li items
  var numbersList = $('#numbersList li');
  
  numbersList.sort(function (a, b) {
   return parseInt($(a).text(), 10) > parseInt($(a).text(), 10);
  }).appendTo(numbersList.parent());
 });
});
The code should work only to find out that the page will only refresh after the button click. And then the re-arranging of the elements are discarded. The simple fix to this issue is to add the preventDefault() to prevent the button's default behavior that is to post back.
$(function () {
 $('#sortList').click(function (e) {
         //add preventDefault() to reflect the changes after sorting
  e.preventDefault();
  // Select all the li items
  var numbersList = $('#numbersList li');
  
  numbersList.sort(function (a, b) {
   return parseInt($(a).text(), 10) > parseInt($(a).text(), 10);
  }).appendTo(numbersList.parent());
 });
});
Fiddle: Sort Unordered list items

Saturday, April 8, 2017

$.getJSON() not loading JSON file within Visual Studio Project in ASP.NET WebForms

Hi,
I was trying to load a JSON file located within my Visual Studio project using $.getJSON(), however the code below doesn't work as expected.
$.getJSON('/Assets/misc/employee.json', function (data) {
 alert('processing!');
})
.done(function (r) {
 alert(r.message);
})
.fail(function (s) {
 alert('oops the file is missing!');
});
After investigating for a few hours, I tested the local path of the JSON file such as http://localhost:3766/Assets/misc/employee.json and the result was an exception "HTTP Error 404.3 - Not Found The page you are requesting cannot be served because of the extension configuration. If the page is a script, add a handler. If the file should be downloaded, add a MIME map.".
I remember the solution in one of my ASP.NET project was to set the MimeMap in the web.config inside the system.webServer element. After setting the MimeMap for json files, I can now load local JSON files using $.getJSON().
<system.webServer>
 <staticContent>
   <mimeMap fileExtension=".json" mimeType="application/json" />
 </staticContent>
</system.webServer>

:-)