Skip to content

Commit db2d663

Browse files
author
Jouke van der Maas
committed
Merge pull request #79 from joukevandermaas/iis
Always prefix IIS virtual path root
2 parents d3c0205 + 9383139 commit db2d663

4 files changed

Lines changed: 36 additions & 20 deletions

File tree

Saule/Constants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ internal class Constants
55
public const string RequestPropertyName = "Saule_ResourceDescriptor";
66
public const string QueryContextPropertyName = "Saule_QueryContext";
77
public const string PreprocessResultPropertyName = "Saule_PreprocessedResult";
8+
public const string WebApiRequestContextPropertyName = "MS_RequestContext";
89

910
public const string MediaType = "application/vnd.api+json";
1011

Saule/Http/PreprocessingDelegatingHandler.cs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ internal static PreprocessResult PreprocessRequest(
4343
};
4444
}
4545

46-
PrepareUrlPathBuilder(jsonApi, request, config, resource);
46+
PrepareUrlPathBuilder(jsonApi, request, config);
4747

4848
return jsonApi.PreprocessContent(content, resource, request.RequestUri);
4949
}
@@ -77,27 +77,26 @@ protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage
7777
private static void PrepareUrlPathBuilder(
7878
JsonApiSerializer jsonApiSerializer,
7979
HttpRequestMessage request,
80-
JsonApiConfiguration config,
81-
ApiResource resource)
80+
JsonApiConfiguration config)
8281
{
83-
var result = config.UrlPathBuilder;
84-
if (resource == null)
82+
if (config.UrlPathBuilder != null)
8583
{
86-
result = result ?? new DefaultUrlPathBuilder();
84+
jsonApiSerializer.UrlPathBuilder = config.UrlPathBuilder;
8785
}
88-
else if (!request.Properties.ContainsKey("MS_RequestContext"))
86+
else if (!request.Properties.ContainsKey(Constants.WebApiRequestContextPropertyName))
8987
{
90-
result = result ?? new DefaultUrlPathBuilder();
88+
jsonApiSerializer.UrlPathBuilder = new DefaultUrlPathBuilder();
9189
}
9290
else
9391
{
94-
var routeTemplate = (request.Properties["MS_RequestContext"] as HttpRequestContext)
95-
?.RouteData.Route.RouteTemplate;
96-
result = result ?? new DefaultUrlPathBuilder(
97-
routeTemplate, resource);
98-
}
92+
var requestContext = request.Properties[Constants.WebApiRequestContextPropertyName]
93+
as HttpRequestContext;
94+
var routeTemplate = requestContext?.RouteData.Route.RouteTemplate;
95+
var virtualPathRoot = requestContext?.VirtualPathRoot ?? "/";
9996

100-
jsonApiSerializer.UrlPathBuilder = result;
97+
jsonApiSerializer.UrlPathBuilder = new DefaultUrlPathBuilder(
98+
virtualPathRoot, routeTemplate);
99+
}
101100
}
102101

103102
private static void PrepareQueryContext(

Saule/Serialization/DefaultUrlPathBuilder.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public DefaultUrlPathBuilder(string prefix)
2929
_prefix = prefix;
3030
}
3131

32-
internal DefaultUrlPathBuilder(string template, ApiResource resource)
32+
internal DefaultUrlPathBuilder(string virtualPathRoot, string template)
3333
{
3434
var templateParts = template.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
3535
var dynamicCount = templateParts.Count(t => t.StartsWith("{"));
@@ -40,7 +40,7 @@ internal DefaultUrlPathBuilder(string template, ApiResource resource)
4040
preDynamic = preDynamic.Take(preDynamic.Count - 1).ToList();
4141
}
4242

43-
_prefix = '/'.TrimJoin(preDynamic.ToArray());
43+
_prefix = '/'.TrimJoin(virtualPathRoot.ToEnumerable().Concat(preDynamic).ToArray());
4444
}
4545

4646
/// <summary>

Tests/Serialization/DefaultUrlPathBuilderTests.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public static IEnumerable<object[]> GetPrefixData()
2929
{
3030
"/api",
3131
"/two/parts",
32-
""
32+
"/"
3333
};
3434
var templates = new[]
3535
{
@@ -45,20 +45,36 @@ from template in templates
4545
select new object[] { prefix, template };
4646
}
4747

48-
[Theory(DisplayName = "Finds correct prefix from template & url/")]
48+
[Theory(DisplayName = "Finds correct prefix from template & url")]
4949
[MemberData("GetPrefixData")]
5050
public void FindsCorrectPrefix(string prefix, string template)
5151
{
5252
var resource = new PersonResource();
5353
template = $"{prefix}/{template}";
5454

55-
var builder = new DefaultUrlPathBuilder(template, resource);
55+
var builder = new DefaultUrlPathBuilder("/", template);
5656

5757
var url = builder.BuildCanonicalPath(resource);
5858

5959
_output.WriteLine($"template: {template}\ngenerated result: {url}");
6060

61-
Assert.Equal($"{prefix}/people/", builder.BuildCanonicalPath(resource));
61+
Assert.Equal($"{prefix.TrimEnd('/')}/people/", builder.BuildCanonicalPath(resource));
62+
}
63+
64+
[Theory(DisplayName = "Finds correct prefix from template, virtual path root & url")]
65+
[MemberData("GetPrefixData")]
66+
public void FindsCorrectPrefixWithVirtualPath(string prefix, string template)
67+
{
68+
var resource = new PersonResource();
69+
template = $"test/{template}";
70+
71+
var builder = new DefaultUrlPathBuilder(prefix, template);
72+
73+
var url = builder.BuildCanonicalPath(resource);
74+
75+
_output.WriteLine($"template: {template}\ngenerated result: {url}");
76+
77+
Assert.Equal($"{prefix.TrimEnd('/')}/test/people/", builder.BuildCanonicalPath(resource));
6278
}
6379

6480
[Fact(DisplayName = "Collection uses ApiResource.UrlPath")]

0 commit comments

Comments
 (0)