Skip to content

Commit 568cff3

Browse files
committed
Initial commit
0 parents  commit 568cff3

17 files changed

+634
-0
lines changed

Diff for: .gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
bin/
2+
obj/
3+
/packages/
4+
riderModule.iml
5+
/_ReSharper.Caches/

Diff for: .idea/.idea.InertiaCore/.idea/.gitignore

+15
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: .idea/.idea.InertiaCore/.idea/indexLayout.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: .idea/.idea.InertiaCore/.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Extensions/Configure.cs

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System.Net;
2+
using Microsoft.AspNetCore.Builder;
3+
using Microsoft.AspNetCore.Http;
4+
using Microsoft.AspNetCore.Mvc.ViewFeatures;
5+
using Microsoft.Extensions.DependencyInjection;
6+
7+
namespace InertiaCore.Extensions;
8+
9+
public static class Configure
10+
{
11+
public static IApplicationBuilder UseInertia(this IApplicationBuilder app)
12+
{
13+
var factory = app.ApplicationServices.GetRequiredService<IResponseFactory>();
14+
Inertia.UseFactory(factory);
15+
16+
app.Use(async (context, next) =>
17+
{
18+
if (context.IsInertiaRequest()
19+
&& context.Request.Method == "GET"
20+
&& context.Request.Headers["X-Inertia-Version"] != Inertia.GetVersion())
21+
{
22+
await OnVersionChange(context, app);
23+
return;
24+
}
25+
26+
await next();
27+
});
28+
29+
return app;
30+
}
31+
32+
public static IServiceCollection AddInertia(this IServiceCollection services)
33+
{
34+
services.AddSingleton<IResponseFactory, ResponseFactory>();
35+
36+
return services;
37+
}
38+
39+
public static IMvcBuilder AddInertiaOptions(this IMvcBuilder builder)
40+
{
41+
builder.AddMvcOptions(options => { options.Filters.Add<InertiaActionFilter>(); });
42+
43+
return builder;
44+
}
45+
46+
private static async Task OnVersionChange(HttpContext context, IApplicationBuilder app)
47+
{
48+
var tempData = app.ApplicationServices.GetRequiredService<TempDataDictionaryFactory>()
49+
.GetTempData(context);
50+
51+
if (tempData.Any()) tempData.Keep();
52+
53+
context.Response.Headers.Add("X-Inertia-Location", context.RequestedUri());
54+
context.Response.StatusCode = (int)HttpStatusCode.Conflict;
55+
56+
await context.Response.CompleteAsync();
57+
}
58+
}

Diff for: Extensions/InertiaExtensions.cs

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
using System.Text.Json;
2+
using Microsoft.AspNetCore.Http;
3+
using Microsoft.AspNetCore.Http.Extensions;
4+
using Microsoft.AspNetCore.Mvc;
5+
6+
namespace InertiaCore.Extensions;
7+
8+
internal static class InertiaExtensions
9+
{
10+
internal static IEnumerable<string> Only(this object obj, IEnumerable<string> only) =>
11+
obj.GetType().GetProperties().Select(c => c.Name)
12+
.Intersect(only, StringComparer.OrdinalIgnoreCase).ToList();
13+
14+
internal static List<string> GetPartialData(this ActionContext context) =>
15+
context.HttpContext.Request.Headers["X-Inertia-Partial-Data"]
16+
.FirstOrDefault()?.Split(",")
17+
.Where(s => !string.IsNullOrEmpty(s))
18+
.ToList() ?? new List<string>();
19+
20+
internal static bool IsInertiaPartialComponent(this ActionContext context, string component) =>
21+
context.HttpContext.Request.Headers["X-Inertia-Partial-Component"] == component;
22+
23+
internal static string RequestedUri(this HttpContext context) =>
24+
Uri.UnescapeDataString(context.Request.GetEncodedPathAndQuery());
25+
26+
internal static string RequestedUri(this ActionContext context) => context.HttpContext.RequestedUri();
27+
28+
internal static bool IsInertiaRequest(this HttpContext context) =>
29+
bool.TryParse(context.Request.Headers["X-Inertia"], out _);
30+
31+
internal static bool IsInertiaRequest(this ActionContext context) => context.HttpContext.IsInertiaRequest();
32+
33+
internal static string ToCamelCase(this string s) => JsonNamingPolicy.CamelCase.ConvertName(s);
34+
}

Diff for: Inertia.cs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Microsoft.AspNetCore.Html;
2+
3+
namespace InertiaCore;
4+
5+
public static class Inertia
6+
{
7+
private static IResponseFactory _factory = default!;
8+
9+
internal static void UseFactory(IResponseFactory factory) => _factory = factory;
10+
11+
public static Response Render(string component, object? props = null) => _factory.Render(component, props);
12+
13+
public static IHtmlContent Html(dynamic model) => _factory.Html(model);
14+
15+
public static void SetRootView(string rootView) => _factory.SetRootView(rootView);
16+
17+
public static void Version(object? version) => _factory.Version(version);
18+
19+
public static string? GetVersion() => _factory.GetVersion();
20+
21+
public static LocationResult Location(string url) => _factory.Location(url);
22+
}

Diff for: InertiaActionFilter.cs

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System.Net;
2+
using InertiaCore.Extensions;
3+
using Microsoft.AspNetCore.Mvc;
4+
using Microsoft.AspNetCore.Mvc.Filters;
5+
using Microsoft.AspNetCore.Mvc.Routing;
6+
7+
namespace InertiaCore;
8+
9+
internal class InertiaActionFilter : IActionFilter
10+
{
11+
private readonly IUrlHelperFactory _urlHelperFactory;
12+
13+
public InertiaActionFilter(IUrlHelperFactory urlHelperFactory) => _urlHelperFactory = urlHelperFactory;
14+
15+
public void OnActionExecuting(ActionExecutingContext context)
16+
{
17+
//
18+
}
19+
20+
public void OnActionExecuted(ActionExecutedContext context)
21+
{
22+
if (!context.IsInertiaRequest()
23+
|| !new[] { "PUT", "PATCH", "DELETE" }.Contains(context.HttpContext.Request.Method)) return;
24+
25+
var destinationUrl = context.Result switch
26+
{
27+
RedirectResult result => result.Url,
28+
RedirectToActionResult result => GetUrl(result, context),
29+
RedirectToPageResult result => GetUrl(result, context),
30+
RedirectToRouteResult result => GetUrl(result, context),
31+
_ => null
32+
};
33+
34+
if (destinationUrl == null) return;
35+
context.HttpContext.Response.Headers.Add("Location", destinationUrl);
36+
context.Result = new StatusCodeResult((int)HttpStatusCode.RedirectMethod);
37+
}
38+
39+
private string? GetUrl(RedirectToActionResult result, ActionContext context)
40+
{
41+
var urlHelper = result.UrlHelper ?? _urlHelperFactory.GetUrlHelper(context);
42+
43+
return urlHelper.Action(
44+
result.ActionName,
45+
result.ControllerName,
46+
result.RouteValues,
47+
null,
48+
null,
49+
result.Fragment);
50+
}
51+
52+
private string? GetUrl(RedirectToPageResult result, ActionContext context)
53+
{
54+
var urlHelper = result.UrlHelper ?? _urlHelperFactory.GetUrlHelper(context);
55+
56+
return urlHelper.Page(
57+
result.PageName,
58+
result.PageHandler,
59+
result.RouteValues,
60+
result.Protocol,
61+
result.Host,
62+
result.Fragment);
63+
}
64+
65+
private string? GetUrl(RedirectToRouteResult result, ActionContext context)
66+
{
67+
var urlHelper = result.UrlHelper ?? _urlHelperFactory.GetUrlHelper(context);
68+
69+
return urlHelper.RouteUrl(
70+
result.RouteName,
71+
result.RouteValues,
72+
null,
73+
null,
74+
result.Fragment);
75+
}
76+
}

Diff for: InertiaCore.csproj

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<ImplicitUsings>enable</ImplicitUsings>
4+
<Nullable>enable</Nullable>
5+
<Version>0.0.1</Version>
6+
<TargetFrameworks>net6.0;net7.0</TargetFrameworks>
7+
<PackageId>AspNetCore.InertiaCore</PackageId>
8+
<Authors>kapi2289</Authors>
9+
<Description>Inertia.js ASP.NET Adapter. https://inertiajs.com/</Description>
10+
<PackageProjectUrl>https://github.com/kapi2289/InertiaCore</PackageProjectUrl>
11+
<RepositoryUrl>https://github.com/kapi2289/InertiaCore</RepositoryUrl>
12+
<RepositoryType>git</RepositoryType>
13+
<PackageTags>Inertia,Inertiajs,ASPNET,Vue</PackageTags>
14+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
15+
</PropertyGroup>
16+
17+
<ItemGroup>
18+
<PackageReference Include="Microsoft.AspNetCore.App" Version="2.2.8"/>
19+
<PackageReference Include="TypeMerger" Version="2.1.1"/>
20+
</ItemGroup>
21+
22+
</Project>

Diff for: InertiaCore.sln

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InertiaCore", "InertiaCore.csproj", "{91B0802C-4C03-4C7C-8043-140C98BB7341}"
4+
EndProject
5+
Global
6+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
7+
Debug|Any CPU = Debug|Any CPU
8+
Release|Any CPU = Release|Any CPU
9+
EndGlobalSection
10+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
11+
{91B0802C-4C03-4C7C-8043-140C98BB7341}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
12+
{91B0802C-4C03-4C7C-8043-140C98BB7341}.Debug|Any CPU.Build.0 = Debug|Any CPU
13+
{91B0802C-4C03-4C7C-8043-140C98BB7341}.Release|Any CPU.ActiveCfg = Release|Any CPU
14+
{91B0802C-4C03-4C7C-8043-140C98BB7341}.Release|Any CPU.Build.0 = Release|Any CPU
15+
EndGlobalSection
16+
EndGlobal

Diff for: InertiaSharedData.cs

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
namespace InertiaCore;
2+
3+
public class InertiaSharedData
4+
{
5+
public IDictionary<string, object?>? Data { get; set; }
6+
7+
public Dictionary<string, object?> Merge(IDictionary<string, object?> with)
8+
{
9+
var result = new Dictionary<string, object?>();
10+
11+
if (Data != null)
12+
foreach (var (key, value) in Data)
13+
result[key] = value;
14+
15+
foreach (var (key, value) in with) result[key] = value;
16+
17+
return result;
18+
}
19+
}

Diff for: LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 Kacper Ziubryniewicz
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

Diff for: LocationResult.cs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System.Net;
2+
using InertiaCore.Extensions;
3+
using Microsoft.AspNetCore.Mvc;
4+
5+
namespace InertiaCore;
6+
7+
public class LocationResult : IActionResult
8+
{
9+
private readonly string _url;
10+
11+
public LocationResult(string url) => _url = url;
12+
13+
public async Task ExecuteResultAsync(ActionContext context)
14+
{
15+
if (context.IsInertiaRequest())
16+
{
17+
context.HttpContext.Response.Headers.Add("X-Inertia-Location", _url);
18+
await new StatusCodeResult((int)HttpStatusCode.Conflict).ExecuteResultAsync(context);
19+
}
20+
21+
await new RedirectResult(_url).ExecuteResultAsync(context);
22+
}
23+
}

Diff for: Page.cs

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace InertiaCore;
2+
3+
internal class Page
4+
{
5+
public Dictionary<string, object?> Props { get; set; } = default!;
6+
public string Component { get; set; } = default!;
7+
public string? Version { get; set; }
8+
public string Url { get; set; } = default!;
9+
}

0 commit comments

Comments
 (0)