using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace FileDownloader
{
class Program
{
static void Main(string[] args)
{
List allUrls = GetUrls().Select(x=>x.Trim()).ToList();
Parallel.ForEach(allUrls, new ParallelOptions() { MaxDegreeOfParallelism = 10 }, url =>
{
try
{
WebRequest request = WebRequest.Create(url);
WebResponse response = request.GetResponse();
string originalFileName = response.ResponseUri.AbsolutePath.Substring(response.ResponseUri.AbsolutePath.LastIndexOf("/") + 1);
Stream streamWithFileBody = response.GetResponseStream();
using (Stream output = File.OpenWrite(@"C:\Ebooks_New\" + originalFileName))
{
streamWithFileBody.CopyTo(output);
}
Console.WriteLine("Downloded : " + originalFileName);
}
catch (Exception ex)
{
Console.WriteLine("Unable to Download : " + ex.ToString());
}
});
Console.WriteLine("Finished : ************************");
Console.ReadKey();
}
public static List GetUrls()
{
return new List() // Put list of URLs here
{
"http://ligman.me/1IW1oab ",
"http://ligman.me/1Uixtlq ",
"http://ligman.me/1R9Ubgt ",
"http://ligman.me/1H4VXHT ",
"http://ligman.me/1f8XUKy ",
"http://ligman.me/1HBEUPi ",
"http://ligman.me/1NDTZR4 ",
"http://ligman.me/1Uiy2f9 ",
"http://ligman.me/1epZ0QU ",
"http://ligman.me/1JIhgjA ",
"http://ligman.me/1CQX5uG ",
}
}
}
}
14 July 2017
Download Files in Parallel using C#
I wrote this little utility program that allows you to download multiple files from URLs using C#.
30 December 2016
Angular 2 Step by Step Guide: How to consume a REST web service via angular service?
Angular 2 has a modular development architecture where each module has its own set of components, templates and routes. Service is more at an application level and can be shared by multiple components or modules. Angular 2 has a concept of injector whereby you don’t need to create the instance of the service yourself but whenever you need to consume service you can request Angular to provide you with an instance. In this blog we are going to consume an external web service which return list of countries and create an angular service to use that web service to provide list of countries to the dropdown in component.
Think of angular service as nothing special but an ES6 class that exports some methods to be consumed by components. First lets clone/download an Angular 2 seed project from Angular’s github repo ( https://github.com/angular/angular2-seed ) and navigate to angular2-seed folder and run npm install. This will install all necessary modules to run the application. Open your project in visual studio code which is a free code editor.
In src folder let’s create a services folder and add a file called countrylist.service.ts. In this file add a class called CountryListService . This is a bare bone class that will provide you with a method to get list of countries so lets add a method to it called getCountries().
For service to be available to other components we have to export the class and add @Injectable() decorator to class to allow Angular to inject objects in it when required. Think of decorates as an annotations used in C# or java. It provide some metadata to angular to function it properly. To use @Injectable you have to import it from '@angular/core'. At this point you have a class that looks like.
Now we are ready to write actual implementation of getCountries(). The REST web service we are going to use is ( https://restcountries.eu/rest/v1/all ). It returns a lot of data but we are only interested in name of countries. We need an http object to call this web service so we need to import Http module from '@angular/http’. Now you can declare an http object in the class and create a new instance when required but Angular provides an alternative where you declare a private variable in constructor of the type you need and it will create an instance when you need it. This is done via dependency injection without you needing to create an object explicitly.
Now we implement getCountries() method. We use http.get method which returns an Observable . Observable provides an async behaviour. Observable comes from RxJs so you have to import it. Once you get a response you have to map it or catch any error. So we implement two functions to deal with either response or error. getCountries() will return Observable of type any[] array. We also need to import map and catch operators from RxJs. In this implementation all we are doing is calling the REST web service and once response comes back and if it is 200 OK we map the response to get the json result out of it and return the result or throw an Observable exception if there is any error calling the web service.
Now we have fully implemented our service lets make it available to the components. Open app.module.ts and add it to providers array providers: [ CountryListService,... ]. You need to import the service from services folder. This makes Angular aware that whenever any component in AppModule asks for object of type CountryListService where it can create one from. Angular maintains a single instance of this service per module using injector.
Now that our service is implemented and ready to be used by components in AppModule lets go to home folder and open home.component.ts . Let import our service and observable first. We use the same principal we used in service to inject service instance via private constructor variable and create a variable of type array to hold list of countries.
Where should you call the service you just written to populate countries array ? It depends on at what point you need the data. If you need the data when your form loads you can implement OnInit from Angular and override ngOnInit method and call the web service there. So lets do that. You need to import OnInit from @angular/core. At this point class signature will look like export class HomeComponent implements OnInit. getCountries() return an Observable so you have to subscribe to it to get data out of it. Here we are using lambda like syntax to subscribe to response or error. Once data is returned we are logging it to console and populating the array with only name field. Hover over subscribe to understand the syntax properly. If there is an error we are just simply logging it to console. You may want to do more with error later.
Now we are ready to display this data in home.component.html. I have added a dropdown for country. We are using *ngFor directive to loop through each country in the array and add it as an option.
Now to run the application from command prompt run npm start and navigate to browser http://localhost:3000/ . You will be able to see list of countries in a dropdown.
You can use Google chrome’s developer tools using F12 to view the console log. That’s it. There are many moving parts but once you understand how it all fits together it becomes easy to implement service. You can extend on this service by implementing OnDestroy and unsubscribe from the Observable.
Think of angular service as nothing special but an ES6 class that exports some methods to be consumed by components. First lets clone/download an Angular 2 seed project from Angular’s github repo ( https://github.com/angular/angular2-seed ) and navigate to angular2-seed folder and run npm install. This will install all necessary modules to run the application. Open your project in visual studio code which is a free code editor.
In src folder let’s create a services folder and add a file called countrylist.service.ts. In this file add a class called CountryListService . This is a bare bone class that will provide you with a method to get list of countries so lets add a method to it called getCountries().
class CountryListService {
getCountries(){
//This method will return list of countries.
}
}
For service to be available to other components we have to export the class and add @Injectable() decorator to class to allow Angular to inject objects in it when required. Think of decorates as an annotations used in C# or java. It provide some metadata to angular to function it properly. To use @Injectable you have to import it from '@angular/core'. At this point you have a class that looks like.
import { Injectable } from '@angular/core';
@Injectable()
export class CountryListService {
getCountries(){
//This method will return list of countries.
}
}
Now we are ready to write actual implementation of getCountries(). The REST web service we are going to use is ( https://restcountries.eu/rest/v1/all ). It returns a lot of data but we are only interested in name of countries. We need an http object to call this web service so we need to import Http module from '@angular/http’. Now you can declare an http object in the class and create a new instance when required but Angular provides an alternative where you declare a private variable in constructor of the type you need and it will create an instance when you need it. This is done via dependency injection without you needing to create an object explicitly.
import { Injectable } from '@angular/core';
import {Http, Response, Headers, RequestOptions} from '@angular/http';
@Injectable()
export class CountryListService {
constructor(private http:Http) {
}
getCountries(){
//This method will return list of countries. We can use http variable from constructor to call get method.
}
}
Now we implement getCountries() method. We use http.get method which returns an Observable
getCountries():Observable{ //You can provide additional header options to get which is not required here. //let headers = new Headers({'content-type':'application/json'}); //let options = new RequestOptions({headers:headers}); return this.http.get("https://restcountries.eu/rest/v1/all") .map(this.extactData) .catch(this.handleError); } private extactData(resp:Response){ let body = resp.json(); console.log(body); return body ; } private handleError(error:any){ console.log(error); return Observable.throw(error.statusText); }
Now we have fully implemented our service lets make it available to the components. Open app.module.ts and add it to providers array providers: [ CountryListService,... ]. You need to import the service from services folder. This makes Angular aware that whenever any component in AppModule asks for object of type CountryListService where it can create one from. Angular maintains a single instance of this service per module using injector.
import {CountryListService} from './services/countrylist.service'
providers: [
CountryListService,
GithubService
],
Now that our service is implemented and ready to be used by components in AppModule lets go to home folder and open home.component.ts . Let import our service and observable first. We use the same principal we used in service to inject service instance via private constructor variable and create a variable of type array to hold list of countries.
import {CountryListService} from '../services/countrylist.service'
import {Observable } from 'rxjs/Rx'
countries:any[]=[]; // declared inside the HomeComponent class
constructor(private countryListService : CountryListService){
}
Where should you call the service you just written to populate countries array ? It depends on at what point you need the data. If you need the data when your form loads you can implement OnInit from Angular and override ngOnInit method and call the web service there. So lets do that. You need to import OnInit from @angular/core. At this point class signature will look like export class HomeComponent implements OnInit. getCountries() return an Observable so you have to subscribe to it to get data out of it. Here we are using lambda like syntax to subscribe to response or error. Once data is returned we are logging it to console and populating the array with only name field. Hover over subscribe to understand the syntax properly. If there is an error we are just simply logging it to console. You may want to do more with error later.
ngOnInit() {
this.countryListService.getCountries().subscribe(
data=>{console.log(data);
for (var i=data.length;i--;) {
console.log('returned : ' + data[i].name)
this.countries[i]=data[i].name;
}
},
err=> console.log(err)
)
}
Now we are ready to display this data in home.component.html. I have added a dropdown for country. We are using *ngFor directive to loop through each country in the array and add it as an option.
<select class="form-control" #country
name="country">
<option value="default">Select country...</option>
<option *ngFor="let cnt of countries">
{{ cnt }}
</option>
</select>
Now to run the application from command prompt run npm start and navigate to browser http://localhost:3000/ . You will be able to see list of countries in a dropdown.
You can use Google chrome’s developer tools using F12 to view the console log. That’s it. There are many moving parts but once you understand how it all fits together it becomes easy to implement service. You can extend on this service by implementing OnDestroy and unsubscribe from the Observable.
23 October 2015
Call Google Maps Geocode API in Parallel using C# and TPL
Google Maps Geocode API provides a way to validate addresses by getting latitude and longitude and address type of a given address. In this post I would like to show you how to call this web service in parallel so you can speed up the address validation process. One thing to note is URL to get Geocode details from Google Maps API is different if you are only using free version in comparison to when you are using Google Maps API for work. By default Google Maps API provide 2500 request per day for free. When you are calling Google Maps API using paid version you need to encrypt your request using your client ID and encryption key provided to you when you buy it.
First thing first. You will need a key to run this application so sign up for Google Maps API and get your key https://developers.google.com/maps/documentation/geocoding/intro
You can download the full source code from GoogleGeocode.GoogleMapsAPI Source
Setup your app.config file
In AppSettings section add
There is a limit of 10 API calls per second when you are calling Google Maps APIs so I am passing 10 addresses to Parallel.ForEach loop and calling Google Geocode API. This will parallalize API calls. Also there is a check if all API calls finish within one second wait for 1 second before calling next batch to avoid getting QUERY_OVER_LIMIT error.
GetGeoDetails() method calls Google Maps API using HttpRequest and Get HttpResponse object back which then being converted to JSON object using JSON.Net library.
First thing first. You will need a key to run this application so sign up for Google Maps API and get your key https://developers.google.com/maps/documentation/geocoding/intro
You can download the full source code from GoogleGeocode.GoogleMapsAPI Source
Setup your app.config file
In AppSettings section add
<add key="IsGoogleMapsAPIPaid" value="0"/> <add key="URL" value="https://maps.googleapis.com/maps/api/geocode/json?address="/> <add key="APIClient" value="yourclientId"/> <add key="APIKey" value="yourcryptokey"/>In your code you will get a list of addresses you want to validate from your database. In this demo I have put some addresses in a list.
ListlstAddresses = new List () { "UNIT 7, 7 ERINDALE ROAD BALCATTA WA 6021", "226 MCINTYRE ROAD SUNSHINE VIC 3020", "UNIT 1 & 2, 12 PREMIER COURT WARANA QLD 4575", "PETERSHAM NSW 2049", "UNIT 7, 7 ERINDALE ROAD BALCATTA WA 6021", "226 MCINTYRE ROAD SUNSHINE VIC 3020", "UNIT 1 & 2, 12 PREMIER COURT WARANA QLD 4575", "WENTWORTHVILLE NSW 2049", "UNIT 7, 7 ERINDALE ROAD BALCATTA WA 6021", "MCINTYRE ROAD SUNSHINE VIC 3020", "UNIT 1 & 2, 12 PREMIER COURT WARANA QLD 4575", "PETERSHAM NSW 2049" };
There is a limit of 10 API calls per second when you are calling Google Maps APIs so I am passing 10 addresses to Parallel.ForEach loop and calling Google Geocode API. This will parallalize API calls. Also there is a check if all API calls finish within one second wait for 1 second before calling next batch to avoid getting QUERY_OVER_LIMIT error.
Parallel.ForEach(selected, new ParallelOptions() { MaxDegreeOfParallelism = 10 }, sel =>
{
try
{
string address = sel.ToString();
Console.WriteLine("Address = " + address);
GeoDetail objResult = GeoDetail.GetGeoDetails(key, address);
lock (lockMe)
{
lstResult.Add(objResult);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
});
GetGeoDetails() method calls Google Maps API using HttpRequest and Get HttpResponse object back which then being converted to JSON object using JSON.Net library.
public static GeoDetail GetGeoDetails(string APIKey, string address)
{
string uri = ConfigurationManager.AppSettings["URL"];
GeoDetail objResult = new GeoDetail() { Address = address, Latitude = -1, Longitude = -1, AddressType = "", Error = "" };
try
{
string requestURL = "";
if (ConfigurationManager.AppSettings["IsGoogleMapsAPIPaid"].Trim() == "0")
{
requestURL = uri + address + "&key=" + APIKey; // No need to sign URL and there is no APIClient ID to pass.
}
else
{
requestURL = GoogleSignedUrl.Sign(uri + address + "&client=" + ConfigurationManager.AppSettings["APIClient"].Trim(), APIKey);
}
HttpWebRequest request = WebRequest.Create(requestURL) as HttpWebRequest;
request.Accept = "application/json";
// Get response
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode == HttpStatusCode.OK)
{
StreamReader readert = new StreamReader(response.GetResponseStream());
string x = readert.ReadToEnd();
JObject jObject = JObject.Parse(x);
//Console.WriteLine(x);
if (jObject["status"].ToString() == "OK")// successful API call
{
if (jObject["results"].Count() > 0)
{
string locationType = jObject["results"][0]["geometry"]["location_type"].ToString();
string lat = jObject["results"][0]["geometry"]["location"]["lat"].ToString().Trim();
string lng = jObject["results"][0]["geometry"]["location"]["lng"].ToString().Trim();
Console.WriteLine("Geolocation lat lng : {0} {1} Type : {2}", lat, lng, locationType);
double? latValue = null;
double? lngValue = null;
if (!string.IsNullOrWhiteSpace(lat))
{
latValue = double.Parse(lat);
}
if (!string.IsNullOrWhiteSpace(lng))
{
lngValue = double.Parse(lng);
}
objResult.Latitude = latValue;
objResult.Longitude = lngValue;
objResult.AddressType = locationType; //locationType == "ROOFTOP")//exact address match
}
else
{
Console.WriteLine("No result found");
objResult.Error = "No result found";
}
}
else
{
Console.WriteLine(jObject["status"].ToString());
objResult.Error = jObject["status"].ToString();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
objResult.Error = ex.ToString();
}
return objResult;
}
Labels:
.NET,
C#,
Google Geocode API,
TPL
08 October 2015
Search all tables in MSSQL for a specific value in all columns
I came across this little snippet which creates a stored procedure that can be used to query all the tables in MSSQL database to search for specific value. It may be useful to someone looking for a similar solution
CREATE PROC SearchAllTables
(
@SearchStr nvarchar(100)
)
AS
BEGIN
CREATE TABLE #Results (ColumnName nvarchar(370), ColumnValue nvarchar(3630))
SET NOCOUNT ON
DECLARE @TableName nvarchar(256), @ColumnName nvarchar(128), @SearchStr2 nvarchar(110)
SET @TableName = ''
SET @SearchStr2 = QUOTENAME('%' + @SearchStr + '%','''')
WHILE @TableName IS NOT NULL
BEGIN
SET @ColumnName = ''
SET @TableName =
(
SELECT MIN(QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME))
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME) > @TableName
AND OBJECTPROPERTY(
OBJECT_ID(
QUOTENAME(TABLE_SCHEMA) + '.' + QUOTENAME(TABLE_NAME)
), 'IsMSShipped'
) = 0
)
WHILE (@TableName IS NOT NULL) AND (@ColumnName IS NOT NULL)
BEGIN
SET @ColumnName =
(
SELECT MIN(QUOTENAME(COLUMN_NAME))
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = PARSENAME(@TableName, 2)
AND TABLE_NAME = PARSENAME(@TableName, 1)
AND DATA_TYPE IN ('char', 'varchar', 'nchar', 'nvarchar', 'int', 'decimal')
AND QUOTENAME(COLUMN_NAME) > @ColumnName
)
IF @ColumnName IS NOT NULL
BEGIN
INSERT INTO #Results
EXEC
(
'SELECT ''' + @TableName + '.' + @ColumnName + ''', LEFT(' + @ColumnName + ', 3630)
FROM ' + @TableName + 'WITH (NOLOCK) ' +
' WHERE ' + @ColumnName + ' LIKE ' + @SearchStr2
)
END
END
END
SELECT ColumnName, ColumnValue FROM #Results
END
10 September 2015
Generic SQL Select Statement Executer in Java
In this post I will show you how to write a Java program that can allow you to run any SQL select statement against SQL Server and write output to csv file. While this is a simple task to use ResultSet and write output to file but imagine you need to keep on modifying output columns based on changes in business requirements or you need to output large number of SQL tables as csv files. In that case task gets little tedious and every time user request a new field to be added or removed you have to modify your class. This is where this trick comes handy.
You can download full source code from here : Generic SQL Select Statement Executer in Java
1. Lets create a new project in eclipse called SQLSelector and add a class file called GenericSelecor.java.
2. Next add sqljdbc4.jar and sqljdbc_auth.dll to your solution. This is required to connect to Microsoft SQL Server.
3. Add sqljdbc4.jar as a reference to your project by right clicking on project and going to properties and select java build path and libraries tab and click on Add Jar
4. Lets add two Properties file. One that is common for all SQL statements like database name,output folder etc and other one specific for current sql statement that will include Select statement, output file name and other specific information. I have Northwind database on my local machine and I want to select all customers from that database.
I have PROD.Properties file which contains database connection specific information.
Relative.Output.Folder=C\:\\SQLOutput\\
Server=localhost;instanceName=SQL2008
ODBC.DataSource=Northwind
I have Generic.Properties file which contains specific select statement and flag to indicate if string outputs should have double quotes
Statement=SELECT CustomerID ,CompanyName ,ContactName ,ContactTitle ,Address ,City ,Region ,PostalCode ,Country ,Phone ,Fax FROM Customers
OutputFileName = Customers.csv
StringOutputInDoubleQuote=Y
5. Now in GenericSelector class read those two properties files as arguments and read all the values in corresponding variables.
6.Load appropriate class driver and create connection to database. In this case I am using MSSQL server and connecting to Northwind database. Get a ResultSet by executing select statement. Get ResultSetMetaData from result set. This will help in identifying type of columns that are returned and name of those columns which then can be used to get the records from ResultSet without actually hard coding column names in application. ResultSetMetaData provides methods getColumnTypeName() and getColumnName() which are used to retrieve specific column information.
7. Now Iterate through each records in ResultSet and for each record find value by using its column name and column type that was retrieved using ResultSetMetaData and write to output file. Here I have checked for type of the column so I can use specific get method. If you don't require any formatting then you can use getObject() method of result set without worrying about underlying record type.
That is it!!! You have a fully functional java code that can create any table as csv output. All you need to do is change SQL in Generic.Properties file. Happy Coding !!!
You can download full source code from here : Generic SQL Select Statement Executer in Java
1. Lets create a new project in eclipse called SQLSelector and add a class file called GenericSelecor.java.
2. Next add sqljdbc4.jar and sqljdbc_auth.dll to your solution. This is required to connect to Microsoft SQL Server.
3. Add sqljdbc4.jar as a reference to your project by right clicking on project and going to properties and select java build path and libraries tab and click on Add Jar
4. Lets add two Properties file. One that is common for all SQL statements like database name,output folder etc and other one specific for current sql statement that will include Select statement, output file name and other specific information. I have Northwind database on my local machine and I want to select all customers from that database.
I have PROD.Properties file which contains database connection specific information.
Relative.Output.Folder=C\:\\SQLOutput\\
Server=localhost;instanceName=SQL2008
ODBC.DataSource=Northwind
I have Generic.Properties file which contains specific select statement and flag to indicate if string outputs should have double quotes
Statement=SELECT CustomerID ,CompanyName ,ContactName ,ContactTitle ,Address ,City ,Region ,PostalCode ,Country ,Phone ,Fax FROM Customers
OutputFileName = Customers.csv
StringOutputInDoubleQuote=Y
5. Now in GenericSelector class read those two properties files as arguments and read all the values in corresponding variables.
propertyFile = args[0];
statementFile= args[1];
Properties dpr = new Properties();
Properties spr = new Properties();
//Read all common variables from properties file
try
{
FileInputStream is = new FileInputStream(propertyFile);
dpr.load(is);
is.close();
Server=dpr.getProperty("Server");
DataSource=dpr.getProperty("ODBC.DataSource");
OutputFolder=dpr.getProperty("Relative.Output.Folder");
}
catch(Exception e)
{
e.printStackTrace();
System.exit(1);
}
// Read all specific variables from properties file
try
{
FileInputStream is = new FileInputStream(statementFile);
spr.load(is);
is.close();
selectSatement =spr.getProperty("Statement"); // This is the select statement from external file
outputFileName =spr.getProperty("OutputFileName");
stringOutputInDoubleQuote = spr.getProperty("StringOutputInDoubleQuote").toUpperCase();
}
catch(Exception e)
{
e.printStackTrace();
System.exit(1);
}
6.Load appropriate class driver and create connection to database. In this case I am using MSSQL server and connecting to Northwind database. Get a ResultSet by executing select statement. Get ResultSetMetaData from result set. This will help in identifying type of columns that are returned and name of those columns which then can be used to get the records from ResultSet without actually hard coding column names in application. ResultSetMetaData provides methods getColumnTypeName() and getColumnName() which are used to retrieve specific column information.
// Here we create a connection to database and run the query and then use metadata to generate csv output
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String sqlCmd = "";
con = DriverManager.getConnection("jdbc:sqlserver://"+Server+";databaseName="+DataSource+";integratedSecurity=true");
sqlCmd = selectSatement;
PreparedStatement stat = con.prepareStatement(sqlCmd);
ResultSet rs = stat.executeQuery(); // Actual Data
ResultSetMetaData rsmd = rs.getMetaData(); // Metadata from current result set.
int columnCount = rsmd.getColumnCount();
String[] columnTypes = new String[columnCount];
String[] columnNames = new String[columnCount];
StringBuilder sb = new StringBuilder();
rows=0;
// The column count starts from 1
for (int i = 1; i < columnCount + 1; i++ )
{
columnTypes[i-1] = rsmd.getColumnTypeName(i); // Get Column Type Names
String name = rsmd.getColumnName(i); // Get actual column names
columnNames[i-1] = name;
sb.append(name);
sb.append( i==columnCount ? "\n" : ",");
}
7. Now Iterate through each records in ResultSet and for each record find value by using its column name and column type that was retrieved using ResultSetMetaData and write to output file. Here I have checked for type of the column so I can use specific get method. If you don't require any formatting then you can use getObject() method of result set without worrying about underlying record type.
String DATETIME_FORMAT_QRY = "dd/MM/yyyy";
java.text.SimpleDateFormat sdf2 = new java.text.SimpleDateFormat(DATETIME_FORMAT_QRY);
while(rs.next())
{
rows++;
// Based on column type call appropriate getXXX() method to get value from database
// If you don't need specifc formatting based on data type you can use getObject() method instead of specific get method
for (int i = 1; i < columnCount + 1; i++ )
{
// If output column type is string type then either output it in double quote or as is based on flag
if(columnTypes[i-1]== "nchar" || columnTypes[i-1]== "nvarchar")
sb.append((rs.getString(columnNames[i-1]) == null ? "" : (stringOutputInDoubleQuote.equals("Y") ? "\""+ rs.getString(columnNames[i-1]).trim() + "\"" : rs.getString(columnNames[i-1]).trim())));
else if(columnTypes[i-1]== "decimal")
sb.append(rs.getDouble(columnNames[i-1]));
else if(columnTypes[i-1]== "int" || columnTypes[i-1]== "tinyint")
sb.append(rs.getInt(columnNames[i-1]));
else if(columnTypes[i-1]== "datetime")
sb.append(rs.getDate(columnNames[i-1])==null ? "" : sdf2.format(rs.getDate(columnNames[i-1])));
else
sb.append("ERROR IN INTERFACE : No check added for "+columnNames[i-1] );
sb.append( i==columnCount ? "\n" : ",");
}
// Write to file
if(rows>0)
{
if(rows==1) // Delete old file
{
File delfile = new File(OutputFolder+"/"+outputFileName);
delfile.delete();
}
FileOutputStream outFile = new FileOutputStream(OutputFolder+"/"+outputFileName,true);
outFile.write(sb.toString().getBytes());
outFile.close();
sb = new StringBuilder(); // Reset string builder for next iteration
}
}
That is it!!! You have a fully functional java code that can create any table as csv output. All you need to do is change SQL in Generic.Properties file. Happy Coding !!!
07 September 2015
Only allow digits in Console Application in C#
If you are writing a console application in C# and you want to restrict user to only enter digits for certain variable there is an option to use ConsoleKeyInfo struct to read each key user input and take action accordingly. This struct provides a way to find which key user has entered in console application and check if it is a number or not using Char.IsNumber() method.
Below is the complete source code that only allow user to enter digits for a field. If user type any other characters it simply ignores them.
Below is the complete source code that only allow user to enter digits for a field. If user type any other characters it simply ignores them.
Console.WriteLine("Enter Numeric Value : ");
ConsoleKeyInfo key;
string inputStr = "";
do
{
key = Console.ReadKey(true);
if (key.Key != ConsoleKey.Backspace && key.Key != ConsoleKey.Enter)
{
if (char.IsNumber(key.KeyChar))//Check if it is a number
{
inputStr += key.KeyChar;
Console.Write(key.KeyChar);
}
}
else
{
if (key.Key == ConsoleKey.Backspace && inputStr.Length > 0)
{
inputStr = inputStr.Substring(0, (inputStr.Length - 1));
Console.Write("\b \b");
}
}
} while (key.Key != ConsoleKey.Enter);
Console.WriteLine("\nNumber you entered is {0}", inputStr);
04 September 2015
Find Distinct Objects from List of Objects using LINQ
To find distinct values from list of values in C# is a one line task by using LINQ's Distinct() method. This works well with primitive types but if you run the same method on List of custom Objects you will not get distinct objects based on its properties. To achieve this you an option to implement IEqualityComparer interface and use it to find distinct objects based on its properties. In the implementation of Equals method you can define which properties to check for equality.
Below code provides the complete solution to get distinct objects from list of objects.
Below code provides the complete solution to get distinct objects from list of objects.
using System.Collections.Generic;
public class Team
{
public string Name {get;set;}
public int Score {get;set;}
}
//Create some dummy data with duplicates
public List<Team> lstTeam = new List<Team>{
new Team{Name="Brazil", Score=1},
new Team{Name="Man U", Score=1},
new Team{Name="Man U", Score=1},
new Team{Name="Brazil", Score=2},
new Team{Name="Man U", Score=2},
new Team{Name="Brazil", Score=2}
};
//This is where we use equality comparer implementation to find unique records
List<Team> lstDistictTeams = lstTeam.Distinct<Team>(new DistinctComparer()).ToList();
foreach(Team t in lstDistictTeams) // Output Distinct Objects
{
Console.WriteLine("Team {0} has Score {1}",t.Name,t.Score);
}
//This class provides a way to compare two objects are equal or not
public class DistinctComparer : IEqualityComparer<Team>
{
public bool Equals(Team x, Team y)
{
return (x.Name == y.Name && x.Score == y.Score); // Here you compare properties for equality
}
public int GetHashCode(Team obj)
{
return (obj.Name.GetHashCode() + obj.score.GetHashCode());
}
}
Labels:
.NET,
C#,
Distinct Objects,
LINQ,
List
14 May 2015
Copy Data between two different MSSQL Databases on different servers using C#
You can copy data from one SQL table to another using INSERT command with SELECT within same database or databases on same server but things gets little complicated when databases are on two different server. Here is a C# snipplet you can use to copy data between two desperate databases on two different servers. Code is self explanatory with comments. Your source and destination table fields needs to match.
// Create source connection
SqlConnection source = new SqlConnection(ConfigurationManager.ConnectionStrings["SourceConnectionString"].ConnectionString);
// Create destination connection
SqlConnection destination = new SqlConnection(ConfigurationManager.ConnectionStrings["DestinationConnectionString"].ConnectionString);
// Open source and destination connections.
source.Open();
destination.Open();
// Select data from Products table
SqlCommand cmd = new SqlCommand(@"SELECT customer
,name
,address1
,address2
,address3
,address4
,address6
,address5
,fax
,territory
,region
,class
FROM
[dbo].[slcustm]", source);
// Execute reader
Console.WriteLine("Read data from [dbo].[slcustm] table");
SqlDataReader reader = cmd.ExecuteReader();
Console.WriteLine("Write data to DestinationCustomers table");
// Create SqlBulkCopy
SqlBulkCopy bulkData = new SqlBulkCopy(destination);
//If you are copying larger amount of data don't forget to set the timeout flag. Default value is 30 seconds. 0 = No limit
bulkData.BulkCopyTimeout = 0;
// Set destination table name
bulkData.DestinationTableName = "DestinationCustomers";
// Write data
bulkData.WriteToServer(reader);
// Close objects
bulkData.Close();
destination.Close();
Labels:
.NET,
Bulk Copy Data,
C#,
MSSQL Server,
SQL
03 May 2015
ASP.NET Gridview with Filter in Header using Reflection and LINQ
Introduction
ASP.NETgridview by default provides facility for sorting
and paging but no inbuilt facility to filter column. This article looks
at possible way to implement filtering function within the Gridview.
Background
I came across this requirement of having agridview which allows filtering data from within the gridview. I also wanted to preserve the sorting and paging of the gridview. Rather than creating separate panel above
gridview for each of the fields to filter data, wouldn't it be nice to put a textbox along with each header column to filter data.This leads me to this solution I derived for it. This may not be the best solution to do it but it definitely works. Our goal is to achieve this.
You can download full source code from : ASP.NET Gridview with Filter in Header Source Code
How It All Works ?
Create ASP.NET Web Application project in Visual Studio. First of all, we will create a DTO class to hold some data that we can display in a gridview. For this demo, I have created a DTO class of outstanding orders that contains some properties and some dummy data.[Serializable]
public class Outstanding
{
public string Item { get; set; }
public string Order { get; set; }
public int Line { get; set; }
public int Status { get; set; }
public string ToLocation { get; set; }
public decimal Qty { get; set; }
public DateTime RegDate { get; set; }
public string Location { get; set; }
public decimal AllocQty { get; set; }
public List GetOutstanding()
{
List lstOrders = new List();
lstOrders.Add(new Outstanding() { Item = "CocaCola",
Order = "000101", Line = 1, Status = 20,
ToLocation = "Sydney",
Qty = 2000, RegDate = new DateTime(2014, 1, 1),
Location = "USA", AllocQty = 100 });
lstOrders.Add(new Outstanding() { Item = "BubbleGum",
Order = "000101", Line = 1, Status = 20,
ToLocation = "Sydney",
Qty = 2500, RegDate = new DateTime(2014, 1, 11),
Location = "USA", AllocQty = 300 });
lstOrders.Add(new Outstanding() { Item = "Coffee",
Order = "000111", Line = 1, Status = 50,
ToLocation = "Melbourne",
Qty = 2500, RegDate = new DateTime(2014, 1, 10),
Location = "USA", AllocQty = 100 });
lstOrders.Add(new Outstanding() { Item = "Sugar",
Order = "000112", Line = 1, Status = 50,
ToLocation = "Melbourne",
Qty = 2300, RegDate = new DateTime(2014, 1, 10),
Location = "NZ", AllocQty = 300 });
lstOrders.Add(new Outstanding() { Item = "Milk",
Order = "000112", Line = 1, Status = 50,
ToLocation = "Melbourne",
Qty = 2300, RegDate = new DateTime(2014, 1, 10),
Location = "NZ", AllocQty = 200 });
lstOrders.Add(new Outstanding() { Item = "Green Tea",
Order = "000112", Line = 1, Status = 20,
ToLocation = "Melbourne",
Qty = 300, RegDate = new DateTime(2014, 1, 10),
Location = "NZ", AllocQty = 220 });
lstOrders.Add(new Outstanding() { Item = "Biscuit",
Order = "000131", Line = 1, Status = 70,
ToLocation = "Perth",
Qty = 200, RegDate = new DateTime(2014, 1, 12),
Location = "IND", AllocQty = 10 });
lstOrders.Add(new Outstanding() { Item = "Wrap",
Order = "000131", Line = 1, Status = 20,
ToLocation = "Perth",
Qty = 2100, RegDate = new DateTime(2014, 1, 12),
Location = "IND", AllocQty = 110 });
return lstOrders;
}
}
Now in the Default.aspx page, add a gridview. To preserve sorting, add link button in HeaderTemplate with CommandName as "Sort" and CommandArgument as name of the column. Also, for the purpose of filtering the application will bind all the textboxes to single event (OnTextChanged="txtItem_TextChanged" ) and within the event we will determine which textbox fired it and take action accordingly. So columns of the gridview will look like this. I have used different filters like =,>,<,>=&<= for numeric data and "contains" filter for string values.
Note : Make sure you name all your textboxes as txtFieldName so when filtering we can remove the txt from the ID of the textbox and then use reflection and LINQ to filter the data.
<asp:TemplateField SortExpression="Item">
<HeaderTemplate>
<asp:LinkButton ID="lbItem" runat="server" Text="Item"
CommandName="Sort" CommandArgument="Item"></asp:LinkButton>
<br />
<asp:TextBox runat="server" ID="txtItem" AutoPostBack="true"
OnTextChanged="txtItem_TextChanged"></asp:TextBox>
</HeaderTemplate>
<ItemTemplate>
<%#Eval("Item") %>
</ItemTemplate>
</asp:TemplateField><asp:TemplateField SortExpression="Line"
ItemStyle-HorizontalAlign="Right" HeaderStyle-HorizontalAlign="Right">
<HeaderTemplate>
<asp:LinkButton ID="lbLine" runat="server" Text="Line"
CommandName="Sort" CommandArgument="Line"
CssClass="RightAlign"></asp:LinkButton>
<br />
<table>
<tr>
<td>
<asp:DropDownList runat="server"
ID="ddlFilterTypeLine" CssClass="upperCaseText">
<asp:ListItem Text="=" Value="="
Selected="True"></asp:ListItem>
<asp:ListItem Text=">" Value=">"></asp:ListItem>
<asp:ListItem Text=">=" Value=">="></asp:ListItem>
<asp:ListItem Text="<" Value="<"></asp:ListItem>
<asp:ListItem Text="<=" Value="<="></asp:ListItem>
</asp:DropDownList>
</td>
<td>
<asp:TextBox runat="server" ID="txtLine" Width="50"
AutoPostBack="true" OnTextChanged="txtItem_TextChanged"
CssClass="upperCaseText"></asp:TextBox>
</td>
</tr>
</table></HeaderTemplate>
<ItemTemplate>
<%#Eval("Line","{0:0}")%>
</ItemTemplate>
</asp:TemplateField>
Now in the Page_Load event, we will bind gridview to the dummy data. I have kept data in ViewState for this demo.
if (!Page.IsPostBack)
{
Outstanding objOutstanding = new Outstanding();
List lstOutstandingOrders = new List();
lstOutstandingOrders = objOutstanding.GetOutstanding();
ViewState["columnNameO"] = "RegDate";
grdViewOutstanding.DataSource = lstOutstandingOrders;
grdViewOutstanding.DataBind();
ViewState["lstOutstandingOrders"] = lstOutstandingOrders;
upnlOutstanding.Update();
}
In the textbox's text change event, we will find out which textbox fired it by looking at the ID of a sender and take action accordingly. Finally, we will bind the data to gridview. To preserve the values in filter after postback, I created a seperate method which gets called everytime postback occurs and set values in corresponding textboxes and filters after postback.
In here what happens is all the textboxes are bound to single event so when even is fired you will first find out which textbox has fired that event and remove txt from the ID of textbox to get the name of the property to filter. x.GetType().GetProperty(filterName).GetValue(x, new object[] { } ) provides the value of associated property from list of objects. This is using reflection to get the property of Outstanding class based on input "filterName" as string value and then get the value of the property from the object and compare it to what is passed in the textbox.
// For Outstanding Orders - Single Event bound to all textboxes
protected void txtItem_TextChanged(object sender, EventArgs e)
{
if (ViewState["lstOutstandingOrders"] != null)
{
List allOutstanding = (List)ViewState["lstOutstandingOrders"];
TextBox txtBox = (TextBox)sender;
string filterName = txtBox.ID.Substring(3); // remove txt from Textbox ID. You need to make sure that all the textboxes for filtering are named as txtFieldName
//Check if there is a dropdown associated with current filter.
if (grdViewOutstanding.HeaderRow.FindControl("ddlFilterType" + filterName) != null)
{
//Get value from filter type dropdown
string filtrerType = ((DropDownList)grdViewOutstanding.HeaderRow.FindControl("ddlFilterType" + filterName)).SelectedItem.Value;
//Special case for DateTime
if (filterName == "RegDate")
{
DateTime filterValue = DateTime.Parse(txtBox.Text.Trim());
//Use LINQ reflection to find value for the input filer value
//x.GetType().GetProperty(filterName).GetValue(x, new object[] { })-- This is the LINQ reflection to get value
//x.GetType().GetProperty(filterName) -- This gives you the actual property associated with Outstanding class based on input property name as string value.
//Then we call get value to get its acutal value and compare it with what is being passed into textbox
if (filtrerType == "=")
allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) == filterValue).ToList();
else if (filtrerType == ">")
allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) > filterValue).ToList();
else if (filtrerType == ">=")
allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) >= filterValue).ToList();
else if (filtrerType == "<")
allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) < filterValue).ToList();
else if (filtrerType == "<=")
allOutstanding = allOutstanding.Where(x => DateTime.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) <= filterValue).ToList();
}
else // Parse Numbers as decimal
{
if (filtrerType == "=")
allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) == decimal.Parse(txtBox.Text.Trim())).ToList();
else if (filtrerType == ">")
allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) > decimal.Parse(txtBox.Text.Trim())).ToList();
else if (filtrerType == ">=")
allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) >= decimal.Parse(txtBox.Text.Trim())).ToList();
else if (filtrerType == "<")
allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) < decimal.Parse(txtBox.Text.Trim())).ToList();
else if (filtrerType == "<=")
allOutstanding = allOutstanding.Where(x => decimal.Parse(x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString()) <= decimal.Parse(txtBox.Text.Trim())).ToList();
}
//Hold Filter Type in ViewState to preserve what is selected for use during postback
ViewState["OFilter" + filterName] = filtrerType;
}
else // Only string value
{
allOutstanding = allOutstanding.Where(x => x.GetType().GetProperty(filterName).GetValue(x, new object[] { }).ToString().ToUpper().Contains(txtBox.Text.Trim().ToUpper())).ToList();
}
//Hold the filter value in ViewState. This will be used in ResetFilterAndValueOutstanidn() during postback
ViewState["O" + filterName] = txtBox.Text.Trim().ToUpper();
ViewState["lstOutstandingOrders"] = allOutstanding;
grdViewOutstanding.DataSource = allOutstanding;
grdViewOutstanding.DataBind();
ResetFilterAndValueOutstanding();
}
}
ResetFilterAndValueOutstanding() method restores values in filter textbox and filter type in dropdown after each postback. All the filter values and filter types are stored in ViewState with key value starting with "O". Make sure you don't store any other data in ViewState with key value starting with "O" because when removing the filter we will remove all the ViewState values starting with "O". protected void ResetFilterAndValueOutstanding()
{
//All the filters and filtervalues are stored in ViewState staring with "O"
foreach (var k in ViewState.Keys)
{
if (k.ToString().StartsWith("O"))
{
//Check if there is a textbox in GridView Header for this ViewState value.
if (grdViewOutstanding.HeaderRow.FindControl("txt" + k.ToString().Substring(1)) != null)
{
((TextBox)grdViewOutstanding.HeaderRow.FindControl("txt" + k.ToString().Substring(1))).Text = ViewState[k.ToString()].ToString().ToUpper();
}
//Check if there is a dropdownlist in GridView for this ViewState value.
if (grdViewOutstanding.HeaderRow.FindControl("ddlFilterType" + k.ToString().Substring(1)) != null)
{
foreach (ListItem li in ((DropDownList)grdViewOutstanding.HeaderRow.FindControl("ddlFilterType" + k.ToString().Substring(1))).Items)
{
if (li.Text == ViewState["OFilter" + k.ToString().Substring(1)].ToString()) li.Selected = true; else li.Selected = false;
}
}
}
}
}
Add a link button on top of the gridview called "Remove Filter" which will remove all the ViewState with keys starting with "O" and rebind gridview to data and reset all filters to its original values.
protected void lbRemoveFilterOutstanding_Click(object sender, EventArgs e)
{
//Find all the ViewState Keys starting with "O". This represents Filters and Filter Values
List lstKeysToRemove = new List();
foreach (var k in ViewState.Keys)
{
if (k.ToString().StartsWith("O"))
{
lstKeysToRemove.Add(k.ToString());
}
}
foreach (string key in lstKeysToRemove)
{
ViewState.Remove(key);
}
Outstanding objOutstanding = new Outstanding();
List lstOutstandingOrders = new List();
lstOutstandingOrders = objOutstanding.GetOutstanding();
grdViewOutstanding.DataSource = lstOutstandingOrders;
grdViewOutstanding.DataBind();
ViewState["lstOutstandingOrders"] = lstOutstandingOrders;
}
There is paging and sorting enabled on the gridview which is easy to understand. This is one of the way to implement filtering on a gridview with paging and sorting.Happy Coding !!!
15 September 2010
File Not Found Exception in Application_Error of Global.asax
I got this nasty error of "File Not Found." in Application_Error of Global.asax file on every web page request of my web application in ASP.NET. I try to check what is causing this File Not Found exception on every single request. Initially I try to catch the exception and check what is stack trace is saying but that is of not much help as there wasn't any indication what is causing it. Then I found the solution. Here it is for those who are trying to resolve it. Save some of your productive hours.
Step 1 : Set break point at Application_Error of Global.asax .
Step 2 : Start debugging your application and when the request hit the Application_Error break point type
into Watch window of visual studio.
This will give you the information on which resource is missing and why this specific exception is generated on every single request.
Happy Coding !!!
Step 1 : Set break point at Application_Error of Global.asax .
Step 2 : Start debugging your application and when the request hit the Application_Error break point type
((HttpApplication)sender).Context.Request.Url
into Watch window of visual studio.
This will give you the information on which resource is missing and why this specific exception is generated on every single request.
Happy Coding !!!
23 May 2010
Show Session Timeout countdown on ASP.NET page
Hi,
I came across a really nice feature that you can use in ASP.NET to show session timeout to users. This provides rich user experience. I used javascript to create this facility. Hope this will help someone looking for the solution.
add a span named countDown to the page where you want to display this session timeout message. If you want it to display on all the pages once user is logged in then put it in Master page and voila !!! Your session timeout message will be there to warn user.
I came across a really nice feature that you can use in ASP.NET to show session timeout to users. This provides rich user experience. I used javascript to create this facility. Hope this will help someone looking for the solution.
var timeout = '<%= Session.Timeout * 60 * 1000 %>';
var timer = setInterval(function() { timeout -= 1000; document.getElementById('countDown').innerHTML = time(timeout); if (timeout == 0) { clearInterval(timer); alert('Your session has expired!') } }, 1000);
function two(x) { return ((x > 9) ? "" : "0") + x }
function time(ms) {
var t = '';
var sec = Math.floor(ms / 1000);
ms = ms % 1000
var min = Math.floor(sec / 60);
sec = sec % 60;
t = two(sec);
var hr = Math.floor(min / 60);
min = min % 60;
t = hr+":"+two(min) + ":" + t;
return "You session will timeout in " + t ;
}
add a span named countDown to the page where you want to display this session timeout message. If you want it to display on all the pages once user is logged in then put it in Master page and voila !!! Your session timeout message will be there to warn user.
<span id="countDown"> </span>
14 April 2010
Creating Custom Membership Provider for Login Control in ASP.NET
You may have came across the situation where you want to use .NET's membership provider facility but don't want to use tables and stored procedures generated by aspnet_regsql.exe . You want to use your own simple Users table in your own database with just few fields like UserID, Password and Role. It may seems like a big task to create your own Membership Provider to use your own login logic but it is not that hard. Just follow the steps below :
1 > Create your own Membership Provider Class and inherit it from base MembershipProvider class. If you are using VB.NET the needed methods are added automatically. If you are using C# just right click the MembershipProvider class and add the properties and methods . Don't forget to import System.Configuration.Provider namespace.
The IDE will generate all the methods and properties and you don't have to implement all of them.
The only method that you need to implement is ValidateUser(string username, string password)
You can leave all the other methods throw an exception unless you explicitly want the facility provided by non implemented method.
2 > Add CustomeMemberShip Provider to your web.config
3.> Add Membership Provider for your login control on Login.aspx page.
In the Properties window of the Login control set MembershipProvider to your MyCustomeMembershipProvider class.
That is it.
Off you go to your own login logic with custom membership provider.
1 > Create your own Membership Provider Class and inherit it from base MembershipProvider class. If you are using VB.NET the needed methods are added automatically. If you are using C# just right click the MembershipProvider class and add the properties and methods . Don't forget to import System.Configuration.Provider namespace.
The IDE will generate all the methods and properties and you don't have to implement all of them.
The only method that you need to implement is ValidateUser(string username, string password)
You can leave all the other methods throw an exception unless you explicitly want the facility provided by non implemented method.
public class MyCustomMemershipProvider : MembershipProvider
{
public int TryLogin(string id, string pass) // My own login method
{
int roleId = 0;
DatabaseUtilityHelper databaseHelper = new DatabaseUtilityHelper();
SqlConnection con = databaseHelper.GetBBCDatabaseConnection();
SqlParameter[] agentParams = new SqlParameter[] {
new SqlParameter("@UserId",id),
new SqlParameter("@Password",pass)};
con.Open();
SqlDataReader reader = DatabaseUtility.ExecuteReader(con, "login_user", CommandType.StoredProcedure, agentParams);
if (reader.Read())
{
roleId = Int32.Parse(reader.GetSqlValue(1).ToString());
}
else
{
roleId = 0;
}
con.Close();
return roleId;
}
public override string ApplicationName
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
.....
..... // Generated Code
....
....
public override bool ValidateUser(string username, string password)
{
int result = TryLogin(username, password);
if (result > 0)
{
return true;
}
else
{
return false;
}
}
2 > Add CustomeMemberShip Provider to your web.config
<membership defaultProvider="MyCustomMemershipProvider"> <providers> <clear/> <add name="MyCustomMemershipProvider" type="BBCApplication.BusinessLogic.MyCustomMemershipProvider"/> </providers> </membership>
3.> Add Membership Provider for your login control on Login.aspx page.
In the Properties window of the Login control set MembershipProvider to your MyCustomeMembershipProvider class.
That is it.
Off you go to your own login logic with custom membership provider.
20 November 2009
Set NTFS folder permissions on remote machine using .NET and WMI
After considerable amount of efforts and trial I was finally able to hack the solution to set NTFS permissions on a remote machine using .NET. For local file system it is just couple of line of codes and it works like a charm but when it comes to remote machines it just gives you a nightmare . So here goes my solution. I am sure this will help someone.
public bool SetPermissions(string remoteDir, string MachineName, string UserName, string Password) // Username and Password is of Admin account on remote machine
{
string TempName = remoteDir;
int Index = TempName.IndexOf(":");
string DriveLetter = ConfigurationManager.AppSettings["ShareDriveLetter"]; // e.q. C
if (Index != -1)
{
string[] arr = TempName.Split(new char[] { ':' });
DriveLetter = arr[0];
TempName = TempName.Substring(Index + 2);
}
ManagementPath myPath = new ManagementPath();
myPath.NamespacePath = @"root\CIMV2";
ConnectionOptions oConn = new ConnectionOptions();
oConn.Username = UserName;
oConn.Password = Password;
oConn.EnablePrivileges = true;
myPath.Server = MachineName;
ManagementScope scope = new ManagementScope(myPath, oConn);
scope.Connect();
//without next strange manipulation, the os.Get().Count will throw the "Invalid query" exception
remoteDir = remoteDir.Replace("\\", "\\\\");
ObjectQuery oq = new ObjectQuery("select Name from Win32_Directory where Name = '" + remoteDir + "'");
using (ManagementObjectSearcher os = new ManagementObjectSearcher(scope, oq))
{
if (os.Get().Count == 0) //It don't exist, so create it!
{
ManagementPath path2 = new ManagementPath();
path2.Server = MachineName;
path2.ClassName = "Win32_Process";
path2.NamespacePath = @"root\CIMV2";
ManagementScope scopeProcess = new ManagementScope(path2, oConn);
using (ManagementClass process = new ManagementClass(scopeProcess, path2, null))
{
//Command line that you want to execute on remote machine
string commandLine = @"cmd /C cacls " + TempName +" /C /T /E /P "+"0909020:F"; // 0909020:F is username:permissions
using (ManagementBaseObject inParams = process.GetMethodParameters("Create"))
{
inParams["CommandLine"] = commandLine;
inParams["CurrentDirectory"] = DriveLetter + @":\\";
inParams["ProcessStartupInformation"] = null;
using (ManagementBaseObject outParams = process.InvokeMethod("Create", inParams, null))
{
int retVal = Convert.ToInt32(outParams.Properties["ReturnValue"].Value);
return (retVal == 0);
}
}
}
}
else
{
return true;//if exists, return true; you may want to return false, of course
}
}
return false;
}
08 October 2009
Microsoft launches Windows smartphones : My view on it
Microsoft is in a battle to reincarnate its dinosaur mobile OS with launch of its own smartphone.The phones, which combine the ability to make calls, surf the internet and view videos, carry Microsoft's Windows Mobile 6.5 operating system.I know you will go like Hey don't we already have that. Don't you think it is too little too late !!! The smartphone market is already saturated with lots of different OS and the major ones like Apple's iPhone system, Plam OS, Google's Android (which is a free platform) and Symbian OS. The new venture Microsoft is attempting is just a desperation to gain market that it already lost to big guys like Google and Apple. In a official launch Mr. Ballmer said "We have taken the Internet Explorer browser technologies, and we rebuilt them for the first time for these Windows phones. So you can get the same experience on these phones that you will get on your windows PC." (Hey watch out, The Blue Screen Of Death (BSOD) is coming to your smartphones !!!) Is that the way you promote your technology. A reincarnated IE ??? Lets face it IE is no where near the facilities provided by other browsers like Mozilla Firefox and with the new kid on the block called Crome which is improving at a speed of light (Well that is an exaggeration but you know what I mean !!!). Microsoft needs to come up with something new that is authentic and that can make others to follow it rather than just trying to get the market that is already saturated. Get a life Microsoft and you really needs some great minds to think of products Mr. Ballmer !!!
03 October 2009
Google Wave: What is it ?

There is a new Google product called Google Wave currently under limited preview. Some of you may have already tried it or at least looked at its video or you may not have any idea about whatsoever. In a simple term it a mashup of emails,documents and social networking. Don't scratch your head. Just go to google and google it! (How ironic !!!). You can look at a video on youtube that explains it in a simple terms. and if you want to get a detailed explanation of it go to Google Wave's website and spare yourself an hour of amazement.
Here is a simple explanation of what you can do with google wave.
For Example you want to know more about Sydeny Opera House. So you start a new wave with this topic and invite your friends. Once they join the wave they can comment on it and everyone who are in the wave can view it and provide their opinion. You will go so whats a big deal here ? You can also share photographs and documents. It can be a really good collaboration platform.
So head out to Google Wave and enjoy it.
30 May 2009
Microsoft's Bing search engine comming soon

Did you heard the news ? What news ? Hey don't worry its not new development in Swine Flue pandemic ! Microsoft is launching its new search engine. You will say don't they have one called "Live". "May be its time for Live to be dead and get reincarnation as a Bing." The reason they are coming up with new search engine is the Live search is not giving them revenue they are expecting and Google is dominating the search engine market and certainly making its more than 90% revenue out of it. So the big guy (Microsoft) want big chunk of the pie rather then just a piece.
Microsoft CEO Steve Ballmer in San Diego during D7 Conference officially launched its new search engine called Bing that previously code named as "Kumo". Microsoft is calling it a decision engine rather than a search engine. Hey don't worry it gives you the search result only not the decision on what to eat today !!!
I have a look at its video and first impression was really awesome.I am not exaggerating.Check out its video Here . You can get more information on Bing Here.
It may be the time for Google to worry a bit. Well it takes a really big effort to get people to use new search engine. "Google become more of a verb than a noun in last decade." Google will certainly reply back to Bing with whatever it takes to sustain its position. Microsoft is also launching $80 to $100 million advertising campaign to promote Bing. By the time, lets enjoy this new battle as it progress and get the most out of it.
17 May 2009
Google's new features : Wonder wheel
Hey, Did anyone noticed Google's new feature when you search something. It gives you more control over your search query. You can see the hyperlink came up when you search something called Show options.... You click on it and magic happens.... well you will say what is new with that options panel. But as you can notice it allows you to filter your result with regards to the time articles published, if you want to see only videos or forums or reviews and there is something very special called wonder wheel. You click on it and it gives you the options to further refine your result. It is really cool.!!!
For example you search for car dealers in sydney and click on the wonder wheel and it automatically refine your search result and allow you to pick up options to go for particular area in sydney and when you choose something it further gives you the options to choose type of car you want. I find it really cool and I am sure you will also enjoy it. Though it is a good option for end users it is a pain in ass for Search Engine Optimization (SEO) guys as they have to take into account this new feature and try to rank their websites for all possible keywords. It will certainly take time for people to get used to with this new feature and use it more frequently and by that time SEO guys needs to come up with solutions to fool this wonder wheel. I hope they will find out something very soon otherwise they are in trouble.
By the time enjoy coffee... and think of ideas.....
10 May 2009
Serialization in .NET
This article is about serialization facility in .NET framework and particularly Object Serialization. So lets start from scratch and define first what is serialization ?
Serialization is the process of storing objects to the file or isolated file and later use it in the same application or same process or in another application on remote machine. It is just like you store data to a file and later use it in another application or same application. The difference here is you are storing objects not some random data and later recreate same object via deserialization.
This process is made simple via .NET frameworks serialization classes. The namespace we are looking here is System.Runtime.Serialization. Serialization save a lot of development time. There are three different kind of serialization provided by .NET framework.
1. Object Serialization
2. XML Serialization
3. Custom Serialization
In this article we will look at Object Serialization.
To serialize an object is very simple process.
1. Create a stream object that can hold the serialized object.
2. Create a BinaryFormatter object (namespace System.Runtime.Serialization.Formatters.Binary).
3. Call BinaryFormatter.Serialize method to serialize the object and output it to a stream.
Lets see it in example. I use C# as a programming language here.
// string object data that is to be serialized.
string data = "This data is to be serialized";
// Create a file stream to save data.
FileStream fs = new FileStream("mySerialiedData.dat",FileMode.Create);
//Create BinaryFormatter object
BinaryFormatter bf = new BinaryFormatter();
// use bf object to serialize data.
bf.Serialize(fs,data);
//close file stream
fs.Close();
That's it the data object is serialized and stored in file mySerializedData.dat.
You can deserialize it using BinaryFormatter's Deserialize method. You need to cast the object back to proper data type.
FileStream fs = new FileStream("mySerializedData.dat",FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
string data = (string) bf.Deserialize(fs); // cast it back to string object
fs.close();
You can serialize and deserialize any object using same technique.
You can make the custom class Serializable and Deserializable by using [Serializable] attribute.
For example:
[serializable]
class Product
{
public int id;
public string name;
public float price;
public double tax;
}
If tax is calculated using value of price than there is no need to serialize it to reduce the size of serialized object. To do this declare it as a [NonSerialized] attribute and implement IDeserializationCallback interface to calculate it when deserializing the object.
For example:
[serializable]
class Product : IDeSerializationCallback
{
public int id;
public string name;
public float price;
[NonSerialized]public double tax;
void IDeserializationCallback.OnDeserialization(object sender)
{
tax = price*0.1;
}
}
Now the value of tax will be available to the application that deserialize the object of Product class via OnDeserializing callback method.
This is how the serialization works in .NET environment. Isn't it really simple? So enjoy serializing. And by the way the closest resemblance to serialization is the teleportation in science fiction !
Serialization is the process of storing objects to the file or isolated file and later use it in the same application or same process or in another application on remote machine. It is just like you store data to a file and later use it in another application or same application. The difference here is you are storing objects not some random data and later recreate same object via deserialization.
This process is made simple via .NET frameworks serialization classes. The namespace we are looking here is System.Runtime.Serialization. Serialization save a lot of development time. There are three different kind of serialization provided by .NET framework.
1. Object Serialization
2. XML Serialization
3. Custom Serialization
In this article we will look at Object Serialization.
To serialize an object is very simple process.
1. Create a stream object that can hold the serialized object.
2. Create a BinaryFormatter object (namespace System.Runtime.Serialization.Formatters.Binary).
3. Call BinaryFormatter.Serialize method to serialize the object and output it to a stream.
Lets see it in example. I use C# as a programming language here.
// string object data that is to be serialized.
string data = "This data is to be serialized";
// Create a file stream to save data.
FileStream fs = new FileStream("mySerialiedData.dat",FileMode.Create);
//Create BinaryFormatter object
BinaryFormatter bf = new BinaryFormatter();
// use bf object to serialize data.
bf.Serialize(fs,data);
//close file stream
fs.Close();
That's it the data object is serialized and stored in file mySerializedData.dat.
You can deserialize it using BinaryFormatter's Deserialize method. You need to cast the object back to proper data type.
FileStream fs = new FileStream("mySerializedData.dat",FileMode.Open);
BinaryFormatter bf = new BinaryFormatter();
string data = (string) bf.Deserialize(fs); // cast it back to string object
fs.close();
You can serialize and deserialize any object using same technique.
You can make the custom class Serializable and Deserializable by using [Serializable] attribute.
For example:
[serializable]
class Product
{
public int id;
public string name;
public float price;
public double tax;
}
If tax is calculated using value of price than there is no need to serialize it to reduce the size of serialized object. To do this declare it as a [NonSerialized] attribute and implement IDeserializationCallback interface to calculate it when deserializing the object.
For example:
[serializable]
class Product : IDeSerializationCallback
{
public int id;
public string name;
public float price;
[NonSerialized]public double tax;
void IDeserializationCallback.OnDeserialization(object sender)
{
tax = price*0.1;
}
}
Now the value of tax will be available to the application that deserialize the object of Product class via OnDeserializing callback method.
This is how the serialization works in .NET environment. Isn't it really simple? So enjoy serializing. And by the way the closest resemblance to serialization is the teleportation in science fiction !
06 May 2009
Windows 7 Release Candidate
Hi All,
Watch out !!! Windows 7 is on its way. Release Candidate is available for download now. Though its not final version yet RC is more close to the final version. Those who may have used beta or wants to check whats new can download it from Microsoft Windows 7 official website. Have a look at the systems requirements.
A PC for testing that meets these minimum system requirements (specific to Windows 7 RC and subject to change in the final version of Windows 7):
*1 GHz or faster 32-bit (x86) or 64-bit (x64) processor
*1 GB RAM (32-bit) / 2 GB RAM (64-bit)
*16 GB available disk space (32-bit) / 20 GB (64-bit)
*DirectX 9 graphics processor with WDDM 1.0 or higher driver
One thing is sure it is going to be the big installation. So those who are using XP on old systems might be disappointed. And one advise those who are buying PC or Notebook at the moment. Wait for a while or ask your dealer if you can get the free upgrade to Windows 7 in future.
Watch out !!! Windows 7 is on its way. Release Candidate is available for download now. Though its not final version yet RC is more close to the final version. Those who may have used beta or wants to check whats new can download it from Microsoft Windows 7 official website. Have a look at the systems requirements.
A PC for testing that meets these minimum system requirements (specific to Windows 7 RC and subject to change in the final version of Windows 7):
*1 GHz or faster 32-bit (x86) or 64-bit (x64) processor
*1 GB RAM (32-bit) / 2 GB RAM (64-bit)
*16 GB available disk space (32-bit) / 20 GB (64-bit)
*DirectX 9 graphics processor with WDDM 1.0 or higher driver
One thing is sure it is going to be the big installation. So those who are using XP on old systems might be disappointed. And one advise those who are buying PC or Notebook at the moment. Wait for a while or ask your dealer if you can get the free upgrade to Windows 7 in future.
21 April 2009
Oracle to buyout Sun Microsystems
Yesterday Oracle Corporation formally announced its intention to buy Sun Microsystems. This is bit of a shock news for me and sure for lot of those who follow Sun closely. Hey my concern is not about dog eat dog situation here. The big question that concern me is that Is it the end of open source era? I hope certainly not. As Sun Microsystems is the biggest Open Source solutions and products provider and lots of penetration in the market this potential take our will create big concern in the market. Lets See how this goes as the Oracle still have to overcome stakeholders approval of this big transaction. Can Oracle really be the Oracle (the one that can see in future) and snatch the deal? You can read the story on Oracle Press release.
Subscribe to:
Posts (Atom)


