Archive

Posts Tagged ‘Computer’

IIS Smooth Streaming

After surviving from toughest weeks of final exams, having a talk at MIND (Malaysian Independent Developers) event was an amazing relief. My chosen topic was IIS Smooth Streaming from development prospective. After a good presentation, I decided to share the resulting presentation file in my blog to make it available to wider audience.

This work is a collection of notes around the web that can be gathered together to form a solid scenario. I hope you enjoy it.

Finally I should deeply thank some respected members of the community because of their helps and their informative presentations at this event: Daqing Lee, Riza Marhaban, Arsalan Pour Fard and Mostafa Abedi.

Advertisements

Web forms or ASHX (Handlers) (a short differentiation)

“What should I choose [Web-forms or Handlers] when I want a simple response from the server? “. After 6 years of development with C#.net I heard this question a lot. Due to this, I decide to answer it here.

Web forms VS ASHX

Fig 1.0

Assume that you are developing a JQuery AJAX based application that sends its requests to servers and receives a specific response from it. In this case the first solution that may strike you is using handlers. Maybe because of some features I list here:

–          It returns only a specific response; it is so light and is not derived from a heavy class that may have some performance penalties.

–          Unlike a web form it doesn’t need to compile its interface, generates HTML and returns the generated HTML to clients.

–          Unlike web services (mostly used before .Net 3.0), it returns almost all of request’s properties. One of the most prominent one is users’ identity.

Yes, using Handlers has many, many benefits but choosing to use them for such purpose may bring many problems as well.

In a standard web-form programming (I’d better say as a good OOP practice) you should implement a multi-layered

Web forms VS ASHX (Handlers)

Fig 2.0

inheritance for all of your web-forms. It is totally a beginner’s mistake to inherit a web-form directly from System.Web.UI.Page.

In this approach (Fig 2.0) you distribute each group of actions to separate layers. For instance, you place secure parts (handling authorized users) inside SecurityWeb class, non-secure parts placed into NonSecureWeb class etc. Finally, all of your customized classes can inherit from WebBase class which executes your common and shared operations. WebBase class is also derived from the built-in System.Web.UI.Page class.

Now, you have built a clean architecture for security, caching, common operations/properties and many more. Just assume that you want to enforce all of the functionalities you defined in your layered architecture take place in you AJAX handlers. Assuming that you handle the incoming requests with a handler class. A handler class that cannot inherit anything from a parent class. So there is almost no clean and neat way to have all of your efforts happen before executing the handler’s block. You have no choice to make external calls to other classes by passing heavy objects and parsing the return values!!

This is just duplicating many of your codes that results in inconsistent and non-secure consequences.

Better solution:
The alternative is to replace the handler class with a web-form one that inherits from an/other parent class/es. Now you can have all of the important actions happen in almost everywhere without any code duplication or security problem outcomes.

Indeed, Web forms are heavy, very heavy. Here I provided my common practice to decrease some weigh of this fatty class.

How to make web forms act close to handlers:

By adding the following code you can easily change the behavior of ASPX files to act similarly with ASHX files:

Response.Clear();
Response.ContentType = "text/html";
Response.Expires = -1;
Response.CacheControl = "no-cache";
Response.AddHeader("Pragma", "no-cache");
Line6: string response = "";</pre>
<pre>// your process over Request and generate the Response</pre>
<pre>Response.Write(response);
Response.End();

Above, is a sample that returns a text. Obviously, you can change it to any desired return value. Line 6 is where you should place your operation to feed the response variable.

You reached the end:). I should thank for your attention, deeply appreciate your sharing thoughts about this post and looking forward to receiving them here 😉

.Net Generics (Performance and flexibility)

April 17, 2011 2 comments

I discussed the reason of using Generics in another article. Here it’s aimed to talk about Generics in detail.

Generics are a part of CLR type system that allows you to develop your own types which are flexible in their parameters’ type. Therefore, it allows you to help your consumers feel comfortable while using your class. The most common use for Generics is data types such as lists, linked lists, stacks, trees etc where the operations on each item is done in the same way regardless of their types.

MS Generics

Fig 1

Why using Generics:

1-      Improve performance: As it’s discussed in my previous article, assume that you have a class that its parameters’ type is not specified. You have two choices to build it. One way is to use Object as your parameters’ type which in most cases it needs boxing and unboxing. The second way is to use Generics which has no boxing and unboxing but has almost the same flexibility as Object hast.

2-      Less runtime errors: While you are using Object you need to convert it in order to use it. And because it is not possible to check the parameters’ type in compile-time compiler needs to do type-checking in runtime. In this case, if you cast it to wrong type compiler raises type mismatch error. In contrary, using Generics doesn’t have this issue since its strongly-typed data type, compiler can catch this matching at compile-time.

 

Creating generics types:

It is quite a fun. You just need to specify the name of parameters that are type flexible. After that everything is done by .Net.

class GenericsTemplate<T, U>

{

T t;

U u;

public GenericsTemplate(T t, U u)

{

this.u = u;

this.t = t;

}

public string getT

{

get { return t.ToString(); }

}

public string getU

{

get { return u.ToString(); }

}

}

Here you have a flexible class which can accept all possible types! Isn’t it easy!! :D. It can be int, string, a custom class or any other type.

How to use it:

Parameters’ type are defined in class instantiation.

class Program

{

static void Main(string[] args)

{

GenericsTemplate<string, int> genClass = new GenericsTemplate<string, int>("Hello World", 560);

Console.Write(genClass.getT + Environment.NewLine + genClass.getU);

Console.ReadKey();

}

}

Since parameters’ type is specified in declaration, compiler can check for any mismatch error.

How to use constraints:

Did you find it useful? But I think you found some limitations in using these variables inside the generic class. You can only have capabilities of base Object data-type which are ToString() and GetHashCode() methods. To overcome this problem .Net introduces a key word called where. This key word can be used to limit the range of possible types that parameter’s can accept. This limitation may also reduce the complexity of consuming your generic class since developers (consumers) won’t be confused among too many possible types can be used.

This limitation can be applied for:

1-      Reference or value type: Forces a parameter to accept data-types which are either reference type or value type. (Key words are class for reference type and struct for value type)

2-      Interface: Parameter can accept types which have a specific implemented interface.

3-      Base class: Parameter can accept types which have a specific inherited interface.

4-      Constructor: Forces a parameter to accept data-types which has a default constructor (parameterless constructor). (Key word is new())

class Program

{

static void Main(string[] args)

{

System.Drawing.Bitmap bt = new System.Drawing.Bitmap(800, 500);

//Bitmap is an inherited class from Image and int is a value type which has implemented IComparable interface

GenericsTemplate<System.Drawing.Bitmap, int> genClass = new GenericsTemplate<System.Drawing.Bitmap, int>(bt, 560);

Console.Write(genClass.getT + Environment.NewLine + genClass.getU);

Console.ReadKey();

}

}

//T should be a reference type and an instance of Image class or any class inherited from Image. U sould be value type and has implemented IComparable interface

class GenericsTemplate<T, U> where T: class, System.Drawing.Image where U: struct, IComparable

{

T t;

U u;

public GenericsTemplate(T t, U u)

{

this.u = u;

this.t = t;

}

public string getT

{

//You can use all properties of Image base class while useing t

get { return t.Width.ToString(); }

}

public string getU

{

get { return u.ToString(); }

}

}

You should follow a correct order (order as listed above).

After defining constraints for generic class you can use added capabilities of parameters inside the class. Here I used Width property of base Image class.

Boxing and Unboxing (A key reason to use Generic)

April 7, 2011 2 comments

This article is a discussion about boxing and unboxing in .Net and also the ways to overcome it.

This term is mostly used when we want to convert value types to reference types or vice versa. We really should care about it in development of critical systems, web applications with high traffic or using classes or methods with frequent use.

Boxing: This is the process of converting the value of a value type variable to a reference type variable.

Assume that you want to store a user-defined type (struct) into an ArrayList (As you know user-defined/struct types are value type). Now let’s know what is stored in this ArrayList?

If you take a look at the Add() method of ArrayList, it has only one overload for this method which is Add(Object object) [and Object is a reference type]. It is good news due to the possibility of storing totally different types into each index of an ArrayList. However, it has some bad news too because it needs to convert your value type variable to a reference type variable. It means that it needs a boxing to fulfill this need.

struct TypeA

{

public int VarA;

public int VarB;

public TypeA(int VarA, int VarB)

{

this.VarA = VarA;

this.VarB = VarB;

}

}

public void TestBoxingAndUnBoxing()

{

TypeA typeA = new TypeA(10, 20);

System.Collections.ArrayList arrList = new System.Collections.ArrayList();

//Boxing occures here 

arrList.Add(typeA);

}

What Happens when a boxing occurs:

1- Because value-typed variables are stored in stack, a new memory cell in heap must be allocated to store this object. Reference types use heap (dynamic memory space) to be stored.

2- The value type’s bits are copied from stack to their new location in heap.

3- The new address is returned to be stored in ArrayList. So we now have a reference type instead of a value type.

Therefore, boxing can be very expensive and sometimes harmful.

Unboxing: is, of course, exactly opposite to boxing, it is the time when a reference type is converted to a value type.

After storing value types into ArrayList, they are wanted to be used somewhere. In other words, you should convert them to their original type in order to use them.

typeA = (TypeA)arrList[0];

System.Console.Write(typeA.VarB.ToString());

What happens in unboxing?

1- It Checks whether it is null or not, then it checks whether the specified type is convertible or not. If both of the above conditions fail it returns an exception.

2- The reference of the object inside the ArrayList is returned. Then bits are copied into the value typed variable.

It has some penalties again. To overcome this problem .Net suggests using Generics when time is totally eminent (But it is a better to consider it always).

Generics is out of scope of this article; however, I describe it briefly in a sample code to show its power and its immense difference compared with objects.

Generics classes/methods are similar to type-less ones but they are not. You can specify their types before compile time when you are coding. For example for classes their types must be specified during their instantiation. Therefore, it gives you the flexibility to have different types in each instance of a class.

Code below is a comparison between a Generic class and an Object one.

//T and U are generic types. It means that you can specify their types in class instantiation. So

class GenericClass
{
public T t;
public U u;

 public GenericClass(T t, U u)
{
this.t = t;
this.u = u;
}
}

//An object class that may cause boxing and unboxing during run-time
class ObjectClass
{
public object t;
public object u;

&nbsp;

 public ObjectClass(object t, object u)
{
this.t = t;
this.u = u;
}
}

Now I want to show you the time it takes to work with each one of them for ten million iterations.

protected void Page_Load(object sender, EventArgs e)
{
DateTime dt1 = DateTime.Now;
ObjectClass ObjClass;
for (int i = 0; i &lt; 10000000; i++)
{
ObjClass = new ObjectClass(10, "Peace");
}
DateTime dt2 = DateTime.Now;

TimeSpan tsDef = dt2.Subtract(dt1);
Response.Write("Object: " + tsDef.TotalMilliseconds.ToString() + "
");

 dt1 = DateTime.Now;
GenericClass GenClass;
for (int i = 0; i &lt; 10000000; i++)
{
GenClass = new GenericClass(10, "Peace");
}
dt2 = DateTime.Now;
tsDef = dt2.Subtract(dt1);
Response.Write("Generic: " + tsDef.TotalMilliseconds.ToString());
}
Boxing and Unboxing

Fig 1, the result of comparision

The result clearly shows this difference. (Of course, you get different results each time you run the program but the ratio remains almost the same)

As you see, it is near to two times faster by using the Generic types.

Reference: Jeffrey Richter, MSPress: MCTS Self-Paced Training Kit (Exam 70-536)

JQuery Autocomplete with ASP.Net

March 29, 2011 4 comments

In this article I want to describe combination of Autocomplete of JQuery and ASP.Net web service. Up to now I really couldn’t find a good article about this issue so it can be useful in the web.

Autocomplete is a plugin of JQuery that you can be used to implement autocomplete with the least efforts. You can find it here.

JQuery Autocomplete plugin has a property called source, in Ajax based programming you should change its source regarding what is entered into the textbox. Assume that you enter “ala” after that a callback is generated that sends some parameters to the web service (textbox.text and other parameters that you want) then in the response data you can feed source property of Autocomplete plugin. I think this stage can be your unique part of your job.

AutoComplete

Fig 1

In this article I’ll discuss about generating a new callback on typing each new word and how to assign the returned value with the source property of Autocomplete plugin. You then can change the web service section with your desired code such as connecting to database and retrieving data on what is sent as parameter to the web service.

Web Service:

I start with web service because it is really simple.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.Services;

using System.Xml;

using System.Text;

using System.Web.Script.Services;

namespace ArticleDean.web.Service

{

/// <summary>

/// Summary description for WSDataService

/// </summary>

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[System.ComponentModel.ToolboxItem(false)]

// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.

[ScriptService]

public class WSDataService : System.Web.Services.WebService

{

[WebMethod]

public string GetStates(string typedValue, string test)

{

test = "ALABAMA:ALASKA:AMERICAN SAMOA:ARIZONA:ARKANSAS:CALIFORNIA:COLORADO:CONNECTICUT:DELAWARE:DISTRICT OF COLUMBIA:FEDERATED STATES OF MICRONESIA:FLORIDA:GEORGIA:GUAM:HAWAII:IDAHO:ILLINOIS:INDIANA:IOWA:KANSAS:KENTUCKY:LOUISIANA:MAINE:MARSHALL ISLANDS:MARYLAND:MASSACHUSETTS:MICHIGAN:MINNESOTA:MISSISSIPPI:MISSOURI:MONTANA:NEBRASKA:NEVADA:NEW HAMPSHIRE:NEW JERSEY:NEW MEXICO:NEW YORK:NORTH CAROLINA:NORTH DAKOTA:NORTHERN MARIANA ISLANDS:OHIO:OKLAHOMA:OREGON:PALAU:PENNSYLVANIA:PUERTO RICO:RHODE ISLAND:SOUTH CAROLINA:SOUTH DAKOTA:TENNESSEE:TEXAS:UTAH:VERMONT:VIRGIN ISLANDS:VIRGINIA:WASHINGTON:WEST VIRGINIA:WISCONSIN:WYOMING";

return test;

}

}

}

The first parameter that web service gets is typedValue. This parameter returns the typed value in textbox. The second parameter is a test one; it is just to show how to send more than one parameter in JSON datatype. You can use them to retrieve your desired data from database but here we just return a long text with ‘:’ separator (This is for training purpose).

ASPX file:

Sorry that it is Image, because of the problem of wordpress to accept html and aspx code, I have to publish this section in image

In the front of the source, there is a function that returns the callback result. It has two parameters, the second one is a method called response (this is a key note) that you should pass the resulting data from callback to it.

In data section of Ajax, I wrote a JSON data, JSON is a pair of key, value that is separated by a ‘:’.

$(".QueryText").val()

returns the typed words in text box

In success section, I splited the resulting string with ‘:’ character and assigned it an array (because JavaScript is a dynamic type checker you don’t need to specify the variable as array, it detects it automatically). Then I sent it to the response method as parameter. This is the only way to return data to the source property of Autocomplete. [return] keyword can’t do this (I wasted a lot of my time to return a value from return keyword, so you can save yours).

Among Autocomplete properties I’m going to discuss some of them. First delay, this parameter is to postpone the callback request to the server. It is very important to do this because ignoring it causes a lot of overhead on the server (it would be a self Denial of Service attack :D). The next is minLength, it depicts that your Autocomplete sends the request after typing a specific number of characters. It also reduces the overhead if you increase it to a meaningful number according to your need.

In header of your form I included JQuery file (jquery-1.5.1.min.js), Autocomplete plugin file (jquery-ui-1.8.custom.min.js) this is a customized file; you can generate it at this address. And also a CSS file that is the official released theme for Autocomplete; you can download and edit it.

Should you have any questions comment me.

Love and peace for you all.

Onlinenic API in C# (Part 2)

March 18, 2011 11 comments

In this article we will discuss about some functionalities of Onlinenic API. We should know that for each function we can establish a new connection. (A good practice is placing connect and login method in the constructor of a class).

Onlinenic API with C#

This article will cover domain availability checking, retrieving domain information and creation of domain. I tried to make you familiar to code the rest yourself, should you encountered any question you can email or comment me.

Domain availability checking:

This function is one of the simplest function in this API. You just need to send your domain name and the extension code of your desired domain. For example “google.com” as domain name and “0” for extension which is “.com”.

/// &lt;summary&gt;
/// Checks the availability of domain name

/// </summary>

/// <param name="domainName">Name of domain e.g. yahoo.com</param>

/// <param name="domainExt">Extension number of domain e.g. 800 for biz</param>

/// <returns>true means domain is available and false means domain is not available</returns>

public bool CheckDomain(string domainName, string domainExt)

{

string chksum = "";

string HashedPass = getMd5Hash(Password);

Guid guid = Guid.NewGuid();

chksum = MemberID + HashedPass + guid.ToString() + "checkdomain" + domainExt + domainName;

chksum = getMd5Hash(chksum);

StringBuilder sb = new StringBuilder();

sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");

sb.Append("<request>");

sb.Append("<category>domain</category>");

sb.Append("<action>CheckDomain</action>");

sb.Append("<params>");

//Domain extension should be the code of a domain name. For example 0 for .com

sb.Append("     <param name=\"domaintype\">" + domainExt.ToString() + "</param>");

//Domain name should be the complete form of a domain name. For example microsoft.com

sb.Append("     <param name=\"domain\">" + domainName + "</param>");

sb.Append("</params>");

sb.Append("<cltrid>" + guid.ToString() + "</cltrid>");

sb.Append("<chksum>" + chksum + "</chksum>");

sb.Append("</request>");
String responseData = String.Empty;

// Buffer to store the response bytes.

Byte[] data;

data = System.Text.Encoding.ASCII.GetBytes(sb.ToString());

// Send the message to the connected TcpServer.

stream.Write(data, 0, data.Length);

//Reads data and returns it to the application

Int32 bytes = stream.Read(data, 0, data.Length);

responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

if (!responseData.Contains("Command completed successfully"))

{

return false;

}

return responseData.Contains("&lt;data name=\"avail\"&gt;1&lt;/data&gt;");

}

Retrieving domain information:

This section is really important because finding the real meaning of this command wasted a lot of my time just to debug and search about this job. Onlinenic API does not retrieve information of all domains; it only does it for domains which are registered under your account. So don’t waste your time to get this functionality.

/// <summary>;

/// Returns the information about a registered domain under your account

/// </summary>

/// <param name="domainName">Name of domain e.g. yahoo.com</param>

/// <param name="domainExt">Extension number of domain e.g. 800 for biz</param>

/// <returns>An xml-based string response</returns>

public string getDomainInfo(string domainName, string domainExt)

{

string chksum = "";

string HashedPass = getMd5Hash(Password);

Guid guid = Guid.NewGuid();

chksum = MemberID + HashedPass + guid.ToString() + "infodomain" +

domainExt + domainName;

chksum = getMd5Hash(chksum);

StringBuilder sb = new StringBuilder();

sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");

sb.Append("<request>");

sb.Append("<category>domain</category>");

sb.Append("<action>InfoDomain</action>");

sb.Append("<params>");

sb.Append("     <param name=\"domaintype\">" + domainExt + "</param>");

sb.Append("     <param name=\"domain\">" + domainName + "</param>");

sb.Append("</params>");

sb.Append("<cltrid>" + guid.ToString() + "</cltrid>");

sb.Append("<chksum>" + chksum + "</chksum>");

sb.Append("</request>");
String responseData = String.Empty;

Byte[] data;

data = System.Text.Encoding.ASCII.GetBytes(sb.ToString());

// Send the message to the connected TcpServer.

stream.Write(data, 0, data.Length);

//Reads data and returns it to the application

Int32 bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

byte[] byteArray = Encoding.ASCII.GetBytes(responseData);

MemoryStream memStream = new MemoryStream(byteArray);

if (!responseData.Contains("Command completed successfully"))

{

return "";

}

else

{

responseData = ParseXMLstream(memStream);

}

return responseData;

}

Domain Creation:

This topic also was one of the most challenging sections of my job because comments in the published documents are totally unclear.

Creation of domain contact:

In order to create/register a domain you should create/register an entity called contact. This entity contains information about persons in charged with this domain, their contact information and some other. It is important to know that creation of contact for each domain extension has a common part and a specific part which differs from one domain extension to another. You should know that for .EU and .Asia domain extensions you should specify country codes related to these regions [you can refer to the document for detailed information].

I tried to build it clearly and use comments to help you learn it easier.

/// <summary>

/// Creates contact which is required for domain registration

/// </summary>

/// <param name="domainExt">Extension number of domain e.g. 800 for biz</param>

/// <param name="name">Name of contact person</param>

/// <param name="organization">Organization of contact person</param>

/// <param name="country">Country of contact person. It is a string with length of 2 e.g. IR for Iran. You should consider domain extension for correct country, for example IR cannot be used as the country of a .EU domain extension</param>

/// <param name="province">Province of contact person</param>

/// <param name="city">City of contact person</param>

/// <param name="street">Address of contact person</param>

/// <param name="postCode">Post code of contact person</param>

/// <param name="phoneNo">Pnone no of contact person</param>

/// <param name="faxNo">Fax number of contact person</param>

/// <param name="email">Email address of contact person</param>

/// <param name="password">Password of contact object</param>

/// <returns>A string of created contact</returns>

public string CreateContact(string domainExt, string name, string organization, string country, string province, string city, string street, string postCode,

string phoneNo, string faxNo, string email, string password)

{

string chksum = "";

string HashedPass = getMd5Hash(Password);

Guid guid = Guid.NewGuid();

chksum = MemberID + HashedPass + guid.ToString() + "crtcontact" + name + organization + email;

chksum = getMd5Hash(chksum);

StringBuilder sb = new StringBuilder();

sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");

sb.Append("<request>");

sb.Append("<category>domain</category>");

sb.Append("<action>CreateContact</action>");

sb.Append("<params>");

sb.Append("<param name=\"domaintype\">" + domainExt + "</param>");

sb.Append("<param name=\"name\">" + name + "</param>");

sb.Append("<param name=\"org\">" + organization + "</param>");

sb.Append("<param name=\"country\">" + country + "</param>");

sb.Append("<param name=\"province\">" + province + "</param>");

sb.Append("<param name=\"city\">" + city + "</param>");

sb.Append("<param name=\"street\">" + stream + "</param>");

sb.Append("<param name=\"postalcode\">" + postCode + "</param>");

sb.Append("<param name=\"voice\">" + phoneNo + "</param>");

sb.Append("<param name=\"fax\">" + faxNo + "</param>");

sb.Append("<param name=\"email\">" + email + "</param>");

sb.Append("<param name=\"password\">" + password + "</param>");

switch (domainExt)

{

case "902": // .EU

sb.Append("<param name=\"euflag\">" + "1" + "</param>");

sb.Append("<param name=\"regtype\">" + "In" + "</param>");

break;

case "220": // .CN

sb.Append("<param name=\"manager\">" + "Your Name" + "</param>");

sb.Append("<param name=\"industry\">" + "S2" + "</param>");

break;

case "905": // .ASIA

sb.Append("<param name=\"ccLocality\">" + "IR" + "</param>");

sb.Append("<param name=\"localitySp\">" + "Tehran" + "</param>");

sb.Append("<param name=\"localityCity\">" + "Tehran" + "</param>");

sb.Append("<param name=\"legalEntityType\">" + "corporation" + "</param>");

sb.Append("<param name=\"identForm\">" + "other" + "</param>");

sb.Append("<param name=\"identNumber\">" + "122211122" + "</param>");

sb.Append("<param name=\"otherIdentForm\">" + "other" + "</param>");

break;

case "806": // .US

sb.Append("<param name=\"AppPurpose\">" + "P1" + "</param>");

sb.Append("<param name=\"NexusCategory\">" + "C12" + "</param>");

break;

}

sb.Append("</params>");

sb.Append("<cltrid>" + guid.ToString() + "</cltrid>");

sb.Append("<chksum>" + chksum + "</chksum>");

sb.Append("</request>");

String responseData = String.Empty;

// Buffer to store the response bytes.

Byte[] data;

data = System.Text.Encoding.ASCII.GetBytes(sb.ToString());

// Send the message to the connected TcpServer.

stream.Write(data, 0, data.Length);

//Reads data and returns it to the application

Int32 bytes = stream.Read(data, 0, data.Length);

responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

byte[] byteArray = Encoding.ASCII.GetBytes(responseData);

MemoryStream memStream = new MemoryStream(byteArray);

if (responseData.Contains("Command completed successfully"))

{

responseData = ParseXMLstream(memStream, "data");

}

return responseData;

}

Registration of a domain:

After creation of one or more contact objects it is feasible to register a domain. You should create at least one contact object for each domain registration. Also you should specify name servers of each domain. You should mention that for registration of different domain extensions, different checksum order should be specified.

/// <summary>

/// Registered an availabe domain under your account. You should build at least one contact before registration of a domain

/// </summary>

/// <param name="domainName">Name of domain e.g. yahoo.com</param>

/// <param name="domainExt">Extension number of domain e.g. 800 for biz</param>

/// <param name="period">The amount of domain registration. e.g. 2 for 2 years</param>

/// <param name="NS1">Name server number 1</param>

/// <param name="NS2">Name server number 2</param>

/// <param name="password">Password of domain object</param>

/// <param name="contact">The created contact of </param>

/// <returns>Returns true if domain is successfully registerd</returns>

public bool createDomain(string domainName, string domainExt, string period,

string NS1, string NS2, string password, string contact)

{

string chksum = "";

string HashedPass = getMd5Hash(Password);

Guid guid = Guid.NewGuid();

switch (domainExt)

{

case "902": //.EU

chksum = MemberID + HashedPass + guid.ToString() + "createdomain" + domainExt + domainName + period + NS1 + NS2 + contact + password;

break;

case "905"://.ASIA

chksum = MemberID + HashedPass + guid.ToString() + "createdomain" + domainExt + domainName +

period + NS1 + NS2 + contact + contact + contact + contact + contact + password;

break;

default:

chksum = MemberID + HashedPass + guid.ToString() + "createdomain" + domainExt + domainName + period + NS1 + NS2 + contact + contact + contact + contact + password;

break;

}

chksum = getMd5Hash(chksum);

StringBuilder sb = new StringBuilder();

sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");

sb.Append("<request>");

sb.Append("<category>domain</category>");

sb.Append("<action>CreateDomain</action>");

sb.Append("<params>");

sb.Append("     <param name=\"domaintype\">" + domainExt + "</param>");

sb.Append("     <param name=\"domain\">" + domainName + "</param>");

sb.Append("     <param name=\"mltype\">" + "0" + "</param>");

sb.Append("     <param name=\"period\">" + period + "</param>");

sb.Append("     <param name=\"dns\">" + NS1 + "</param>");

sb.Append("     <param name=\"dns\">" + NS2 + "</param>");

sb.Append("     <param name=\"registrant\">" + contact + "</param>");

sb.Append("     <param name=\"tech\">" + contact + "</param>");

sb.Append("     <param name=\"billing\">" + contact + "</param>");

sb.Append("     <param name=\"admin\">" + contact + "</param>");

sb.Append("     <param name=\"password\">" + password + "</param>");

sb.Append("</params>");

sb.Append("<cltrid>" + guid.ToString() + "</cltrid>");

sb.Append("<chksum>" + chksum + "</chksum>");

sb.Append("</request>");
String responseData = String.Empty;

// Buffer to store the response bytes.

Byte[] data;

data = System.Text.Encoding.ASCII.GetBytes(sb.ToString());

//Send the message to the connected TcpServer.

stream.Write(data, 0, data.Length);

//Reads data and returns it to the application

Int32 bytes = stream.Read(data, 0, data.Length);

responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bool flag = responseData.Contains("Command completed successfully");

if (!flag)

{

return false;

}

return flag;

}

I wish you found it useful.

Onlinenic API in C# (Part 1)

March 15, 2011 11 comments

Onlinenic API with C#

Some weeks ago I had to build a complete library to work with Onlinenic’s API. After spending about a week on this awful API I managed to develop one.

A technical independent pdf document was released by Onlinenic but it is not clear; however I attached this file to this post. The first is from Onlinenic, the other is from an unknown source.

Because unfortunately I couldn’t find any technical document on the web in any platforms, I decided to write a post about this issue in c#. I hope you find it useful. This article contains: establishing connection, login to API and log out from API. You can read the rest in another postOnlinenic API in C# (Part 2).

Connecting to API:

Firstly, you should know that it only accepts TCP connection. So you should build a TCP connection to connect to this API.

You should send your command in an XML format, AIP also sends its response in this format too.

In order to connect to the API you can use this method:

bool Connect()

{

client = new TcpClient();

// Server name is <a href="http://www.onlinenic.com/">www.onlinenic.com</a> and port no is 30009

client.Connect(ServerName, PortNo);

stream = client.GetStream();

// String to store the response ASCII representation.

String responseData = String.Empty;

// Buffer to store the response bytes.

Byte[] data = new Byte[256];

// Read the first batch of the TcpServer response bytes.

Int32 bytes = stream.Read(data, 0, data.Length);

responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bool flag = responseData.Contains("Your Connection with API Server is Successful");

if (!flag)

throw new NotConnectedException();

return flag;

}

You can catch response in two ways:

1- Response code: <code>1000</code>, an example for successful attempt

2- Response message :<msg>Server response</msg>

I used msg tag to make my program more readable.

I also wrote some exception classes to response to errors properly. As you can see “NotConnectedException” class is created to throw an exception in the case of connection failure.

Login:

In order to login to API you should specify your credential information. In code below you can make an XML command and pass it to the server.

There is a hashed value called checksum which exists in all of commands either you send to API or receive from it. This is for security purposes to prevent anyone from intersecting the connection and changing the value of the fields. Each command such as login or Domain registration has its own checksum format. Here as you cans see below it is the concatenation of username, hashed password, a new GUID and a string contains “login”. You then should hash it.

To hash your password you can click on this.

bool Login()

{

string chksum = "";

string HashedPass = getMd5Hash(Password);

Guid guid = Guid.NewGuid();

// MemberID is your username and for you password you should hash you password

chksum = MemberID + HashedPass + guid.ToString() + "login";

chksum = getMd5Hash(chksum);

StringBuilder sb = new StringBuilder();

sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");

sb.Append("<request>");

sb.Append("<category>client</category>");

sb.Append("<action>Login</action>");

sb.Append("<params>");

sb.Append("<param name=\"clid\">" + MemberID + "</param>");

sb.Append("</params>");

sb.Append("<cltrid>" + guid.ToString() + "</cltrid>");

sb.Append("<chksum>" + chksum + "</chksum>");

sb.Append("</request>");

String responseData = String.Empty;

// Buffer to store the response bytes.

Byte[] data;

data = System.Text.Encoding.ASCII.GetBytes(sb.ToString());

// Send the message to the connected TcpServer.

stream.Write(data, 0, data.Length);

//Reads data and returns it to the application

Int32 bytes = stream.Read(data, 0, data.Length);

responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bool flag = responseData.Contains("Command completed successfully");

if (!flag)

throw new NotLoginException();

return flag;

}

Log out:

bool Logout()

{

string chksum = "";

string HashedPass = getMd5Hash(Password);

Guid guid = Guid.NewGuid();

chksum = MemberID + HashedPass + guid.ToString() + "logout";

chksum = getMd5Hash(chksum);

StringBuilder sb = new StringBuilder();

sb.Append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
sb.Append("<request>");
sb.Append("<category>client</category>");
sb.Append("<action>Logout</action>");
sb.Append("<params>");
sb.Append("<param name=\"clid\">" + MemberID + "</param>");
sb.Append("</params>");
sb.Append("<cltrid>" + guid.ToString() + "</cltrid>");
sb.Append("<chksum>" + chksum + "</chksum>");
sb.Append("</request>");
String responseData = String.Empty;

// Buffer to store the response bytes.

Byte[] data;

data = System.Text.Encoding.ASCII.GetBytes(sb.ToString());

// Send the message to the connected TcpServer.

stream.Write(data, 0, data.Length);

//Reads data and returns it to the application

Int32 bytes = stream.Read(data, 0, data.Length);

responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bytes = stream.Read(data, 0, data.Length);

responseData += System.Text.Encoding.ASCII.GetString(data, 0, bytes);

bool flag = responseData.Contains("Command completed successfully");

return flag;

}