cdun2
cdun2

Reputation: 1

Getting Data from a Website using MVC 4 Web API

This is a follow-up to this post: New at MVC 4 Web API Confused about HTTPRequestMessage

Here is a summary of what I am trying to do: There is a web site that I want to interface with via MVC 4 Web API. At the site, users can log in with a user name and password, then go to a link called ‘Raw Data’ to query data from the site.

On the ‘Raw Data’ page, there is a dropdown list for ‘Device’, a text box for ‘From’ date, and a text box for ‘To’ date. Given these three parameters, the user can click the ‘Get Data’ button, and return a table of data to the page. What I have to do, is host a service on Azure that will programmatically provide values for these three parameters to the site, and return a CSV file from the site to Azure storage.

The company that hosts the site has provided documentation to programmatically interface with the site to retrieve this raw data. The document describes how requests are to be made against their cloud service. Requests must be authenticated using a custom HTTP authentication scheme. Here is how the authentication scheme works:

  1. Calculate an MD5 hash from the user password.
  2. Append the request line to the end of the value from step one.
  3. Append the date header to the end of the value in step two.
  4. Append the message body (if any) to the end of the value in step 3.
  5. Calculate MD5 hash over the resulting value from step 4.
  6. Append the value from step 5 to the user email using the “:” character as a delimiter.
  7. Calculate Base64 over the value from step 6.

The code that I am going to list was done in Visual Studio 2012, C#, .NET Framework 4.5. All of the code in this post is in my 'FileDownloadController.cs' Controller class. The ‘getMd5Hash’ function takes a string, and returns an MD5 hash:

//Create MD5 Hash:  Hash an input string and return the hash as a 32 character hexadecimal string. 
    static string getMd5Hash(string input)
    {
        // Create a new instance of the MD5CryptoServiceProvider object.
        MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();

        // Convert the input string to a byte array and compute the hash. 
        byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));

        // Create a new Stringbuilder to collect the bytes 
        // and create a string.
        StringBuilder sBuilder = new StringBuilder();

        // Loop through each byte of the hashed data  
        // and format each one as a hexadecimal string. 
        for (int i = 0; i < data.Length; i++)
        {
            sBuilder.Append(data[i].ToString("x2"));
        }

        // Return the hexadecimal string. 
        return sBuilder.ToString();
    }

This function takes a string, and returns BASE64:

        //Convert to Base64
    static string EncodeTo64(string input)
    {
        byte[] str1Byte = System.Text.Encoding.ASCII.GetBytes(input);
        String plaintext = Convert.ToBase64String(str1Byte);

        return plaintext;
    }

The next function creates an HTTPClient, makes an HTTPRequestMessage, and returns the authorization. Note: The following is the URI that was returned from Fiddler when data was returned from the ‘Raw Data’ page: GET /rawdata/exportRawDataFromAPI/?devid=3188&fromDate=01-24-2013&toDate=01-25-2013 HTTP/1.1

Let me first walk through what is happening with this function:

  1. The ‘WebSiteAuthorization’ function takes a ‘deviceID’, a ‘fromDate’, a ‘toDate’ and a ‘password’.
  2. Next, I have three variables declared. I’m not clear on whether or not I need a ‘message body’, but I have a generic version of this set up. The other two variables hold the beginning and end of the URI.
  3. I have a variable named ‘dateHeader’, which holds the data header.
  4. Next, I attempt to create an HTTPClient, assign the URI with parameters to it, and then assign ‘application/json’ as the media type. I’m still not very clear on how this should be structured.
  5. In the next step, the authorization is created, per the requirements of the API documentation, and then the result is returned.

    public static string WebSiteAuthorization(Int32 deviceid, string fromDate, string toDate, string email, string password)
    {
        var messagebody = "messagebody"; // TODO: ??????????? Message body
        var uriAddress = "GET/rawdata/exportRawDataFromAPI/?devid=";
        var uriAddressSuffix = "HTTP/1.1";
    
        //create a date header
        DateTime dateHeader = DateTime.Today;
        dateHeader.ToUniversalTime();
    
        //create the HttpClient, and its BaseAddress
        HttpClient ServiceHttpClient = new HttpClient();
        ServiceHttpClient.BaseAddress = new Uri(uriAddress + deviceid.ToString() + " fromDate" + fromDate.ToString() + " toDate" + toDate.ToString() + uriAddressSuffix);
        ServiceHttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
        //create the authorization string
        string authorizationString = getMd5Hash(password);
        authorizationString = authorizationString + ServiceHttpClient + dateHeader + messagebody;
        authorizationString = email + getMd5Hash(authorizationString);
        authorizationString = EncodeTo64(authorizationString);
    
        return authorizationString;
    
    }
    

I haven’t tested this on Azure yet. I haven't completed the code that gets the file. One thing I know I need to do is to determine the correct way to create an HttpRequestMessage and use HttpClient to send it. In the documentation that I've read, and the examples that I've looked at, the following code fragments appear to be possible approaches to this:

Var serverAddress = http://my.website.com/;
//Create the http client, and give it the ‘serverAddress’:
Using(var httpClient = new HttpClient()
{BaseAddress = new Uri(serverAddress)))
Var requestMessage = new HttpRequestMessage();
Var objectcontent = requestMessage.CreateContent(base64Message, MediaTypeHeaderValue.Parse          (“application/json”)

or----

var formatters = new MediaTypeFormatter[] { new jsonMediaTypeFormatter() }; 
HttpRequestMessage<string> request = new HttpRequestMessage<string>
("something", HttpMethod.Post, new Uri("http://my.website.com/"), formatters); 

request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); 

var httpClient = new HttpClient(); 
var response = httpClient.SendAsync(request);

or------

Client = new HttpClient();
var request = new HttpRequestMessage
                 {
                     RequestUri = "http://my.website.com/",
                     Method = HttpMethod.Post,
                     Content = new StringContent("ur message")
                 };

I'm not sure which approach to take with this part of the code.

Thank you for your help.

Upvotes: 0

Views: 3711

Answers (1)

LeoQns
LeoQns

Reputation: 1322

Read this step by step tutorial to understand the basic.

Upvotes: 1

Related Questions