Create Cloud Machine programmatically

When your business requires cloud services for your applications or infrastructure, then you have to find good cloud provider. Amazon EC2, Tata Insta compute are a good example. Most of the cloud provider uses Apache CloudStack.

If we need 2-3 cloud machines then we can use their interface. But based on business if you need more machines then its painful to create them using their interface. Most of the cloud providers provides API in such cases. So client can create machines automatically.

There are few things which they need for all machines:
- All the machines must be remotely accessible.
- Required application must be installed.
- Some port shall be opened for global access.

All these points if we add in API then we can remote machines with in few minutes.

Amazon EC2 provides a AWS console and AWSSDK to achieve this. But if we go Tata Insta Compute or any other provider then I think it will create complex compared to AWS console.

To automate this manual process for Tata I have written a API which will do all things one by one… Just we have to create a single machine first with all required application. Then create a snapshot of this machines. Note down all the id related to OS, Snapshot, ZONE, Network.

Below script (Apache CloudStack) will handle all the creativity which require API keys of Sandbox or Production account.

public enum MachineState { START = 1, STOP = 2, RESTART = 3 };
    public enum JobType { DEPLOYMACHINE = 1, ACQUIREIP = 2 };

    class Program
    {

        const int ZONEID = 1111;
        const int SERVICEOFFERINGID = 2222;
        const int TEMPLATEID = 3333;
        const int NETWORKIDS = 4444;
        static string[] PORTLIST = { "3389-3389" };

        static void Main(string[] args)
        {
            // Fully qualified URL with http(s)://host:port
            String apiHost = "http://xxxxxxxxxxxxxx.com/client/api";

            // ApiKey and secretKey as given by your InstaCompute vendor
            String apiKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
            String secretKey = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";

            for (int icounter = 1; icounter <= 1; icounter++)
            {
                String jobId = DeployVirtualMachine(apiHost, apiKey, secretKey, "Feb-04-" + icounter);
                Console.WriteLine("DeployVirtualMachine Job ID:" + jobId);
                if (!string.IsNullOrEmpty(jobId))
                {
                    string currentJobIDStatus = "0";
                    int machineID = 0;
                    int ipID = 0;
                    while (currentJobIDStatus == "0")
                    {
                        currentJobIDStatus = CheckJob(apiHost, apiKey, secretKey, Convert.ToInt32(jobId), JobType.DEPLOYMACHINE, out machineID);
                        Console.WriteLine("DeployVirtualMachine Job ID Status:" + currentJobIDStatus);
                        System.Threading.Thread.Sleep(5000);
                    }
                    if (currentJobIDStatus == "1")
                    {
                        jobId = AcuirePublicIP(apiHost, apiKey, secretKey);
                        Console.WriteLine("AcuirePublicIP Job ID:" + jobId);

                        if (!string.IsNullOrEmpty(jobId))
                        {
                            currentJobIDStatus = "0";
                            while (currentJobIDStatus == "0")
                            {
                                currentJobIDStatus = CheckJob(apiHost, apiKey, secretKey, Convert.ToInt32(jobId), JobType.ACQUIREIP, out ipID);
                                Console.WriteLine("AcuirePublicIP Job ID Status:" + currentJobIDStatus);
                                System.Threading.Thread.Sleep(5000);
                            }
                            Console.WriteLine("MachineID :" + machineID);
                            Console.WriteLine("IPID :" + ipID);

                            if (machineID > 0 && ipID > 0 && currentJobIDStatus == "1")
                            {
                                Console.WriteLine("MapPublicIPWithMachine.");
                                MapPublicIPWithMachine(apiHost, apiKey, secretKey, ipID, machineID);
                            }
                        }
                    }
                }
            }

       }

        protected static string parseUrl(string url)
        {
            System.Net.WebClient webdata = new System.Net.WebClient();

            //the below statement assigns byte[]
            byte[] bytes = webdata.DownloadData(url);

            //the below code converts byte[] type string type
            return System.Text.Encoding.GetEncoding("utf-8").GetString(bytes);
        }

        protected static string GetEncodedValue(string data)
        {
            return HttpUtility.UrlEncode(data, System.Text.Encoding.UTF8);
        }

        /**
        * 1. Signs a string with a secret key using SHA-1
        * 2. Base64 encode the result
        * 3. URL encode the final result
        *
        * @param request
        * @param key
        * @return
        */
        protected static String signRequest(String data, String key)
        {
            string canonicalString = data;
            // now encode the canonical string
            Encoding ae = new UTF8Encoding();
            // create a hashing object
            HMACSHA1 signature = new HMACSHA1();
            // secretId is the hash key
            signature.Key = ae.GetBytes(key);
            byte[] bytes = ae.GetBytes(canonicalString);
            byte[] moreBytes = signature.ComputeHash(bytes);
            // convert the hash byte array into a base64 encoding
            return Convert.ToBase64String(moreBytes);
        }

        protected static void List(string apiHost, string apiKey, string secretKey, string apiCommand)
        {
            // Step 1: Make sure your APIKey is toLowerCased and URL encoded
            String encodedApiKey = GetEncodedValue(apiKey.ToLower());

            // Step 2: toLowerCase all the parameters, URL encode each parameter value,
            // and the sort the parameters in alphabetical order
            // Please note that if any parameters with a '&' as a value will cause
            // this test client to fail since we are using '&' to delimit
            // the string
            ArrayList sortedParams = new ArrayList();
            sortedParams.Add("apikey=" + encodedApiKey);
            sortedParams.Add("command=" + GetEncodedValue(apiCommand.ToLower()));

            sortedParams.Sort();

            // Step 3: Construct the sorted URL and sign and URL encode
            // the sorted URL with your secret key
            String sortedUrl = null;
            bool first = true;
            foreach (String param in sortedParams)
            {
                if (first)
                {
                    sortedUrl = param;
                    first = false;
                }
                else
                {
                    sortedUrl = sortedUrl + "&" + param;
                }
            }

            String encodedSignature = GetEncodedValue(signRequest(sortedUrl, secretKey));

            // Step 4: Construct the final URL we want to send to the
            // InstaCompute Management Server
            // Final result should look like:
            // http(s)://://client/api?&apiKey=&signature=
            String finalUrl = apiHost + "?command=" + apiCommand + "&apiKey=" + apiKey + "&signature="
              + encodedSignature;

            string response = parseUrl(finalUrl);
        }


        protected static void ListTemplates(string apiHost, string apiKey, string secretKey)
        {
            string apiCommand = "listTemplates";
            // Step 1: Make sure your APIKey is toLowerCased and URL encoded
            String encodedApiKey = GetEncodedValue(apiKey.ToLower());

            // Step 2: toLowerCase all the parameters, URL encode each parameter value,
            // and the sort the parameters in alphabetical order
            // Please note that if any parameters with a '&' as a value will cause
            // this test client to fail since we are using '&' to delimit
            // the string
            ArrayList sortedParams = new ArrayList();
            sortedParams.Add("apikey=" + encodedApiKey);
            sortedParams.Add("command=" + GetEncodedValue(apiCommand.ToLower()));
            sortedParams.Add("templatefilter=" + GetEncodedValue("selfexecutable".ToLower()));

            sortedParams.Sort();

            // Step 3: Construct the sorted URL and sign and URL encode
            // the sorted URL with your secret key
            String sortedUrl = null;
            bool first = true;
            foreach (String param in sortedParams)
            {
                if (first)
                {
                    sortedUrl = param;
                    first = false;
                }
                else
                {
                    sortedUrl = sortedUrl + "&" + param;
                }
            }

            String encodedSignature = GetEncodedValue(signRequest(sortedUrl, secretKey));

            // Step 4: Construct the final URL we want to send to the
            // InstaCompute Management Server
            // Final result should look like:
            // http(s)://://client/api?&apiKey=&signature=
            String finalUrl = apiHost + "?command=" + apiCommand + "&templateFilter=selfexecutable&apiKey=" + apiKey + "&signature="
              + encodedSignature;

            string response = parseUrl(finalUrl);
        }



        protected static void ListVirtualMachines(string apiHost, string apiKey, string secretKey)
        {
            string apiCommand = "listVirtualMachines";
            // Step 1: Make sure your APIKey is toLowerCased and URL encoded
            String encodedApiKey = GetEncodedValue(apiKey.ToLower());

            // Step 2: toLowerCase all the parameters, URL encode each parameter value,
            // and the sort the parameters in alphabetical order
            // Please note that if any parameters with a '&' as a value will cause
            // this test client to fail since we are using '&' to delimit
            // the string
            ArrayList sortedParams = new ArrayList();
            sortedParams.Add("apikey=" + encodedApiKey);
            sortedParams.Add("command=" + GetEncodedValue(apiCommand.ToLower()));

            sortedParams.Sort();

            // Step 3: Construct the sorted URL and sign and URL encode
            // the sorted URL with your secret key
            String sortedUrl = null;
            bool first = true;
            foreach (String param in sortedParams)
            {
                if (first)
                {
                    sortedUrl = param;
                    first = false;
                }
                else
                {
                    sortedUrl = sortedUrl + "&" + param;
                }
            }

            String encodedSignature = GetEncodedValue(signRequest(sortedUrl, secretKey));

            // Step 4: Construct the final URL we want to send to the
            // InstaCompute Management Server
            // Final result should look like:
            // http(s)://://client/api?&apiKey=&signature=
            String finalUrl = apiHost + "?command=" + apiCommand + "&apiKey=" + apiKey + "&signature="
              + encodedSignature;

            string response = parseUrl(finalUrl);

          }

        protected static string AcuirePublicIP(string apiHost, string apiKey, string secretKey)
        {
            string apiCommand = "associateIpAddress";

            // Step 1: Make sure your APIKey is toLowerCased and URL encoded
            String encodedApiKey = GetEncodedValue(apiKey.ToLower());

            // Step 2: toLowerCase all the parameters, URL encode each parameter value,
            // and the sort the parameters in alphabetical order
            // Please note that if any parameters with a '&' as a value will cause
            // this test client to fail since we are using '&' to delimit
            // the string
            ArrayList sortedParams = new ArrayList();
            sortedParams.Add("apikey=" + encodedApiKey);
            sortedParams.Add("command=" + GetEncodedValue(apiCommand.ToLower()));
            sortedParams.Add("zoneid=" + ZONEID);

            sortedParams.Sort();

            // Step 3: Construct the sorted URL and sign and URL encode
            // the sorted URL with your secret key
            String sortedUrl = null;
            bool first = true;
            foreach (String param in sortedParams)
            {
                if (first)
                {
                    sortedUrl = param;
                    first = false;
                }
                else
                {
                    sortedUrl = sortedUrl + "&" + param;
                }
            }

            String encodedSignature = GetEncodedValue(signRequest(sortedUrl, secretKey));

            // Step 4: Construct the final URL we want to send to the
            // InstaCompute Management Server
            // Final result should look like:
            // http(s)://://client/api?&apiKey=&signature=
            String finalUrl = apiHost + "?command=" + apiCommand + "&zoneId=" + ZONEID + "&apiKey=" + apiKey + "&signature=" + encodedSignature; ;

            string response = parseUrl(finalUrl);

            XDocument xdoc = XDocument.Parse(response, LoadOptions.PreserveWhitespace);

            return (from xmlData in xdoc.Descendants("jobid")
                    select xmlData.Value).FirstOrDefault();
        }

        protected static void MapPublicIPWithMachine(string apiHost, string apiKey, string secretKey, int publicIP, int machineID)
        {
            string apiCommand = "createPortForwardingRule";
            int ipaddressid = publicIP;
            
            string protocol = "tcp";
            int virtualmachineid = machineID;
            int networkid = NETWORKIDS;

            foreach (string port in PORTLIST)
            {
                string[] portRange = port.Split('-');
                // Step 1: Make sure your APIKey is toLowerCased and URL encoded
                String encodedApiKey = GetEncodedValue(apiKey.ToLower());

                // Step 2: toLowerCase all the parameters, URL encode each parameter value,
                // and the sort the parameters in alphabetical order
                // Please note that if any parameters with a '&' as a value will cause
                // this test client to fail since we are using '&' to delimit
                // the string
                ArrayList sortedParams = new ArrayList();
                sortedParams.Add("apikey=" + encodedApiKey);
                sortedParams.Add("command=" + GetEncodedValue(apiCommand.ToLower()));
                sortedParams.Add("ipaddressid=" + ipaddressid);
                sortedParams.Add("networkid=" + networkid);
                sortedParams.Add("privateport=" + portRange[0]);
                sortedParams.Add("protocol=" + protocol);
                sortedParams.Add("publicport=" + portRange[0]);
                sortedParams.Add("privateendport=" + portRange[1]);
                sortedParams.Add("publicendport=" + portRange[1]);
                sortedParams.Add("virtualmachineid=" + virtualmachineid);

                sortedParams.Sort();

                // Step 3: Construct the sorted URL and sign and URL encode
                // the sorted URL with your secret key
                String sortedUrl = null;
                bool first = true;
                foreach (String param in sortedParams)
                {
                    if (first)
                    {
                        sortedUrl = param;
                        first = false;
                    }
                    else
                    {
                        sortedUrl = sortedUrl + "&" + param;
                    }
                }

                String encodedSignature = GetEncodedValue(signRequest(sortedUrl, secretKey));

                // Step 4: Construct the final URL we want to send to the
                // InstaCompute Management Server
                // Final result should look like:
                // http(s)://://client/api?&apiKey=&signature=
                String finalUrl = apiHost + "?command=" + apiCommand + "&ipaddressid=" + ipaddressid + "&networkid=" + networkid + "&privateport=" + portRange[0] + "&protocol=" + protocol + "&publicport=" + portRange[0] + "&privateendport=" + portRange[1] + "&publicendport=" + portRange[1] + "&virtualmachineid=" + virtualmachineid + "&apiKey=" + apiKey + "&signature=" + encodedSignature;

                string response = parseUrl(finalUrl);

                XDocument xdoc = XDocument.Parse(response, LoadOptions.PreserveWhitespace);
            }
        }

        protected static string DeployVirtualMachine(string apiHost, string apiKey, string secretKey, string displayName)
        {
            string apiCommand = "deployVirtualMachine";
            displayName = GetEncodedValue(displayName);
            // Step 1: Make sure your APIKey is toLowerCased and URL encoded
            String encodedApiKey = GetEncodedValue(apiKey.ToLower());

            // Step 2: toLowerCase all the parameters, URL encode each parameter value,
            // and the sort the parameters in alphabetical order
            // Please note that if any parameters with a '&' as a value will cause
            // this test client to fail since we are using '&' to delimit
            // the string
            ArrayList sortedParams = new ArrayList();
            sortedParams.Add("apikey=" + encodedApiKey);
            sortedParams.Add("command=" + GetEncodedValue(apiCommand.ToLower()));
            sortedParams.Add("displayname=" + GetEncodedValue(displayName.ToLower()));
            sortedParams.Add("networkids=" + NETWORKIDS);
            sortedParams.Add("serviceofferingid=" + SERVICEOFFERINGID);
            sortedParams.Add("templateid=" + TEMPLATEID);
            sortedParams.Add("zoneid=" + ZONEID);

            sortedParams.Sort();

            // Step 3: Construct the sorted URL and sign and URL encode
            // the sorted URL with your secret key
            String sortedUrl = null;
            bool first = true;
            foreach (String param in sortedParams)
            {
                if (first)
                {
                    sortedUrl = param;
                    first = false;
                }
                else
                {
                    sortedUrl = sortedUrl + "&" + param;
                }
            }

            String encodedSignature = GetEncodedValue(signRequest(sortedUrl, secretKey));

            // Step 4: Construct the final URL we want to send to the
            // InstaCompute Management Server
            // Final result should look like:
            // http(s)://://client/api?&apiKey=&signature=
            String finalUrl = apiHost + "?command=" + apiCommand + "&zoneId=" + ZONEID + "&serviceOfferingId=" + SERVICEOFFERINGID + "&templateId=" + TEMPLATEID + "&networkIds=" + NETWORKIDS + "&displayName=" + displayName + "&apiKey=" + apiKey + "&signature=" + encodedSignature; ;

            string response = parseUrl(finalUrl);

            XDocument xdoc = XDocument.Parse(response, LoadOptions.PreserveWhitespace);

            return (from xmlData in xdoc.Descendants("jobid")
                    select xmlData.Value).FirstOrDefault();
        }

        protected static string ChangeVirtualMachineState(string apiHost, string apiKey, string secretKey, int hostID, MachineState toState)
        {
            string apiCommand = string.Empty;
            switch (toState)
            {
                case MachineState.START:
                    apiCommand = "startVirtualMachine";
                    break;
                case MachineState.STOP:
                    apiCommand = "stopVirtualMachine";
                    break;
                case MachineState.RESTART:
                    apiCommand = "rebootVirtualMachine";
                    break;

            }
            // Step 1: Make sure your APIKey is toLowerCased and URL encoded
            String encodedApiKey = GetEncodedValue(apiKey.ToLower());

            // Step 2: toLowerCase all the parameters, URL encode each parameter value,
            // and the sort the parameters in alphabetical order
            // Please note that if any parameters with a '&' as a value will cause
            // this test client to fail since we are using '&' to delimit
            // the string
            ArrayList sortedParams = new ArrayList();
            sortedParams.Add("apikey=" + encodedApiKey);
            sortedParams.Add("command=" + GetEncodedValue(apiCommand.ToLower()));
            sortedParams.Add("id=" + hostID);

            sortedParams.Sort();

            // Step 3: Construct the sorted URL and sign and URL encode
            // the sorted URL with your secret key
            String sortedUrl = null;
            bool first = true;
            foreach (String param in sortedParams)
            {
                if (first)
                {
                    sortedUrl = param;
                    first = false;
                }
                else
                {
                    sortedUrl = sortedUrl + "&" + param;
                }
            }

            String encodedSignature = GetEncodedValue(signRequest(sortedUrl, secretKey));

            // Step 4: Construct the final URL we want to send to the
            // InstaCompute Management Server
            // Final result should look like:
            // http(s)://://client/api?&apiKey=&signature=
            String finalUrl = apiHost + "?command=" + apiCommand + "&id=" + hostID + "&apiKey=" + apiKey + "&signature="
              + encodedSignature;

            string response = parseUrl(finalUrl);

            XDocument xdoc = XDocument.Parse(response, LoadOptions.PreserveWhitespace);

            return (from xmlData in xdoc.Descendants("jobid")
                    select xmlData.Value).FirstOrDefault();
        }


        protected static string CheckJob(string apiHost, string apiKey, string secretKey, int jobID, JobType jobType, out int ID)
        {
            ID = 0;
            string apiCommand = "queryAsyncJobResult";
            // Step 1: Make sure your APIKey is toLowerCased and URL encoded
            String encodedApiKey = GetEncodedValue(apiKey.ToLower());

            // Step 2: toLowerCase all the parameters, URL encode each parameter value,
            // and the sort the parameters in alphabetical order
            // Please note that if any parameters with a '&' as a value will cause
            // this test client to fail since we are using '&' to delimit
            // the string
            ArrayList sortedParams = new ArrayList();
            sortedParams.Add("apikey=" + encodedApiKey);
            sortedParams.Add("command=" + GetEncodedValue(apiCommand.ToLower()));
            sortedParams.Add("jobid=" + jobID);

            sortedParams.Sort();

            // Step 3: Construct the sorted URL and sign and URL encode
            // the sorted URL with your secret key
            String sortedUrl = null;
            bool first = true;
            foreach (String param in sortedParams)
            {
                if (first)
                {
                    sortedUrl = param;
                    first = false;
                }
                else
                {
                    sortedUrl = sortedUrl + "&" + param;
                }
            }

            String encodedSignature = GetEncodedValue(signRequest(sortedUrl, secretKey));

            // Step 4: Construct the final URL we want to send to the
            // InstaCompute Management Server
            // Final result should look like:
            // http(s)://://client/api?&apiKey=&signature=
            String finalUrl = apiHost + "?command=" + apiCommand + "&jobId=" + jobID + "&apiKey=" + apiKey + "&signature="
              + encodedSignature;

            string response = parseUrl(finalUrl);

            XDocument xdoc = XDocument.Parse(response, LoadOptions.PreserveWhitespace);

            var jobStatus = (from xmlData in xdoc.Descendants("jobstatus")
                             select xmlData.Value).FirstOrDefault();

            if (jobStatus == "0")
            {
                return jobStatus;
            }
            if (jobStatus == "1")
            {
                string query = string.Empty;
                switch (jobType)
                {
                    case JobType.DEPLOYMACHINE:
                        var newMachine = (from xmlData in xdoc.Descendants("virtualmachine")
                                          select new CloudVirtualMachine
                                          {
                                              Account = xmlData.Element("account").Value,
                                              ID = Convert.ToInt32(xmlData.Element("id").Value),
                                              Name = xmlData.Element("name").Value,
                                              DisplayName = xmlData.Element("displayname").Value,
                                          }).ToList();
                        foreach (CloudVirtualMachine cvm in newMachine)
                        {
                            ID = cvm.ID;
                        }
                        break;
                    case JobType.ACQUIREIP:
                        var newIP = (from xmlData in xdoc.Descendants("jobresult").Elements("ipaddress")

                                     select new CloudIP
                                     {
                                         Account = xmlData.Element("account").Value,
                                         ID = Convert.ToInt32(xmlData.Element("id").Value),
                                         IPAddress = xmlData.Element("ipaddress").Value,
                                     }).ToList();
                        foreach (CloudIP cip in newIP)
                        {
                            ID = cip.ID;
                        }
                        break;
                }
            }
            return jobStatus;
        }    

       
    }

    public class CloudVirtualMachine
    {
        public String Account { get; set; }
        public int ID { get; set; }
        public String Name { get; set; }
        public String DisplayName { get; set; }
        public int DomainID { get; set; }
        public String Domain { get; set; }
        public DateTime Created { get; set; }
        public string State { get; set; }
        public int Groupid { get; set; }
        public String Group { get; set; }
        public int ZoneID { get; set; }
        public String ZoneName { get; set; }
        public int TemplateID { get; set; }
        public String TemplateName { get; set; }
        public String TemplateDisplayText { get; set; }
        public bool PasswordEnabled { get; set; }
        public int ServiceOfferingID { get; set; }
        public String ServiceOfferingName { get; set; }
        public int CpuNumber { get; set; }
        public int CpuSpeed { get; set; }
        public int Memory { get; set; }
        public int GuestOSID { get; set; }
        public string Hypervisor { get; set; }
    }

    public class CloudIP
    {
        public String Account { get; set; }
        public int ID { get; set; }
        public int DomainID { get; set; }
        public String Domain { get; set; }
        public String IPAddress { get; set; }
        public String VirtualMachineID { get; set; }
        public String VirtualMachineName { get; set; }
        public String VirtualMachineDisplayName { get; set; }
    }

How to export schema of MYSQL Database?

If you need schema of your MYSQL database for backup or any copy database to another server, then you must need schema with or without data.

GUI tools like SQLYog, WebYog or PHPmyAdmin will best example for that. But if you need any command or utility then MYSQLDUMP has most important role.

For using mysqldump you can export schema as well as data with it.


mysqldump -u root -p –no-data [mydatabase] > myschema.sql

How To Split Pdf Documents Using ITextSharp in C#

In Today’s life cycle PDF has a important role because it doesn’t require any special package to be installed to view it on system, mobile devices, IPOD or IPAD.

Sometimes pdf documents have scanned images, large text data. We need to extract some of the pages for sharing with someone else i.e. friends or any team members. ItextSharp can help us to achieve this.

Following is the sample code which can split the pdf pages to individual file.

using (PdfReader reader = new PdfReader(pdfFileName))
{
for (int pagenumber = 1; pagenumber <= reader.NumberOfPages; pagenumber++)
{
    string filename = pagenumber.ToString() + ".pdf";

    Document document = new Document();
    PdfCopy pdfCopy = new PdfCopy(document, new FileStream(@"c:\temp\" + filename, FileMode.Create));

    document.Open();

    pdfCopy.AddPage(copy.GetImportedPage(reader, pagenumber));

    document.Close();
}
}

Deploy ASP.NET MVC Site on IIS6 – Windows Server 2003

I built a new ASP.NET MVC 4 (.NET 4) web application, but client wanted it to be hosted on their older Windows Server 2003 running IIS 6. While hosting I got 403 error because IIS6 comes with .Net framework 2.0.

I have figured out what we need to do inorder to host the mvc site on IIS6. We do need all the appropriate MVC assemblies in the application bin folder, otherwise we will have to install mvc on server. But the server must have .net Framework 4.0.

Steps :

1. Install the .NET 4 Framework.

2. Make sure ASP.NET v4.0.30319 is ‘Allowed’ under Web Service Extensions in IIS – it is ‘Prohibited’ by default.

3. IIS Website Configuration: Right click on your new website and select ‘Properties’:

a. Under the ‘Home Directory’ tab, make sure that ‘Execute permissions’ is set to ‘Scripts only’ .
b. Under the ‘ASP.NET’ tab, make sure that the ASP.NET version is set to ‘4.0.30319’.
c. Click on the ‘Configuration’ button in the ‘Home Directory’ tab and make sure that all the Application extensions are mapped to .NET 4 versions of the dlls.
d. Add a ‘Wildcard application mapping’ – click on ‘Insert’ and enter ‘C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll’ as the ‘Executable’. Leave ‘Verify that file exists’ unchecked.

Basic Authentication in ASP.Net MVC Web API

ASP.NET Web API is a great tool to create lightweight, HTTP services that reach a broad range of clients, including all browsers and mobile platforms.

In most of scenarios we need authentication to restrict services . There are two ways to restrict it

- Forms authentication
- Windows authentication

Forms authentication is a mechanism that works well in interactive web applications, but Windows authentication is not widely used. Now days services are invoked from the browser using jquery or javascripts for mobile platforms because application are widely used on mobile devices.

HTTP authentication is part of the standard protocol and can be easily handled by client and mobile platforms. To implement Basic authentication in ASP.NET Web API by extending AuthorizeAttribute. But its sometimes not working well, Another a custom message handler by deriving from DelegateHandler class.

Below is the code sample which is deriving from DelegateHandler class and working well.

Code Block:

public class BasicAuthMessageHandler : DelegatingHandler
{
private const string BasicAuthResponseHeader = "WWW-Authenticate";
private const string BasicAuthResponseHeaderValue = "Basic";

public IProvidePrincipal PrincipalProvider = new DummyPrincipalProvider();

public BasicAuthMessageHandler(HttpConfiguration httpConfiguration)
{
InnerHandler = new HttpControllerDispatcher(httpConfiguration);
}

protected override System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
AuthenticationHeaderValue authValue = request.Headers.Authorization;
if (authValue != null && !String.IsNullOrWhiteSpace(authValue.Parameter))
{
Credentials parsedCredentials = ParseAuthorizationHeader(authValue.Parameter);
if (parsedCredentials != null)
{
IPrincipal myPrincipal = PrincipalProvider.CreatePrincipal(parsedCredentials.Username, parsedCredentials.Password);
Thread.CurrentPrincipal = myPrincipal;
HttpContext.Current.User = myPrincipal;
}
}
return base.SendAsync(request, cancellationToken)
.ContinueWith(task =>
{
var response = task.Result;
if (response.StatusCode == HttpStatusCode.Unauthorized
&& !response.Headers.Contains(BasicAuthResponseHeader))
{
response.Headers.Add(BasicAuthResponseHeader
, BasicAuthResponseHeaderValue);
}

if (response.StatusCode == HttpStatusCode.Unauthorized)
{
var content = new StringContent("Invalid Credentials");
response.Content = content;
response.StatusCode = System.Net.HttpStatusCode.Unauthorized;
}
return response;
});
}

private Credentials ParseAuthorizationHeader(string authHeader)
{
string[] credentials = Encoding.ASCII.GetString(Convert
.FromBase64String(authHeader))
.Split(
new[] { ':' });
if (credentials.Length != 2 || string.IsNullOrEmpty(credentials[0])
|| string.IsNullOrEmpty(credentials[1])) return null;
return new Credentials()
{
Username = credentials[0],
Password = credentials[1],
};
}
}
public interface IProvidePrincipal
{
IPrincipal CreatePrincipal(string username, string password);
}
public class Credentials
{
public string Username { get; set; }
public string Password { get; set; }
}
public class DummyPrincipalProvider : IProvidePrincipal
{
public IPrincipal CreatePrincipal(string username, string password)
{
//check user using any membership provider Websecurity/Membership
if (!WebSecurity.Login(username, password, persistCookie: false))
{
return null;
}
var identity = new GenericIdentity(username);
IPrincipal principal = new GenericPrincipal(identity, Roles.GetRolesForUser(username));
return principal;
}
}

WebApiConfig:

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: null,
handler: new BasicAuthMessageHandler(GlobalConfiguration.Configuration)

Controller:

[Authorize]
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "first", "second" };
}
}

Client:

using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri("http://example.com");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Authorization", Convert.ToBase64String(Encoding.ASCII.GetBytes(String.Format("{0}:{1}", userName, password))));
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var Response =await client.GetAsync("api/accounts/validateuser");
}

 

 

How to print PDF in ASP.NET MVC

Creating PDF docs in Asp.Net MVC is a fairly common functionality. Usually either for reporting or, more often, for having printable friendly documents.

I have tried the itextSharp with XMlWorkker but latest version is not free. We have to purchase it for commercial use.

After some research I have found the excellent wkhtmltopdf tool to convert html content to PDF. It uses the WebKit engine (used by browsers like Chrome and Safari) to render HTML. Its also fast.

With Rotativa, (It is using wkhtmltopdf) we can print the all things in pdf:

Steps to use Rotativa:

Install using the Nuget package manager or, more conveniently, with the package manager console, typing:

Install-Package Rotativa

Writing a controller action to return a view representing the desired PDF output.  Replace it with ActionAsPDF. Such as:

public ActionResult Test()        {
return new ActionAsPdf("Index", new { name = "Giorgio" }) { FileName = "Test.pdf" };
}

More formats:

public ActionResult Test()
{
return new ActionAsPdf("Index", new { name = "Giorgio" }) { FileName = "Test.pdf" };
}

public ActionResult TestExternalUrl()
{
return new UrlAsPdf("http://www.google.com")
{
FileName = "TestExternalUrl.pdf",
PageMargins = new Margins(0, 0, 0, 0)
};
}

public ActionResult TestView()
{
ViewBag.Message = string.Format("Hello {0} to ASP.NET MVC!", "Giorgio III.");
return new ViewAsPdf("Index")
{
FileName = "TestView.pdf",
PageSize = Size.A4,
PageOrientation = Orientation.Landscape,
PageMargins = { Left = 0, Right = 0 }
};
}

public ActionResult TestSaveOnServer(string fileName)
{
var filePath = Path.Combine(Server.MapPath("/App_Data"), fileName);
ViewBag.Message = string.Format("Hello {0} to ASP.NET MVC!", "Giorgio III.");
return new ViewAsPdf("Index")
{
FileName = fileName,
PageSize = Size.A3,
PageOrientation = Orientation.Landscape,
PageMargins = { Left = 0, Right = 0 },
SaveOnServerPath = filePath
};
}

public ActionResult TestViewWithModel(string id)
{
var model = new TestViewModel { DocTitle = id, DocContent = "This is a test" };
return new ViewAsPdf(model);
}

public ActionResult TestPartialViewWithModel(string id)
{
var model = new TestViewModel { DocTitle = id, DocContent = "This is a test with a partial view" };
return new PartialViewAsPdf(model);
}

Entity Framework – How to supply a connection string to constructor

If you are using Entity Framework in your projects or websites. You are about to add clients which will have other databases with other connection strings. Database schema is same for all.

For this you are to pass client connection string in EF constructor, this will override the base connection string and use the connection string database.

Basic connection string will not works with EF so you have to use same format of connection string which was created while creating the EDMX file i.e with meta info.

There are two ways to use connection string in constructor:

1. EntityConnectionStringBuilder : Create a connection string format real time with all details.

2. Connection String from config file.

using (MyEntity myent= new MyEntity("name=client2_connectionstring"))
{
}

using (MyEntity myent= new MyEntity("name=client2_connectionstring"))
{
}