Skip to content

Commit b042d4b

Browse files
committed
feat(serialization): add input formatter and handle POST request
1 parent b1ed2ab commit b042d4b

File tree

7 files changed

+56
-36
lines changed

7 files changed

+56
-36
lines changed

src/JsonApiDotNetCore/Controllers/JsonApiController.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,22 @@ public virtual IActionResult GetRelationship(int id, string relationshipName)
8484
return Ok(relationship);
8585
}
8686

87+
[HttpPost]
88+
public virtual IActionResult Post([FromBody] T entity)
89+
{
90+
if(entity == null)
91+
return BadRequest();
92+
93+
_dbSet.Add(entity);
94+
_context.SaveChanges();
95+
96+
return Created(HttpContext.Request.Path, entity);
97+
}
98+
8799
[HttpPatch("{id}")]
88-
public virtual IActionResult Patch(int id)
100+
public virtual IActionResult Patch(int id, [FromBody] T entity)
89101
{
102+
90103
return Ok("Patch Id");
91104
}
92105

src/JsonApiDotNetCore/Extensions/StringExtensions.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,30 @@ namespace JsonApiDotNetCore.Extensions
44
{
55
public static class StringExtensions
66
{
7+
public static string ToProperCase(this string str)
8+
{
9+
var chars = str.ToCharArray();
10+
if (chars.Length > 0)
11+
{
12+
chars[0] = char.ToUpper(chars[0]);
13+
var builder = new StringBuilder();
14+
for (var i = 0; i < chars.Length; i++)
15+
{
16+
if ((chars[i]) == '-')
17+
{
18+
i = i + 1;
19+
builder.Append(char.ToUpper(chars[i]));
20+
}
21+
else
22+
{
23+
builder.Append(chars[i]);
24+
}
25+
}
26+
return builder.ToString();
27+
}
28+
return str;
29+
}
30+
731
public static string Dasherize(this string str)
832
{
933
var chars = str.ToCharArray();

src/JsonApiDotNetCore/Formatters/JsonApiInputFormatter.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System;
22
using System.IO;
33
using System.Threading.Tasks;
4-
using JsonApiDotNetCore.Internal;
54
using JsonApiDotNetCore.Serialization;
5+
using JsonApiDotNetCore.Services;
66
using Microsoft.AspNetCore.Mvc.Formatters;
77
using Microsoft.Extensions.DependencyInjection;
88
using Newtonsoft.Json;
@@ -11,15 +11,14 @@ namespace JsonApiDotNetCore.Formatters
1111
{
1212
public class JsonApiInputFormatter : IInputFormatter
1313
{
14-
1514
public bool CanRead(InputFormatterContext context)
1615
{
1716
if (context == null)
1817
throw new ArgumentNullException(nameof(context));
1918

2019
var contentTypeString = context.HttpContext.Request.ContentType;
2120

22-
return string.IsNullOrEmpty(contentTypeString) || contentTypeString == "application/vnd.api+json";
21+
return contentTypeString == "application/vnd.api+json";
2322
}
2423

2524
public Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
@@ -37,7 +36,7 @@ public Task<InputFormatterResult> ReadAsync(InputFormatterContext context)
3736
try
3837
{
3938
var body = GetRequestBody(context.HttpContext.Request.Body);
40-
var contextGraph = context.HttpContext.RequestServices.GetService<IContextGraph>();
39+
var contextGraph = context.HttpContext.RequestServices.GetService<IJsonApiContext>().ContextGraph;
4140
var model = JsonApiDeSerializer.Deserialize(body, contextGraph);
4241

4342
return InputFormatterResult.SuccessAsync(model);

src/JsonApiDotNetCore/Models/DocumentData.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ public class DocumentData
1111
[JsonProperty("type")]
1212
public string Type
1313
{
14-
get { return _type; }
15-
set { _type = value.Dasherize(); }
14+
get { return _type.Dasherize(); }
15+
set { _type = value; }
1616
}
1717

1818
[JsonProperty("id")]

src/JsonApiDotNetCore/Routing/RouteBuilderExtensions.cs

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,12 @@ namespace JsonApiDotNetCore.Routing
55
{
66
public static class RouteBuilderExtensions
77
{
8-
// public static void UseJsonApi(this IRouteBuilder routes)
9-
// {
10-
// var defaultHandler = routes.ApplicationBuilder.ApplicationServices.GetRequiredService<MvcRouteHandler>();
11-
// routes.MapRoute(
12-
// name: "default",
13-
// template: "{controller=Home}/{action=Index}/{id?}");
14-
// }
15-
16-
// private static RequestDelegate RequestHandler()
17-
// {
18-
// return (context) => {
19-
// var model = context.GetRouteValue("model");
20-
// return context.Response.WriteAsync($"model: {model}");
21-
// };
22-
// }
23-
248
public static IApplicationBuilder UseJsonApi(this IApplicationBuilder app)
259
{
2610
if (app == null)
27-
{
2811
throw new ArgumentNullException(nameof(app));
29-
}
3012

3113
return app.UseMvc();
32-
3314
}
3415
}
3516
}

src/JsonApiDotNetCore/Serialization/JsonApiDeSerializer.cs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using System.Reflection;
5+
using JsonApiDotNetCore.Extensions;
56
using JsonApiDotNetCore.Internal;
67
using JsonApiDotNetCore.Models;
78
using Newtonsoft.Json;
@@ -13,27 +14,28 @@ public static class JsonApiDeSerializer
1314
public static object Deserialize(string requestBody, IContextGraph contextGraph)
1415
{
1516
var document = JsonConvert.DeserializeObject<Document>(requestBody);
16-
var contextEntity = contextGraph.GetContextEntity(document.Data.Type);
17-
17+
18+
var entityTypeName = document.Data.Type.ToProperCase();
19+
20+
var contextEntity = contextGraph.GetContextEntity(entityTypeName);
21+
1822
var entity = Activator.CreateInstance(contextEntity.EntityType);
19-
20-
entity = _setEntityAttributes(entity, contextEntity, document.Data.Attributes);
2123

22-
return null;
24+
return _setEntityAttributes(entity, contextEntity, document.Data.Attributes);
2325
}
2426

2527
private static object _setEntityAttributes(
2628
object entity, ContextEntity contextEntity, Dictionary<string, object> attributeValues)
2729
{
2830
var entityProperties = entity.GetType().GetProperties();
2931

30-
foreach(var attr in contextEntity.Attributes)
32+
foreach (var attr in contextEntity.Attributes)
3133
{
3234
var entityProperty = entityProperties.FirstOrDefault(p => p.Name == attr.InternalAttributeName);
33-
34-
if(entityProperty == null)
35+
36+
if (entityProperty == null)
3537
throw new ArgumentException($"{contextEntity.EntityType.Name} does not contain an attribute named {attr.InternalAttributeName}", nameof(entity));
36-
38+
3739
object newValue;
3840
if (attributeValues.TryGetValue(attr.PublicAttributeName, out newValue))
3941
{

src/JsonApiDotNetCoreExample/Controllers/PeopleController.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ public class PeopleController : JsonApiController<Person>
1212
{
1313
public PeopleController(
1414
ILoggerFactory loggerFactory,
15-
AppDbContext context, IJsonApiContext jsonApiContext)
15+
AppDbContext context,
16+
IJsonApiContext jsonApiContext)
1617
: base(loggerFactory, context, jsonApiContext)
1718
{ }
1819
}

0 commit comments

Comments
 (0)