// -----------------------------------------------------------------------
//
// Copyright (C) 2012 Microsoft Corporation
//
// -----------------------------------------------------------------------
namespace Microsoft.Samples.Management.OData.AssociationClient
{
using System.Collections.Generic;
using System.IO;
using System.Net;
///
/// Represents an HTTP request to the ODATA server.
///
internal class OdataJsonRequest
{
///
/// the HTTP request
///
private HttpWebRequest request;
///
/// URL options that should be added to the request
///
private Dictionary options;
///
/// Headers option value
///
private Dictionary headers;
///
/// HTTP verb of the request
///
private string verb;
///
/// URL of the request
///
private string url;
///
/// credentials for the request
///
private ICredentials credentials;
///
/// the server response
///
private HttpWebResponse response;
///
/// Initializes a new instance of the OdataJsonRequest class.
///
/// HTTP verb
/// the url
/// credentials, typically a CredentialCache
public OdataJsonRequest(string verb, string url, ICredentials credentials)
{
this.options = new Dictionary();
this.headers = new Dictionary();
this.url = url;
this.verb = verb;
this.credentials = credentials;
}
///
/// Gets or sets the body of the request.
///
public string RequestBody { get; set; }
///
/// Gets the body of the server response. Valid only after SendReceive();
///
public string ResponseBody { get; private set; }
///
/// Gets the status code of the server response. Valid only after SendReceive();
///
public HttpStatusCode ResponseStatus { get; private set; }
///
/// Gets the decoded response body
///
public dynamic Response { get; private set; }
///
/// Checks whether a reference set contains a given element.
/// The set and the element are expected to be sub-elements of a ResponseBody
/// of a previous request.
///
/// the reference-set (in a response body)
/// the reference (in a response body)
/// true if the set contains the element
public static bool JsonReferenceSetContains(dynamic set, dynamic element)
{
return JsonReferenceSetContains(set, element.__metadata.uri);
}
///
/// Encodes a single name-value pair in JSON format.
///
/// the key
/// the value
/// the encoded pair
public static string EncodeJsonElement(string key, string value)
{
return "\"" + key + "\": \"" + value + "\"";
}
///
/// Encodes a single name-value pair in JSON format.
///
/// the key
/// the value
/// the encoded pair
public static string EncodeJsonElement(string key, int value)
{
return "\"" + key + "\": " + value.ToString();
}
///
/// Starts JSON encoding of a struct property, writing the field name and open-brace in JSON format.
///
/// the field name
/// the encoded string
public static string BeginJsonStruct(string name)
{
return "\"" + name + "\": {";
}
///
/// Finishes JSON encoding of a struct property, writing close-brace.
///
/// the encoded string
public static string EndJsonStruct()
{
return "}";
}
///
/// Adds a URL option to the request.
///
/// option name
/// option value
public void AddOption(string name, string value)
{
this.options.Add(name, value);
}
///
/// Adds a header value
///
/// option name
/// option value
public void AddHeader(string name, string value)
{
this.headers.Add(name, value);
}
///
/// Sends the request and waits for the response.
///
public void SendReceive()
{
// add URL options
if (this.options.Count > 0)
{
string fullOptions = string.Empty;
foreach (KeyValuePair pair in this.options)
{
if (fullOptions.Length == 0)
{
fullOptions += "?" + pair.Key + "=" + pair.Value;
}
else
{
fullOptions += "&" + pair.Key + "=" + pair.Value;
}
}
this.url += fullOptions;
}
// create the request
this.request = (HttpWebRequest)WebRequest.Create(this.url);
foreach (KeyValuePair header in this.headers)
{
this.request.Headers.Add(header.Key, header.Value);
}
this.request.Credentials = this.credentials;
this.request.Method = this.verb;
this.request.Accept = "application/json;odata=verbose";
// send the request data
if (false == string.IsNullOrEmpty(this.RequestBody))
{
System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
byte[] requestData = encoding.GetBytes(this.RequestBody);
this.request.ContentLength = requestData.Length;
this.request.ContentType = "application/json;odata=verbose";
Stream requestStream = this.request.GetRequestStream();
requestStream.Write(requestData, 0, requestData.Length);
requestStream.Close();
}
// wait for the response and parse it
try
{
this.response = (HttpWebResponse)this.request.GetResponse();
}
catch (WebException ex)
{
this.response = (HttpWebResponse)ex.Response;
}
this.ResponseStatus = this.response.StatusCode;
StreamReader stream = new StreamReader(this.response.GetResponseStream());
this.ResponseBody = stream.ReadToEnd();
if (this.ResponseStatus == HttpStatusCode.OK ||
this.ResponseStatus == HttpStatusCode.Created)
{
System.Management.Automation.ErrorRecord error;
dynamic ret = Microsoft.PowerShell.Commands.JsonObject.ConvertFromJson(this.ResponseBody, out error);
this.Response = ret;
}
}
}
}