Skip to content

Commit 11450e5

Browse files
authored
Merge pull request #97 from Research-Institute/fix/#93
Fix/#93
2 parents 30e1c0d + d2ef98e commit 11450e5

11 files changed

+431
-12
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ JsonApiDotnetCore provides a framework for building [json:api](http://jsonapi.or
2222
- [Non-Integer Type Keys](#non-integer-type-keys)
2323
- [Routing](#routing)
2424
- [Namespacing and Versioning URLs](#namespacing-and-versioning-urls)
25+
- [Disable Convention](#disable-convention)
2526
- [Defining Custom Data Access Methods](#defining-custom-data-access-methods)
2627
- [Pagination](#pagination)
2728
- [Filtering](#filtering)
@@ -244,6 +245,24 @@ services.AddJsonApi<AppDbContext>(
244245
opt => opt.Namespace = "api/v1");
245246
```
246247

248+
#### Disable Convention
249+
250+
You can disable the dasherized convention and specify your own template
251+
by using the `DisableRoutingConvention` Attribute:
252+
253+
```csharp
254+
[DisableRoutingConvention]
255+
public class CamelCasedModelsController : JsonApiController<CamelCasedModel>
256+
{
257+
public CamelCasedModelsController(
258+
IJsonApiContext jsonApiContext,
259+
IResourceService<CamelCasedModel> resourceService,
260+
ILoggerFactory loggerFactory)
261+
: base(jsonApiContext, resourceService, loggerFactory)
262+
{ }
263+
}
264+
```
265+
247266
### Defining Custom Data Access Methods
248267

249268
By default, data retrieval is distributed across 3 layers:
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
using System;
2+
3+
namespace JsonApiDotNetCore.Controllers
4+
{
5+
public class DisableRoutingConventionAttribute : Attribute
6+
{ }
7+
}
Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// REF: https://github.com/aspnet/Entropy/blob/dev/samples/Mvc.CustomRoutingConvention/NameSpaceRoutingConvention.cs
22
// REF: https://github.com/aspnet/Mvc/issues/5691
3+
using System.Reflection;
34
using JsonApiDotNetCore.Controllers;
45
using JsonApiDotNetCore.Extensions;
6+
using Microsoft.AspNetCore.Mvc;
57
using Microsoft.AspNetCore.Mvc.ApplicationModels;
68

79
namespace JsonApiDotNetCore.Internal
@@ -17,21 +19,36 @@ public DasherizedRoutingConvention(string nspace)
1719
public void Apply(ApplicationModel application)
1820
{
1921
foreach (var controller in application.Controllers)
20-
{
21-
if (IsJsonApiController(controller))
22+
{
23+
var template = string.Empty;
24+
25+
if (IsDasherizedJsonApiController(controller))
26+
template = $"{_namespace}/{controller.ControllerName.Dasherize()}";
27+
else
28+
template = GetTemplate(controller);
29+
30+
controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
2231
{
23-
var template = $"{_namespace}/{controller.ControllerName.Dasherize()}";
24-
controller.Selectors[0].AttributeRouteModel = new AttributeRouteModel()
25-
{
26-
Template = template
27-
};
28-
}
32+
Template = template
33+
};
2934
}
3035
}
3136

32-
private bool IsJsonApiController(ControllerModel controller)
37+
private bool IsDasherizedJsonApiController(ControllerModel controller)
3338
{
34-
return controller.ControllerType.IsSubclassOf(typeof(JsonApiControllerMixin));
39+
var type = controller.ControllerType;
40+
var notDisabled = type.GetCustomAttribute<DisableRoutingConventionAttribute>() == null;
41+
return notDisabled && type.IsSubclassOf(typeof(JsonApiControllerMixin));
42+
}
43+
44+
private string GetTemplate(ControllerModel controller)
45+
{
46+
var type = controller.ControllerType;
47+
var routeAttr = type.GetCustomAttribute<RouteAttribute>();
48+
if(routeAttr != null)
49+
return ((RouteAttribute)routeAttr).Template;
50+
51+
return controller.ControllerName;
3552
}
3653
}
3754
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using JsonApiDotNetCore.Controllers;
2+
using JsonApiDotNetCore.Services;
3+
using JsonApiDotNetCoreExample.Models;
4+
using Microsoft.Extensions.Logging;
5+
6+
namespace JsonApiDotNetCoreExample.Controllers
7+
{
8+
[DisableRoutingConvention]
9+
public class CamelCasedModelsController : JsonApiController<CamelCasedModel>
10+
{
11+
public CamelCasedModelsController(
12+
IJsonApiContext jsonApiContext,
13+
IResourceService<CamelCasedModel> resourceService,
14+
ILoggerFactory loggerFactory)
15+
: base(jsonApiContext, resourceService, loggerFactory)
16+
{ }
17+
}
18+
}

src/JsonApiDotNetCoreExample/Controllers/TodoItemsCustomController.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.Collections.Generic;
22
using System.Threading.Tasks;
3+
using JsonApiDotNetCore.Controllers;
34
using JsonApiDotNetCore.Models;
45
using JsonApiDotNetCore.Services;
56
using JsonApiDotNetCoreExample.Models;
@@ -8,6 +9,7 @@
89

910
namespace JsonApiDotNetCoreExample.Controllers
1011
{
12+
[DisableRoutingConvention]
1113
[Route("custom/route/todo-items")]
1214
public class TodoItemsCustomController : CustomJsonApiController<TodoItem>
1315
{

src/JsonApiDotNetCoreExample/Data/AppDbContext.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
using JsonApiDotNetCoreExample.Models;
22
using JsonApiDotNetCore.Models;
3-
using JsonApiDotNetCoreExample.Models;
43
using Microsoft.EntityFrameworkCore;
5-
using System;
64

75
namespace JsonApiDotNetCoreExample.Data
86
{
@@ -33,5 +31,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
3331

3432
[Resource("todo-collections")]
3533
public DbSet<TodoItemCollection> TodoItemCollections { get; set; }
34+
35+
[Resource("camelCasedModels")]
36+
public DbSet<CamelCasedModel> CamelCasedModels { get; set; }
3637
}
3738
}

src/JsonApiDotNetCoreExample/Migrations/20170426232509_AddCamelCasedModel.Designer.cs

Lines changed: 120 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Microsoft.EntityFrameworkCore.Migrations;
4+
using Microsoft.EntityFrameworkCore.Metadata;
5+
6+
namespace JsonApiDotNetCoreExample.Migrations
7+
{
8+
public partial class AddCamelCasedModel : Migration
9+
{
10+
protected override void Up(MigrationBuilder migrationBuilder)
11+
{
12+
migrationBuilder.CreateTable(
13+
name: "CamelCasedModels",
14+
columns: table => new
15+
{
16+
Id = table.Column<int>(nullable: false)
17+
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn),
18+
CompoundAttr = table.Column<string>(nullable: true)
19+
},
20+
constraints: table =>
21+
{
22+
table.PrimaryKey("PK_CamelCasedModels", x => x.Id);
23+
});
24+
}
25+
26+
protected override void Down(MigrationBuilder migrationBuilder)
27+
{
28+
migrationBuilder.DropTable(
29+
name: "CamelCasedModels");
30+
}
31+
}
32+
}

src/JsonApiDotNetCoreExample/Migrations/AppDbContextModelSnapshot.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,18 @@ protected override void BuildModel(ModelBuilder modelBuilder)
1616
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.SerialColumn)
1717
.HasAnnotation("ProductVersion", "1.1.1");
1818

19+
modelBuilder.Entity("JsonApiDotNetCoreExample.Models.CamelCasedModel", b =>
20+
{
21+
b.Property<int>("Id")
22+
.ValueGeneratedOnAdd();
23+
24+
b.Property<string>("CompoundAttr");
25+
26+
b.HasKey("Id");
27+
28+
b.ToTable("CamelCasedModels");
29+
});
30+
1931
modelBuilder.Entity("JsonApiDotNetCoreExample.Models.Person", b =>
2032
{
2133
b.Property<int>("Id")
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using JsonApiDotNetCore.Models;
2+
3+
namespace JsonApiDotNetCoreExample.Models
4+
{
5+
public class CamelCasedModel : Identifiable
6+
{
7+
[Attr("compoundAttr")]
8+
public string CompoundAttr { get; set; }
9+
}
10+
}

0 commit comments

Comments
 (0)