├── .gitignore ├── Inertia.AspNetCore ├── Views │ └── Shared │ │ └── inertia.cshtml ├── Inertia.cs ├── Configure.cs ├── Inertia.AspNetCore.csproj └── Result.cs ├── .github └── workflows │ ├── xunit.yml │ └── nuget.yml ├── Inertia.AspNetCore.Tests ├── InertiaTest.cs ├── ConfigureTest.cs └── Inertia.AspNetCore.Tests.csproj ├── README.md ├── LICENSE └── Inertia.sln /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | /packages/ 4 | riderModule.iml 5 | /_ReSharper.Caches/ 6 | .idea 7 | -------------------------------------------------------------------------------- /Inertia.AspNetCore/Views/Shared/inertia.cshtml: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /Inertia.AspNetCore/Inertia.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | 3 | namespace Inertia.AspNetCore 4 | { 5 | public abstract class InertiaController : Controller 6 | { 7 | public virtual IActionResult Inertia(string component, object props) => new InertiaResult(component, props, ViewData, TempData); 8 | } 9 | } -------------------------------------------------------------------------------- /.github/workflows/xunit.yml: -------------------------------------------------------------------------------- 1 | name: XUnit 2 | on: [push] 3 | jobs: 4 | test: 5 | runs-on: ubuntu-latest 6 | steps: 7 | - uses: actions/checkout@v2 8 | - name: Setup dotnet 9 | uses: actions/setup-dotnet@v1 10 | with: 11 | dotnet-version: | 12 | 5.x 13 | 6.x 14 | - name: Install dependencies 15 | run: dotnet restore 16 | - name: Build 17 | run: dotnet build --configuration Release --no-restore 18 | - name: Test with the dotnet CLI 19 | run: dotnet test --no-restore --verbosity normal -------------------------------------------------------------------------------- /Inertia.AspNetCore.Tests/InertiaTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Moq; 3 | using Xunit; 4 | 5 | namespace Inertia.AspNetCore.Tests 6 | { 7 | public class InertiaTest 8 | { 9 | [Fact] 10 | public void Inertia_Inertia_ReturnsInertiaResult() 11 | { 12 | Mock mock = new Mock 13 | { 14 | CallBase = true 15 | }; 16 | 17 | IActionResult result = mock.Object.Inertia("abc", new { }); 18 | 19 | Assert.IsType(result); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /Inertia.AspNetCore/Configure.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using Microsoft.Extensions.DependencyInjection; 3 | using Microsoft.Extensions.FileProviders; 4 | 5 | namespace Inertia.AspNetCore 6 | { 7 | public static class Configure 8 | { 9 | public static IMvcBuilder AddInertia(this IMvcBuilder app) 10 | { 11 | app.AddRazorRuntimeCompilation(opts => 12 | { 13 | opts.FileProviders.Add( 14 | new EmbeddedFileProvider(typeof(Configure).GetTypeInfo().Assembly)); 15 | }); 16 | 17 | return app; 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /Inertia.AspNetCore.Tests/ConfigureTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Moq; 3 | using Xunit; 4 | 5 | namespace Inertia.AspNetCore.Tests 6 | { 7 | public class ConfigureTest 8 | { 9 | [Fact] 10 | public void Configure_AddInertia_ReturnIMvcBuilder() 11 | { 12 | Mock mock = new Mock 13 | { 14 | DefaultValue = DefaultValue.Mock 15 | }; 16 | 17 | IMvcBuilder result = mock.Object.AddInertia(); 18 | 19 | Assert.IsAssignableFrom(result); 20 | } 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /.github/workflows/nuget.yml: -------------------------------------------------------------------------------- 1 | name: Nuget 2 | on: 3 | release: 4 | types: [created] 5 | jobs: 6 | push: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v2 10 | - name: Setup dotnet 11 | uses: actions/setup-dotnet@v1 12 | with: 13 | dotnet-version: | 14 | 5.x 15 | 6.x 16 | - name: Install dependencies 17 | run: dotnet restore 18 | - name: Build 19 | run: dotnet build --configuration Release --no-restore 20 | - name: Pack 21 | run: dotnet pack -c Release -o out 22 | - name: Push 23 | run: dotnet nuget push ./out/*.nupkg -k ${NUGET_TOKEN} -s https://api.nuget.org/v3/index.json 24 | env: 25 | NUGET_TOKEN: ${{ secrets.NUGET_TOKEN }} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://user-images.githubusercontent.com/6599653/114456558-032e2200-9bab-11eb-88bc-a19897f417ba.png) 2 | 3 | 4 | # Inertia.js ASP.Net Core Adapter 5 | 6 | ## Prerequisite 7 | 1. .NET Core v5 and later 8 | 2. An ASP.NET Core MVC project 9 | 10 | ## Install 11 | 1. Package Manager: PM> Install-Package Inertia.AspNetCore 12 | 2. .NET CLI: dotnet add package Inertia.AspNetCore 13 | 14 | ## Usage 15 | 1. Setup Startup.cs 16 | ```c# 17 | using Inertia.AspNetCore; 18 | 19 | public void ConfigureServices(IServiceCollection services) 20 | { 21 | services.AddControllersWithViews().AddInertia(); 22 | } 23 | ``` 24 | 2. In your controller 25 | ````c# 26 | using Inertia.AspNetCore; 27 | 28 | public class HomeController : InertiaController { 29 | public IActionResult Index() 30 | { 31 | return Inertia("Index", new 32 | { 33 | UserId = 1 34 | }); 35 | } 36 | } 37 | ```` 38 | 39 | Visit [inertiajs.com](https://inertiajs.com/) to learn more. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Frédéric C. 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. -------------------------------------------------------------------------------- /Inertia.AspNetCore.Tests/Inertia.AspNetCore.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0;net6.0 5 | enable 6 | 7 | false 8 | 9 | 9 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | all 19 | 20 | 21 | runtime; build; native; contentfiles; analyzers; buildtransitive 22 | all 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Inertia.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Inertia.AspNetCore", "Inertia.AspNetCore\Inertia.AspNetCore.csproj", "{4CAEE378-E68F-4DDD-B280-C87BF02DA2B1}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Inertia.AspNetCore.Tests", "Inertia.AspNetCore.Tests\Inertia.AspNetCore.Tests.csproj", "{085947E5-77A4-4A13-8D4E-1A8FD8B45AB6}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {4CAEE378-E68F-4DDD-B280-C87BF02DA2B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {4CAEE378-E68F-4DDD-B280-C87BF02DA2B1}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {4CAEE378-E68F-4DDD-B280-C87BF02DA2B1}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {4CAEE378-E68F-4DDD-B280-C87BF02DA2B1}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {085947E5-77A4-4A13-8D4E-1A8FD8B45AB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {085947E5-77A4-4A13-8D4E-1A8FD8B45AB6}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {085947E5-77A4-4A13-8D4E-1A8FD8B45AB6}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {085947E5-77A4-4A13-8D4E-1A8FD8B45AB6}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Inertia.AspNetCore/Inertia.AspNetCore.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net5.0;net6.0 5 | true 6 | Inertia.AspNetCore 7 | 0.0.7 8 | A simple AspNetCore adapter for Inertia.js. https://inertiajs.com 9 | Frédéric Choquette 10 | https://www.nuget.org/packages/Inertia.AspNetCore/ 11 | https://github.com/frederic2ec/inertia-aspnetcore 12 | git 13 | LICENSE 14 | AspNetCore, Inertia.js, Inertia 15 | true 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | True 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Inertia.AspNetCore/Result.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.CompilerServices; 3 | using System.Text.Json; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.AspNetCore.Mvc.ViewFeatures; 7 | 8 | [assembly:InternalsVisibleTo("Inertia.AspNetCore.Tests")] 9 | namespace Inertia.AspNetCore 10 | { 11 | internal class InertiaData 12 | { 13 | public string component { get; set; } 14 | public object props { get; set; } 15 | public string url { get; set; } 16 | public string version { get; set; } 17 | 18 | } 19 | 20 | internal class InertiaResult : IActionResult 21 | { 22 | private readonly string _component; 23 | private readonly object _props; 24 | private readonly ViewDataDictionary _viewData; 25 | private readonly ITempDataDictionary _tempData; 26 | 27 | internal InertiaResult(string component, object props, ViewDataDictionary viewData, ITempDataDictionary tempData) 28 | { 29 | _component = component; 30 | _props = props; 31 | _viewData = viewData; 32 | _tempData = tempData; 33 | } 34 | 35 | public async Task ExecuteResultAsync(ActionContext context) 36 | { 37 | InertiaData data = new InertiaData 38 | { 39 | component = _component, 40 | props = _props, 41 | url = context.HttpContext.Request.Path.Value + context.HttpContext.Request.QueryString.Value, 42 | version = Guid.NewGuid().ToString().Replace("-", string.Empty) 43 | }; 44 | 45 | string dataString = JsonSerializer.Serialize(data); 46 | 47 | if (context.HttpContext.Request.Headers.ContainsKey("X-Inertia")) 48 | { 49 | if (context.HttpContext.Request.Headers["X-Inertia"].ToString() == "true") 50 | { 51 | context.HttpContext.Response.Headers["Vary"] = "Accept"; 52 | context.HttpContext.Response.Headers["X-Inertia"] = "True"; 53 | await new ContentResult { Content = dataString, ContentType = "application/json" } 54 | .ExecuteResultAsync(context); 55 | return; 56 | } 57 | } 58 | 59 | _viewData["Data"] = dataString; 60 | 61 | ViewResult render = new ViewResult 62 | { 63 | ViewName = "inertia", 64 | ViewData = _viewData, 65 | TempData = _tempData 66 | }; 67 | 68 | await render.ExecuteResultAsync(context); 69 | } 70 | } 71 | } --------------------------------------------------------------------------------