Skip to content

Fix/#118 #120

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,14 @@ deploy:
server: https://www.myget.org/F/research-institute/api/v2/package
api_key:
secure: 6CeYcZ4Ze+57gxfeuHzqP6ldbUkPtF6pfpVM1Gw/K2jExFrAz763gNAQ++tiacq3
skip_symbols: true
skip_symbols: false
on:
branch: develop
- provider: NuGet
server: https://www.myget.org/F/jadnc/api/v2/package
api_key:
secure: 6CeYcZ4Ze+57gxfeuHzqP6ldbUkPtF6pfpVM1Gw/K2jExFrAz763gNAQ++tiacq3
skip_symbols: true
skip_symbols: false
on:
branch: unstable
- provider: NuGet
Expand Down
9 changes: 9 additions & 0 deletions src/JsonApiDotNetCore/Formatters/JsonApiReader.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using JsonApiDotNetCore.Internal;
using JsonApiDotNetCore.Serialization;
using JsonApiDotNetCore.Services;
using Microsoft.AspNetCore.Mvc.Formatters;
Expand Down Expand Up @@ -50,6 +52,13 @@ public Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
context.HttpContext.Response.StatusCode = 422;
return InputFormatterResult.FailureAsync();
}
catch(JsonApiException jex)
{
_logger?.LogError(new EventId(), jex, "An error occurred while de-serializing the payload");
context.HttpContext.Response.StatusCode = jex.GetStatusCode();
context.HttpContext.Response.Body = new MemoryStream(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(jex.GetError())));
return InputFormatterResult.FailureAsync();
}
}

private string GetRequestBody(Stream body)
Expand Down
7 changes: 2 additions & 5 deletions src/JsonApiDotNetCore/Internal/TypeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,9 @@ public static object ConvertType(object value, Type type)

return Convert.ChangeType(stringValue, type);
}
catch (Exception)
catch (Exception e)
{
if (type.GetTypeInfo().IsValueType)
return Activator.CreateInstance(type);

return null;
throw new FormatException($"{ value } cannot be converted to { type.GetTypeInfo().Name }", e);
}
}
}
Expand Down
79 changes: 50 additions & 29 deletions src/JsonApiDotNetCore/Serialization/JsonApiDeSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class JsonApiDeSerializer : IJsonApiDeSerializer
private readonly IJsonApiContext _jsonApiContext;
private readonly IGenericProcessorFactory _genericProcessorFactor;

public JsonApiDeSerializer(
public JsonApiDeSerializer(
IJsonApiContext jsonApiContext,
IGenericProcessorFactory genericProcessorFactory)
{
Expand All @@ -26,9 +26,16 @@ public JsonApiDeSerializer(

public object Deserialize(string requestBody)
{
var document = JsonConvert.DeserializeObject<Document>(requestBody);
var entity = DocumentToObject(document.Data);
return entity;
try
{
var document = JsonConvert.DeserializeObject<Document>(requestBody);
var entity = DocumentToObject(document.Data);
return entity;
}
catch (Exception e)
{
throw new JsonApiException("400", "Failed to deserialize request body", e.Message);
}
}

public object Deserialize<TEntity>(string requestBody)
Expand All @@ -38,26 +45,40 @@ public object Deserialize<TEntity>(string requestBody)

public object DeserializeRelationship(string requestBody)
{
var data = JToken.Parse(requestBody)["data"];
try
{
var data = JToken.Parse(requestBody)["data"];

if(data is JArray)
return data.ToObject<List<DocumentData>>();
if (data is JArray)
return data.ToObject<List<DocumentData>>();

return new List<DocumentData> { data.ToObject<DocumentData>() };
return new List<DocumentData> { data.ToObject<DocumentData>() };
}
catch (Exception e)
{
throw new JsonApiException("400", "Failed to deserialize request body", e.Message);
}
}

public List<TEntity> DeserializeList<TEntity>(string requestBody)
{
var documents = JsonConvert.DeserializeObject<Documents>(requestBody);
try
{
var documents = JsonConvert.DeserializeObject<Documents>(requestBody);

var deserializedList = new List<TEntity>();
foreach (var data in documents.Data)
{
var entity = DocumentToObject(data);
deserializedList.Add((TEntity)entity);
}

var deserializedList = new List<TEntity>();
foreach (var data in documents.Data)
return deserializedList;
}
catch (Exception e)
{
var entity = DocumentToObject(data);
deserializedList.Add((TEntity)entity);
throw new JsonApiException("400", "Failed to deserialize request body", e.Message);
}

return deserializedList;
}

private object DocumentToObject(DocumentData data)
Expand All @@ -66,7 +87,7 @@ private object DocumentToObject(DocumentData data)
_jsonApiContext.RequestEntity = contextEntity;

var entity = Activator.CreateInstance(contextEntity.EntityType);

entity = SetEntityAttributes(entity, contextEntity, data.Attributes);
entity = SetRelationships(entity, contextEntity, data.Relationships);

Expand Down Expand Up @@ -106,8 +127,8 @@ private object SetEntityAttributes(
}

private object SetRelationships(
object entity,
ContextEntity contextEntity,
object entity,
ContextEntity contextEntity,
Dictionary<string, RelationshipData> relationships)
{
if (relationships == null || relationships.Count == 0)
Expand All @@ -117,18 +138,18 @@ private object SetRelationships(

foreach (var attr in contextEntity.Relationships)
{
entity = attr.IsHasOne
? SetHasOneRelationship(entity, entityProperties, attr, contextEntity, relationships)
entity = attr.IsHasOne
? SetHasOneRelationship(entity, entityProperties, attr, contextEntity, relationships)
: SetHasManyRelationship(entity, entityProperties, attr, contextEntity, relationships);
}

return entity;
}

private object SetHasOneRelationship(object entity,
PropertyInfo[] entityProperties,
RelationshipAttribute attr,
ContextEntity contextEntity,
private object SetHasOneRelationship(object entity,
PropertyInfo[] entityProperties,
RelationshipAttribute attr,
ContextEntity contextEntity,
Dictionary<string, RelationshipData> relationships)
{
var entityProperty = entityProperties.FirstOrDefault(p => p.Name == $"{attr.InternalRelationshipName}Id");
Expand All @@ -142,7 +163,7 @@ private object SetHasOneRelationship(object entity,
{
var relationshipAttr = _jsonApiContext.RequestEntity.Relationships
.SingleOrDefault(r => r.PublicRelationshipName == relationshipName);

var data = (Dictionary<string, string>)relationshipData.ExposedData;

if (data == null) return entity;
Expand All @@ -159,9 +180,9 @@ private object SetHasOneRelationship(object entity,
}

private object SetHasManyRelationship(object entity,
PropertyInfo[] entityProperties,
RelationshipAttribute attr,
ContextEntity contextEntity,
PropertyInfo[] entityProperties,
RelationshipAttribute attr,
ContextEntity contextEntity,
Dictionary<string, RelationshipData> relationships)
{
var entityProperty = entityProperties.FirstOrDefault(p => p.Name == attr.InternalRelationshipName);
Expand All @@ -179,7 +200,7 @@ private object SetHasManyRelationship(object entity,

var genericProcessor = _genericProcessorFactor.GetProcessor(attr.Type);
var ids = relationshipData.ManyData.Select(r => r["id"]);
genericProcessor.SetRelationships(entity, attr, ids);
genericProcessor.SetRelationships(entity, attr, ids);
}

return entity;
Expand Down
11 changes: 11 additions & 0 deletions test/UnitTests/Internal/TypeHelper_Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,16 @@ public void Can_Convert_DateTimeOffsets()
// assert
Assert.Equal(dto, result);
}

[Fact]
public void Bad_DateTimeOffset_String_Throws()
{
// arrange
var formattedString = "this_is_not_a_valid_dto";

// act
// assert
Assert.Throws<FormatException>(() => TypeHelper.ConvertType(formattedString, typeof(DateTimeOffset)));
}
}
}