/// <summary> /// Send an HTTP GET request to the specified URI and intepret the result as TResult. /// </summary> /// <typeparam name="TResult">The .NET class to use for response deserialization.</typeparam> /// <param name="uri">A uniform resource identifier that is the target of this GET request.</param> /// <param name="dataFormat">One of the data-interchange formats that Socrata supports. The default is JSON.</param> /// <returns>The HTTP response, deserialized into an object of type <typeparamref name="TResult"/>.</returns> internal TResult read <TResult>(Uri uri, SodaDataFormat dataFormat = SodaDataFormat.JSON) where TResult : class { var request = new SodaRequest(uri, "GET", AppToken, Username, password, dataFormat, null, RequestTimeout); return(request.ParseResponse <TResult>()); }
/// <summary> /// Initialize a new SodaRequest. /// </summary> /// <param name="uri">The Uri to send the request to.</param> /// <param name="method">The HTTP method to use for the request.</param> /// <param name="appToken">The Socrata App Token to send with the request.</param> /// <param name="username">The Socrata user account to use for the request.</param> /// <param name="password">The password for the specified Socrata <paramref name="username"/>.</param> /// <param name="dataFormat">One of the data-interchange formats that Socrata supports. The default is JSON.</param> /// <param name="payload">The body of the request.</param> /// <param name="timeout">The number of milliseconds to wait for a response before throwing a Timeout WebException.</param> internal SodaRequest(Uri uri, string method, string appToken, string username, string password, SodaDataFormat dataFormat = SodaDataFormat.JSON, string payload = null, int?timeout = null) : this() { this.dataFormat = dataFormat; this.Client = new HttpClient(); this.Client.Timeout = timeout.HasValue ? new TimeSpan(0, 0, 0, 0, timeout.Value) : Client.Timeout; this.RequestMessage = new HttpRequestMessage { RequestUri = uri, Method = new HttpMethod(method) }; if (!String.IsNullOrEmpty(appToken)) { //http://dev.socrata.com/docs/app-tokens.html this.Client.DefaultRequestHeaders.Add("X-App-Token", appToken); } if (!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password)) { //Authentication using HTTP Basic Authentication //http://dev.socrata.com/docs/authentication.html string authKVP = String.Format("{0}:{1}", username, password); byte[] authBytes = Encoding.UTF8.GetBytes(authKVP); this.Client.DefaultRequestHeaders.Add("Authorization", String.Format("Basic {0}", Convert.ToBase64String(authBytes))); } //http://dev.socrata.com/docs/formats/index.html switch (dataFormat) { case SodaDataFormat.JSON: Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); break; case SodaDataFormat.CSV: this.Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/csv")); this.Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); break; case SodaDataFormat.XML: this.Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/rdf+xml")); break; } if (!String.IsNullOrEmpty(payload)) { switch (dataFormat) { case SodaDataFormat.JSON: this.RequestMessage.Content = new StringContent(payload, Encoding.UTF8, "application/json"); break; case SodaDataFormat.CSV: this.RequestMessage.Content = new StringContent(payload, Encoding.UTF8, "text/csv"); break; case SodaDataFormat.XML: this.RequestMessage.Content = new StringContent(payload, Encoding.UTF8, "application/rdf+xml"); break; } } }
/// <summary> /// Replace any existing rows with the payload data, using the specified resource identifier. /// </summary> /// <param name="payload">A string of serialized data.</param> /// <param name="dataFormat">One of the data-interchange formats that Socrata supports, into which the payload has been serialized.</param> /// <param name="resourceId">The identifier (4x4) for a resource on the Socrata host to target.</param> /// <returns>A <see cref="SodaResult"/> indicating success or failure.</returns> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the specified <paramref name="dataFormat"/> is equal to <see cref="SodaDataFormat.XML"/>.</exception> /// <exception cref="System.ArgumentOutOfRangeException">Thrown if the specified <paramref name="resourceId"/> does not match the Socrata 4x4 pattern.</exception> /// <exception cref="System.InvalidOperationException">Thrown if this SodaClient was initialized without authentication credentials.</exception> public SodaResult Replace(string payload, SodaDataFormat dataFormat, string resourceId) { if (dataFormat == SodaDataFormat.XML) { throw new ArgumentOutOfRangeException("dataFormat", "XML is not a valid format for write operations."); } if (FourByFour.IsNotValid(resourceId)) { throw new ArgumentOutOfRangeException("resourceId", "The provided resourceId is not a valid Socrata (4x4) resource identifier."); } if (String.IsNullOrEmpty(Username) || String.IsNullOrEmpty(password)) { throw new InvalidOperationException("Write operations require an authenticated client."); } var uri = SodaUri.ForResourceAPI(Host, resourceId); var request = new SodaRequest(uri, "PUT", AppToken, Username, password, dataFormat, payload); SodaResult result = null; try { if (dataFormat == SodaDataFormat.JSON) { result = request.ParseResponse <SodaResult>(); } else if (dataFormat == SodaDataFormat.CSV) { string resultJson = request.ParseResponse <string>(); result = Newtonsoft.Json.JsonConvert.DeserializeObject <SodaResult>(resultJson); } } catch (WebException webException) { string message = webException.UnwrapExceptionMessage(); result = new SodaResult() { Message = webException.Message, IsError = true, ErrorCode = message, Data = payload }; } catch (Exception ex) { result = new SodaResult() { Message = ex.Message, IsError = true, ErrorCode = ex.Message, Data = payload }; } return(result); }
/// <summary> /// Creates the source for the specified revision. /// </summary> /// <param name="data">A string of serialized data.</param> /// <param name="revision">The revision created as part of a create revision step.</param> /// <param name="dataFormat">The format of the data.</param> /// <param name="filename">The filename that should be associated with this upload.</param> /// <returns>A <see cref="Source"/> indicating success or failure.</returns> /// <exception cref="System.InvalidOperationException">Thrown if this SodaDSMAPIClient was initialized without authentication credentials.</exception> public Source CreateSource(string data, Revision revision, SodaDataFormat dataFormat = SodaDataFormat.CSV, string filename = "NewUpload") { if (String.IsNullOrEmpty(data)) { throw new ArgumentException("Data must be provided.", "data"); } if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password)) { throw new InvalidOperationException("Write operations require an authenticated client."); } if (revision == null) { throw new ArgumentException("Revision required.", "revision"); } var sourceUri = SodaUri.ForSource(Host, revision.GetSourceEndpoint()); Debug.WriteLine(sourceUri.ToString()); revision.GetRevisionNumber(); // Construct Revision Request body Newtonsoft.Json.Linq.JObject payload = new Newtonsoft.Json.Linq.JObject(); Newtonsoft.Json.Linq.JObject source_type = new Newtonsoft.Json.Linq.JObject(); Newtonsoft.Json.Linq.JObject parse_option = new Newtonsoft.Json.Linq.JObject(); source_type["type"] = "upload"; source_type["filename"] = filename; parse_option["parse_source"] = true; payload["source_type"] = source_type; payload["parse_options"] = parse_option; var createSourceRequest = new SodaRequest(sourceUri, "POST", null, username, password, SodaDataFormat.JSON, payload.ToString()); Result sourceOutput = createSourceRequest.ParseResponse <Result>(); string uploadDataPath = sourceOutput.Links["bytes"]; var uploadUri = SodaUri.ForUpload(Host, uploadDataPath); Debug.WriteLine(uploadUri.ToString()); var fileUploadRequest = new SodaRequest(uploadUri, "POST", null, username, password, dataFormat, data); fileUploadRequest.SetDataType(SodaDataFormat.JSON); Result result = fileUploadRequest.ParseResponse <Result>(); return(new Source(result)); }
/// <summary> /// Initialize a new SodaRequest. /// </summary> /// <param name="uri">The Uri to send the request to.</param> /// <param name="method">The HTTP method to use for the request.</param> /// <param name="appToken">The Socrata App Token to send with the request.</param> /// <param name="username">The Socrata user account to use for the request.</param> /// <param name="password">The password for the specified Socrata <paramref name="username"/>.</param> /// <param name="dataFormat">One of the data-interchange formats that Socrata supports. The default is JSON.</param> /// <param name="payload">The body of the request.</param> /// <param name="timeout">The number of milliseconds to wait for a response before throwing a Timeout WebException.</param> internal SodaRequest(Uri uri, string method, string appToken, string username, string password, SodaDataFormat dataFormat = SodaDataFormat.JSON, string payload = null, int?timeout = null) { this.dataFormat = dataFormat; var request = WebRequest.Create(uri) as HttpWebRequest; request.Method = method.ToUpper(); request.ProtocolVersion = new System.Version("1.1"); request.PreAuthenticate = true; request.Timeout = timeout.HasValue ? timeout.Value : request.Timeout; if (!String.IsNullOrEmpty(appToken)) { //http://dev.socrata.com/docs/app-tokens.html request.Headers.Add("X-App-Token", appToken); } if (!String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password)) { //Authentication using HTTP Basic Authentication //http://dev.socrata.com/docs/authentication.html string authKVP = String.Format("{0}:{1}", username, password); byte[] authBytes = Encoding.UTF8.GetBytes(authKVP); request.Headers.Add("Authorization", String.Format("Basic {0}", Convert.ToBase64String(authBytes))); } //http://dev.socrata.com/docs/formats/index.html switch (dataFormat) { case SodaDataFormat.JSON: request.Accept = "application/json"; if (!request.Method.Equals("GET")) { request.ContentType = "application/json"; } break; case SodaDataFormat.CSV: switch (request.Method) { case "GET": request.Accept = "text/csv"; break; case "POST": case "PUT": request.ContentType = "text/csv"; break; } break; case SodaDataFormat.XML: request.Accept = "application/rdf+xml"; break; } if (!String.IsNullOrEmpty(payload)) { byte[] bodyBytes = Encoding.UTF8.GetBytes(payload); using (var stream = request.GetRequestStream()) { stream.Write(bodyBytes, 0, bodyBytes.Length); } } this.webRequest = request; }
internal void SetDataType(SodaDataFormat format) { dataFormat = format; }