Skip to content

Commit 08e2945

Browse files
authored
Merge pull request #262 from crfloyd/feature/#162
Feature/#162
2 parents 9e1fac9 + 470db70 commit 08e2945

File tree

6 files changed

+46
-11
lines changed

6 files changed

+46
-11
lines changed

src/Examples/JsonApiDotNetCoreExample/Models/Person.cs

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ public class Person : Identifiable, IHasMeta
2020

2121
[HasMany("todo-collections")]
2222
public virtual List<TodoItemCollection> TodoItemCollections { get; set; }
23+
24+
[HasOne("unincludeable-item", Link.All, canInclude: false)]
25+
public virtual TodoItem UnIncludeableItem { get; set; }
2326

2427
public Dictionary<string, object> GetMeta(IJsonApiContext context)
2528
{

src/JsonApiDotNetCore/Data/DefaultEntityRepository.cs

+11-4
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,18 @@ public virtual IQueryable<TEntity> Include(IQueryable<TEntity> entities, string
131131
{
132132
var entity = _jsonApiContext.RequestEntity;
133133
var relationship = entity.Relationships.FirstOrDefault(r => r.PublicRelationshipName == relationshipName);
134-
if (relationship != null)
135-
return entities.Include(relationship.InternalRelationshipName);
134+
if (relationship == null)
135+
{
136+
throw new JsonApiException(400, $"Invalid relationship {relationshipName} on {entity.EntityName}",
137+
$"{entity.EntityName} does not have a relationship named {relationshipName}");
138+
}
139+
140+
if (!relationship.CanInclude)
141+
{
142+
throw new JsonApiException(400, $"Including the relationship {relationshipName} on {entity.EntityName} is not allowed");
143+
}
144+
return entities.Include(relationship.InternalRelationshipName);
136145

137-
throw new JsonApiException(400, $"Invalid relationship {relationshipName} on {entity.EntityName}",
138-
$"{entity.EntityName} does not have a relationship named {relationshipName}");
139146
}
140147

141148
public virtual async Task<IEnumerable<TEntity>> PageAsync(IQueryable<TEntity> entities, int pageSize, int pageNumber)

src/JsonApiDotNetCore/Models/HasManyAttribute.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ namespace JsonApiDotNetCore.Models
22
{
33
public class HasManyAttribute : RelationshipAttribute
44
{
5-
public HasManyAttribute(string publicName, Link documentLinks = Link.All)
6-
: base(publicName, documentLinks)
5+
public HasManyAttribute(string publicName, Link documentLinks = Link.All, bool canInclude = true)
6+
: base(publicName, documentLinks, canInclude)
77
{ }
88

99
public override void SetValue(object entity, object newValue)

src/JsonApiDotNetCore/Models/HasOneAttribute.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ namespace JsonApiDotNetCore.Models
22
{
33
public class HasOneAttribute : RelationshipAttribute
44
{
5-
public HasOneAttribute(string publicName, Link documentLinks = Link.All)
6-
: base(publicName, documentLinks)
5+
public HasOneAttribute(string publicName, Link documentLinks = Link.All, bool canInclude = true)
6+
: base(publicName, documentLinks, canInclude)
77
{ }
88

99
public override void SetValue(object entity, object newValue)

src/JsonApiDotNetCore/Models/RelationshipAttribute.cs

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ namespace JsonApiDotNetCore.Models
44
{
55
public abstract class RelationshipAttribute : Attribute
66
{
7-
protected RelationshipAttribute(string publicName, Link documentLinks)
7+
protected RelationshipAttribute(string publicName, Link documentLinks, bool canInclude)
88
{
99
PublicRelationshipName = publicName;
1010
DocumentLinks = documentLinks;
11+
CanInclude = canInclude;
1112
}
1213

1314
public string PublicRelationshipName { get; }
@@ -16,6 +17,7 @@ protected RelationshipAttribute(string publicName, Link documentLinks)
1617
public bool IsHasMany => GetType() == typeof(HasManyAttribute);
1718
public bool IsHasOne => GetType() == typeof(HasOneAttribute);
1819
public Link DocumentLinks { get; } = Link.All;
20+
public bool CanInclude { get; }
1921

2022
public abstract void SetValue(object entity, object newValue);
2123

@@ -26,8 +28,7 @@ public override string ToString()
2628

2729
public override bool Equals(object obj)
2830
{
29-
var attr = obj as RelationshipAttribute;
30-
if (attr == null)
31+
if (!(obj is RelationshipAttribute attr))
3132
{
3233
return false;
3334
}

test/JsonApiDotNetCoreExampleTests/Acceptance/Spec/DocumentTests/Included.cs

+24
Original file line numberDiff line numberDiff line change
@@ -335,5 +335,29 @@ public async Task Request_ToIncludeDeeplyNestedRelationships_Returns_400()
335335
// assert
336336
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
337337
}
338+
339+
[Fact]
340+
public async Task Request_ToIncludeRelationshipMarkedCanIncludeFalse_Returns_400()
341+
{
342+
// arrange
343+
var person = _context.People.First();
344+
345+
var builder = new WebHostBuilder()
346+
.UseStartup<Startup>();
347+
348+
var httpMethod = new HttpMethod("GET");
349+
350+
var route = $"/api/v1/people/{person.Id}?include=unincludeable-item";
351+
352+
var server = new TestServer(builder);
353+
var client = server.CreateClient();
354+
var request = new HttpRequestMessage(httpMethod, route);
355+
356+
// act
357+
var response = await client.SendAsync(request);
358+
359+
// assert
360+
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
361+
}
338362
}
339363
}

0 commit comments

Comments
 (0)