/// <summary> /// Adds an INCORRECT_HTTP_RESPONSE_STATUS_CODE_RETURNED error key with appropriate /// messaging to the result's error list /// </summary> /// <typeparam name="TContent"></typeparam> /// <param name="result"></param> /// <param name="expectedStatusCode"></param> /// <param name="actualStatusCode"></param> /// <param name="actionName">Such as "creating a draft"</param> /// <param name="requestBody">If body provided in request, pass that here</param> public static void AddUnexpectedStatusCodeError <TContent>( this RestResponseResult <TContent> result, HttpStatusCode expectedStatusCode, IRestResponse restResponse, string actionName, object requestBody = null ) { var endOfError = ""; if (requestBody != null) { endOfError += $" using request body of {JsonConvert.SerializeObject(requestBody)}"; } if (!string.IsNullOrWhiteSpace(restResponse.ErrorMessage)) { endOfError += $" with IRestResponse.ErrorMessage of '{restResponse.ErrorMessage}'"; } if (!string.IsNullOrWhiteSpace(restResponse.Content)) { endOfError += $" with IRestResponse.Content of '{restResponse.Content}'"; } result.Errors.Add(new Error { Key = RequestErrorKeys.INCORRECT_HTTP_RESPONSE_STATUS_CODE_RETURNED, Message = $"The HTTP status code of '{expectedStatusCode}' was expected. Instead, the HTTP status code of '{restResponse.StatusCode}' was returned when {actionName} for type '{typeof(TContent).FullName}'{endOfError}" }); }
/// <summary> /// Creates the new model and uploads the media asset using the appropriate service endpoint /// </summary> /// <param name="model"></param> /// <param name="filePath"></param> /// <returns></returns> public virtual RestResponseResult <TModel> Upload(TModel model, string filePath) { var fileData = File.ReadAllBytes(filePath); var fileInfo = new FileInfo(filePath); var mimeType = MimeMapping.GetMimeMapping(filePath); var jObject = JObject.FromObject(model); jObject.Add("DirectUpload", true); var url = Settings.BaseUrl + EndpointUrl; var client = new RestClient(url); var request = new RestRequest(Method.POST); request.AddHeader("authorization", "Bearer " + Session.AccessToken); request.AddHeader("X-File-Name", fileInfo.Name); request.AddHeader("X-Sf-Properties", jObject.ToString(Formatting.None)); request.AddParameter(mimeType, fileData, ParameterType.RequestBody); IRestResponse response = ExecuteAuthorizedRequest(client, request); var result = new RestResponseResult <TModel>(HttpStatusCode.Created, response); if (!result.WasExpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.Created, response, $"uploading {typeof(TModel).FullName}", model); return(result); } result.ResultObject = JsonConvert.DeserializeObject <TModel>(response.Content); return(result); }
public void WasUnexpectedStatusCode_Given_RestResponse_StatusCode_Does_Not_Match_ExpectedStatusCode_Returns_True() { // Arrange var restResponse = new RestResponse() { StatusCode = HttpStatusCode.OK }; var restResponseResult = new RestResponseResult <bool>( HttpStatusCode.InternalServerError, restResponse ); // Act & Assert restResponseResult.WasUnexpectedStatusCode.ShouldBeTrue(); }
public void WasUnexpectedStatusCode_Given_RestResponse_StatusCode_Matches_ExpectedStatusCode_Returns_False() { // Arrange var statusCode = HttpStatusCode.OK; var restResponse = new RestResponse() { StatusCode = statusCode }; var restResponseResult = new RestResponseResult <bool>( statusCode, restResponse ); // Act & Assert restResponseResult.WasUnexpectedStatusCode.ShouldBeFalse(); }
public static string GetUnexpectedStatusCodeErrorMessage <T>(this RestResponseResult <T> restResponseResult) { var baseErrorMessage = $"Expected status code is '{restResponseResult.ExpectedStatusCode}' but actual status was code was '{restResponseResult.RestResponse.StatusCode}'."; var errorMessage = $"{baseErrorMessage}'. REST response's content is: '{restResponseResult.RestResponse.Content}'"; if (restResponseResult.RestResponse.IsWaitAMomentResponse()) { /* * Sitefinity sometimes returns the "Please wait a moment" response instead of the expected status code indicating something is happening * like Sitefinity is rebooting, upgrading, etc. Instead of outputting the entire HTML content including the CSS and HTML markup, * return a simple message so it's easier to understand when failures occur */ errorMessage = $"{baseErrorMessage}'. Sitefinity is returning the '{RestResponseContentData.PLEASE_WAIT_A_MOMENT}' message in it's content response"; } return(errorMessage); }
/// <summary> /// Gets related items based on the relationship name. /// NOTE: Use this for multi-instance relationships /// </summary> /// <param name="id">The Id of the content.</param> /// <param name="string">The name of the relationship.</param> /// <returns>The response of the request wrapped in a RestResponseResult where ResultObject is the returned related object list</returns> public RestResponseResult <List <TRelatedContent> > GetRelatedRecords <TRelatedContent>(Guid id, string relationshipName) where TRelatedContent : SitefinityContentDto { var requestUrl = $"{Settings.BaseUrl}{EndpointUrl}({id})/{relationshipName}"; var restResponse = ExecuteSitefinityRequest(Method.GET, requestUrl, null); var result = new RestResponseResult <List <TRelatedContent> >(HttpStatusCode.OK, restResponse); if (result.WasUnexpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.OK, restResponse, $"getting many related data items"); return(result); } result.ResultObject = JsonConvert.DeserializeObject <ODataServiceGetResponse <TRelatedContent> >(restResponse.Content).Value; return(result); }
/// <summary> /// Creates a draft content item /// </summary> /// <param name="model"></param> /// <returns>The response of the request wrapped in a RestResponseResult where ResultObject is the returned object with its updated values</returns> public RestResponseResult <TContent> CreateDraft(TContent model) { var body = JsonConvert.SerializeObject(model); var requestUrl = Settings.BaseUrl + EndpointUrl; var restResponse = ExecuteSitefinityRequest(Method.POST, requestUrl, body); var result = new RestResponseResult <TContent>(HttpStatusCode.Created, restResponse); if (result.WasUnexpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.Created, restResponse, "creating a draft", model); return(result); } result.ResultObject = JsonConvert.DeserializeObject <TContent>(restResponse.Content); return(result); }
/// <summary> /// Gets an existing item. /// </summary> /// <param name="id">The Id of the content.</param> /// <returns>The response of the request wrapped in a RestResponseResult where ResultObject is the returned object</returns> public RestResponseResult <TContent> GetItem(Guid id) { var requestUrl = $"{Settings.BaseUrl}{EndpointUrl}({id})"; var restResponse = ExecuteSitefinityRequest(Method.GET, requestUrl, null); var result = new RestResponseResult <TContent>(HttpStatusCode.OK, restResponse); if (result.WasUnexpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.OK, restResponse, "getting item"); return(result); } result.ResultObject = JsonConvert.DeserializeObject <TContent>(restResponse.Content); return(result); }
/// <summary> /// Removes the related item based on the relationship name. /// </summary> /// <param name="id">The Id of the main content.</param> /// <param name="relatedId">The Id of the related content.</param> /// <param name="string">The name of the relationship.</param> /// <returns>The response of the request wrapped in a RestResponseResult where ResultObject is whether the related object was successfully deleted</returns> public RestResponseResult <bool> DeleteRelated(Guid id, Guid relatedId, string relationshipName) { var requestUrl = $"{Settings.BaseUrl}{EndpointUrl}({id})/{relationshipName}({relatedId})/$ref"; var restResponse = ExecuteSitefinityRequest(Method.DELETE, requestUrl, null); var result = new RestResponseResult <bool>(HttpStatusCode.NoContent, restResponse); if (result.WasUnexpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.NoContent, restResponse, "deleting related data"); result.ResultObject = false; return(result); } result.ResultObject = true; return(result); }
/// <summary> /// Publish an existing content item. /// </summary> /// <param name="id">The Id of the content</param> /// <returns>The response of the request wrapped in a RestResponseResult where ResultObject is whether the object was successfully published</returns> public RestResponseResult <bool> Publish(Guid id) { var requestUrl = $"{Settings.BaseUrl}{EndpointUrl}({id})/operation"; var body = "{\"action\": \"Publish\",\"actionParameters\": {}}"; var restResponse = ExecuteSitefinityRequest(Method.POST, requestUrl, body); var result = new RestResponseResult <bool>(HttpStatusCode.OK, restResponse); if (result.WasUnexpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.OK, restResponse, "publishing"); result.ResultObject = false; return(result); } result.ResultObject = true; return(result); }
/// <summary> /// Modify existing item. /// </summary> /// <param name="model">The content model.</param> /// <returns>The response of the request wrapped in a RestResponseResult where ResultObject is the returned object with it's updated values</returns> public RestResponseResult <TContent> Modify(TContent model) { var requestUrl = $"{Settings.BaseUrl}{EndpointUrl}({model.Id})"; var body = JsonConvert.SerializeObject(model, new JsonSerializerSettings { ContractResolver = new ShouldSerializeContractResolver() }); var restResponse = ExecuteSitefinityRequest(Method.PATCH, requestUrl, body); var result = new RestResponseResult <TContent>(HttpStatusCode.NoContent, restResponse); if (result.WasUnexpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.NoContent, restResponse, "modifying data"); return(result); } result.ResultObject = JsonConvert.DeserializeObject <TContent>(restResponse.Content); return(result); }
/// <summary> /// Gets existing items based on the given parameters /// </summary> /// <param name="skip">The number of items to skip before returning the results.</param> /// <param name="take">The number of items to pull in the result.</param> /// <returns>The response of the request wrapped in a RestResponseResult where ResultObject is the returned object list</returns> public RestResponseResult <List <TContent> > Get(int?skip = null, int?take = null) { skip = skip ?? 0; take = take ?? SITEFINITY_MAX_RESULTS_ROW_COUNT; var requestUrl = $"{Settings.BaseUrl}{EndpointUrl}?$skip={skip}&$take={take}"; var restResponse = ExecuteSitefinityRequest(Method.GET, requestUrl, null); var result = new RestResponseResult <List <TContent> >(HttpStatusCode.OK, restResponse); if (result.WasUnexpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.OK, restResponse, $"getting data items"); return(result); } result.ResultObject = JsonConvert.DeserializeObject <ODataServiceGetResponse <TContent> >(restResponse.Content).Value; return(result); }
/// <summary> /// Gets the number of the existing, published Sitefinity items for data type specified by this service /// </summary> /// <returns>The response of the request wrapped in a RestResponseResult where ResultObject is the total number of published records</returns> public RestResponseResult <int> GetCount() { var requestUrl = $"{Settings.BaseUrl}{EndpointUrl}/$count"; var restResponse = ExecuteSitefinityRequest(Method.GET, requestUrl, null); var result = new RestResponseResult <int>(HttpStatusCode.OK, restResponse); if (result.WasUnexpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.OK, restResponse, "getting the total count of published"); return(result); } var content = restResponse.Content.Trim(new char[] { '\uFEFF' }); // Removing the leading Byte Order Mark (BOM) from content. result.ResultObject = Convert.ToInt32(content); return(result); }
/// <summary> /// Create a relationship record between the main content and the related content /// </summary> /// <param name="id">The Id of the main content.</param> /// <param name="relatedId">The Id of the related content.</param> /// <param name="string">The name of the relationship.</param> /// <param name="string">The endpoint URL of the related item.</param> /// <returns>The response of the request wrapped in a RestResponseResult where ResultObject is whether the object was successfully created</returns> public RestResponseResult <bool> CreateRelated(Guid id, Guid relatedId, string relationshipName, string relationshipEndpointUrl) { var requestObject = new JObject();; var postODataId = $"{Settings.BaseUrl}{relationshipEndpointUrl}({relatedId})"; requestObject.Add("@odata.id", new JValue(postODataId)); var body = JsonConvert.SerializeObject(requestObject); var requestUrl = $"{Settings.BaseUrl}{EndpointUrl}({id})/{relationshipName}/$ref"; var restResponse = ExecuteSitefinityRequest(Method.POST, requestUrl, body); var result = new RestResponseResult <bool>(HttpStatusCode.NoContent, restResponse); if (result.WasUnexpectedStatusCode) { result.AddUnexpectedStatusCodeError(HttpStatusCode.NoContent, restResponse, "creating a relationship"); result.ResultObject = false; return(result); } result.ResultObject = true; return(result); }
public static void ShouldBeExpectedStatusCode <T>(this RestResponseResult <T> restResponseResult) { restResponseResult.WasExpectedStatusCode.ShouldBeTrue( GetUnexpectedStatusCodeErrorMessage(restResponseResult)); }