Created
March 25, 2011 12:53
-
-
Save PaulCampbell/886799 to your computer and use it in GitHub Desktop.
Generic repository style service for REST services
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IJsonService<T> | |
{ | |
// Methods | |
void Delete(T entity); | |
IList<T> FindAll(IDictionary<string, object> propertyValuePairs, int pageNo, int resultsPerPage, string sortBy, string sortDirection); | |
T Get(int id); | |
IList<T> Get(List<int> IDs); | |
IList<T> GetAll(int pageNo, int resultsPerPage, string sortBy, string sortDirection, string segment); | |
RestResult Save(T entity); | |
RestResult Update(T entity); | |
IList<T> GetRelatedObjectsForEntity(string entityType, int entityId); | |
} | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IRestResource | |
{ | |
int ID { get; set; } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class JsonService<T> : IJsonService<T> where T : IRestResource | |
{ | |
private readonly string _serviceEndPoint = System.Configuration.ConfigurationManager.AppSettings["RestURL"]; | |
public void Delete(T entity) | |
{ | |
throw new NotImplementedException(); | |
} | |
/// <summary> | |
/// Searches resources for instances that "start with" values in property keys | |
/// </summary> | |
/// <param name="propertyValuePairs">Dictionary of search keys / values - matches when "key" column starts with "value"</param> | |
/// <param name="pageNo">page number </param> | |
/// <param name="resultsPerPage">how many results per page</param> | |
/// <param name="sortBy">column to sort by</param> | |
/// <param name="sortDirection">direction (ASC || DESC)</param> | |
/// <returns></returns> | |
public IList<T> FindAll(IDictionary<string, object> propertyValuePairs, int pageNo, int resultsPerPage, | |
string sortBy, string sortDirection) | |
{ | |
// Do we need to match on beginswith || equals || ends with??? | |
var matchtype = "beginswith"; | |
var searchString = "filter="; | |
foreach (var p in propertyValuePairs) | |
{ | |
searchString = String.Format("{0}{1}.{2}.{3}", searchString, p.Key,matchtype, p.Value); | |
} | |
var uri = String.Format("{0}/{5}/?offset={1}&limit={2}&sorttype={3}&sortby={4}&{6}", | |
_serviceEndPoint, pageNo, resultsPerPage, sortDirection, sortBy, typeof (T).Name, | |
searchString); | |
string resp = GetJson(uri, HttpMethod.GET.ToString()); | |
var o = JObject.Parse(resp); | |
var returnResources = o.SelectToken(typeof(T).Name + "s"); | |
var models = GetModels(returnResources); | |
return models; | |
} | |
/// <summary> | |
/// Return the full resource | |
/// </summary> | |
/// <param name="id">Id of the resource</param> | |
/// <returns></returns> | |
public T Get(int id) | |
{ | |
// Grab the json feed from the service... | |
var uri = String.Format("{0}/{1}/{2}", _serviceEndPoint, typeof (T).Name, id); | |
var o = JObject.Parse(GetJson(uri, HttpMethod.GET.ToString())); | |
var returnResource = o.SelectToken(typeof(T).Name + "s"); | |
// deserialise it for the view | |
var models = GetModels(returnResource); | |
return models[0]; | |
} | |
public IList<T> Get(List<int> IDs) | |
{ | |
var listOfIds = ""; | |
foreach(var i in IDs) | |
{ | |
listOfIds += i.ToString() + ","; | |
} | |
var uri = String.Format("{0}/{1}/{2}", _serviceEndPoint, typeof(T).Name, listOfIds); | |
var o = JObject.Parse(GetJson(uri, HttpMethod.GET.ToString())); | |
var returnResources = o.SelectToken(typeof(T).Name + "s"); | |
var models = GetModels(returnResources); | |
return models; | |
} | |
/// <summary> | |
/// Get a list of resources | |
/// </summary> | |
/// <param name="pageNo">page number </param> | |
/// <param name="resultsPerPage">how many results per page</param> | |
/// <param name="sortBy">column to sort by</param> | |
/// <param name="sortDirection">direction (ASC || DESC)</param> | |
/// /// <param name="segment">name of segmented data (e.g. userwhohavenotloggedin)</param> | |
/// <returns></returns> | |
public IList<T> GetAll(int pageNo, int resultsPerPage, string sortBy, string sortDirection, string segment) | |
{ | |
var uri = String.Format("{0}/{5}/?offset={1}&limit={2}&sorttype={3}&sortby={4}&segment={6}", _serviceEndPoint, pageNo, | |
resultsPerPage, sortDirection, sortBy, typeof(T).Name, segment); | |
var o = JObject.Parse(GetJson(uri, HttpMethod.GET.ToString())); | |
var returnResources = o.SelectToken(typeof (T).Name + "s"); | |
var models = GetModels(returnResources); | |
return models; | |
} | |
/// <summary> | |
/// Save a new resource | |
/// </summary> | |
/// <param name="entity">the new resource</param> | |
/// <returns>rest call result object</returns> | |
public RestResult Save(T entity) | |
{ | |
var restResult = PushJson(String.Format("{0}/{1}/", _serviceEndPoint, typeof (T).Name), | |
HttpMethod.POST.ToString(), entity); | |
return restResult; | |
} | |
/// <summary> | |
/// Update a resource | |
/// </summary> | |
/// <param name="entity">the resource to persist</param> | |
/// <returns>rest call result object</returns> | |
public RestResult Update(T entity) | |
{ | |
var restResult = PushJson(String.Format("{0}/{1}/{2}", _serviceEndPoint, typeof (T).Name, entity.ID), | |
HttpMethod.PUT.ToString(), entity); | |
return restResult; | |
} | |
/// <summary> | |
/// Method for retrieving an objects related resources. | |
/// for example: UserAccount/1/UserGroups | |
/// </summary> | |
/// <param name="entityType">The name of the base entity - UserAccounts in the above example</param> | |
/// <param name="entityId">The ID of the base entity</param> | |
/// <returns>A list of objects related to the base entity</returns> | |
public IList<T> GetRelatedObjectsForEntity(string entityType, int entityId) | |
{ | |
var uri = String.Format("{0}/{1}/{2}/{3}s", _serviceEndPoint, entityType, entityId.ToString(), typeof(T).Name); | |
var o = JObject.Parse(GetJson(uri, HttpMethod.GET.ToString())); | |
var returnResources = o.SelectToken(typeof(T).Name + "s"); | |
var models = GetModels(returnResources); | |
return models; | |
} | |
/// <summary> | |
/// POST or PUT an object to the REST service | |
/// </summary> | |
/// <param name="uri">The URI of the resource</param> | |
/// <param name="httpMethod"></param> | |
/// <param name="entity"></param> | |
/// <returns></returns> | |
private RestResult PushJson(string uri, string httpMethod, T entity) | |
{ | |
string json = Newtonsoft.Json.JsonConvert.SerializeObject(entity); | |
byte[] arr = System.Text.Encoding.UTF8.GetBytes(json); | |
var webRequest = GetWebRequest(String.Format("{0}/{1}/{2}", _serviceEndPoint, typeof (T).Name, entity.ID)); | |
webRequest.Method = httpMethod; | |
webRequest.ContentType = "application/json"; | |
webRequest.ContentLength = arr.Length; | |
Stream dataStream = webRequest.GetRequestStream(); | |
dataStream.Write(arr, 0, arr.Length); | |
dataStream.Close(); | |
try | |
{ | |
HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); | |
// Service responses: | |
string returnString = response.StatusCode.ToString(); | |
var jsonResult = new StreamReader(response.GetResponseStream()).ReadToEnd(); | |
var o = JArray.Parse(jsonResult); | |
var restResult = | |
Newtonsoft.Json.JsonConvert.DeserializeObject<RestResult>( | |
o[0].ToString()); | |
foreach (JProperty j in o[0].SelectToken("Fields")) | |
{ | |
var f = new Field(); | |
f.FieldName = j.Name; | |
f.Message = j.Value["Message"].ToString(); | |
f.Status = j.Value["Status"].ToString(); | |
restResult.Forms.Add(f); | |
} | |
return restResult; | |
} | |
catch (Exception e) | |
{ | |
// Network down... What do we want to do? | |
throw; | |
} | |
} | |
private string GetJson(string uri, string httpMethod) | |
{ | |
var webRequest = GetWebRequest(uri); | |
webRequest.Method = httpMethod; | |
webRequest.ContentType = "application/json"; | |
try | |
{ | |
var response = (HttpWebResponse)webRequest.GetResponse(); | |
var jsonResponse = string.Empty; | |
using (var sr = new StreamReader(response.GetResponseStream())) | |
{ | |
jsonResponse = sr.ReadToEnd(); | |
} | |
return jsonResponse; | |
} | |
catch (Exception e) | |
{ | |
// Network down... What do we want to do? | |
throw; | |
} | |
} | |
private static HttpWebRequest GetWebRequest(string formattedUri) | |
{ | |
var serviceUri = new Uri(formattedUri, UriKind.Absolute); | |
return (HttpWebRequest) System.Net.WebRequest.Create(serviceUri); | |
} | |
private List<T> GetModels(JToken returnResources) | |
{ | |
List<T> models; | |
if (returnResources == null || returnResources.Type == JTokenType.Null) | |
{ | |
// There were no results in the list... | |
return new List<T>(); | |
} | |
if (returnResources.Type.ToString() == "Array") | |
{ | |
models = Newtonsoft.Json.JsonConvert.DeserializeObject<List<T>>(returnResources.ToString()); | |
} | |
else | |
{ | |
// if there is only 1 result, the service does not return an array... we must serialise accordingly. | |
models = new List<T>(); | |
models.Add(Newtonsoft.Json.JsonConvert.DeserializeObject<T>(returnResources.ToString())); | |
} | |
return models; | |
} | |
} | |
public enum HttpMethod | |
{ | |
GET = 1, | |
POST = 2, | |
PUT = 3, | |
DELETE = 4 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment