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! :-)