From 3bca423fcc16bc19f0a2e20bfce480a8d1d4ccbf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 12 Mar 2020 15:39:03 +0300 Subject: [PATCH] Completed "Overriding a Page" section. --- docs/en/Modules/Account.md | 3 + .../Customization-User-Interface.md | 89 +++++++++++++++++- docs/en/images/overriding-login-cshtml.png | Bin 0 -> 4655 bytes 3 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 docs/en/Modules/Account.md create mode 100644 docs/en/images/overriding-login-cshtml.png diff --git a/docs/en/Modules/Account.md b/docs/en/Modules/Account.md new file mode 100644 index 0000000000..6901b38f59 --- /dev/null +++ b/docs/en/Modules/Account.md @@ -0,0 +1,3 @@ +# Account Module + +TODO \ No newline at end of file diff --git a/docs/en/UI/AspNetCore/Customization-User-Interface.md b/docs/en/UI/AspNetCore/Customization-User-Interface.md index ce50141ac0..b6901dcd5e 100644 --- a/docs/en/UI/AspNetCore/Customization-User-Interface.md +++ b/docs/en/UI/AspNetCore/Customization-User-Interface.md @@ -2,7 +2,17 @@ This document explains how to override the user interface of a depended [application module](../../Modules/Index.md) for ASP.NET Core MVC / Razor Page applications. -## Overriding a Page Model +## Overriding a Page + +This section covers the [Razor Pages](https://docs.microsoft.com/en-us/aspnet/core/razor-pages/) development, which is the recommended approach to create server rendered user interface for ASP.NET Core. Pre-built modules typically uses the Razor Pages approach instead of the classic MVC pattern (next sections will cover the MVC pattern too). + +You typically have three kind of override requirement for a page: + +* Overriding **only the Page Model** (C#) side to perform additional logic without changing the page UI. +* Overring **only the Razor Page** (.chtml file) to change the UI without changing the c# behind the page. +* **Completely overriding** the page. + +### Overriding a Page Model (C#) ````csharp using System.Threading.Tasks; @@ -36,5 +46,80 @@ namespace Acme.BookStore.Web.Pages.Identity.Users } ```` -This class replaces `EditModalModel` for the users and overrides the `OnPostAsync` method. +* This class inherits from and replaces the `EditModalModel` for the users and overrides the `OnPostAsync` method to perform additional logic before and after the underlying code. +* It uses `ExposeServices` and `Dependency` attributes to replace the class. + +### Overriding a Razor Page (.CSHTML) + +Overriding a `.cshtml` file (razor page, razor view, view component... etc.) is possible through the [Virtual File System](../../Virtual-File-System.md). + +Virtual File system allows us to **embed resources into assemblies**. In this way, pre-built modules define the razor pages inside their NuGet packages. When you depend a module, you can override any file added to the virtual file system by that module, including pages/views. + +#### Example + +This example overrides the **login page** UI defined by the [Account Module](../../Modules/Account.md). + +Physical files override the embedded files defined in the same location. The account module defines a `Login.cshtml` file under the `Pages/Account` folder. So, you can override it by creating a file in the same path: + +![overriding-login-cshtml](../../images/overriding-login-cshtml.png) + +You typically want to copy the original `.cshtml` file of the module, then make the necessary changes. You can find the original file [here](https://github.com/abpframework/abp/blob/dev/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Login.cshtml). Do not copy the `Login.cshtml.cs` file which is the code behind file for the razor page and we don't want to override it yet (see the next section). + +That's all, you can change the file content however you like. + +### Completely Overriding a Razor Page + +You may want to completely override a page; the razor and the c# file related to the page. + +In such a case; + +1. Override the C# page model class just like described above, but don't replace the existing page model class. +2. Override the Razor Page just described above, but also change the @model directive to point your new page model. + +#### Example + +This example overrides the **login page** defined by the [Account Module](../../Modules/Account.md). + +Create a page model class deriving from the ` LoginModel ` (defined in the ` Volo.Abp.Account.Web.Pages.Account ` namespace): + +````csharp +public class MyLoginModel : LoginModel +{ + public MyLoginModel( + IAuthenticationSchemeProvider schemeProvider, + IOptions accountOptions + ) : base( + schemeProvider, + accountOptions) + { + + } + + public override Task OnPostAsync(string action) + { + //TODO: Add logic + return base.OnPostAsync(action); + } + + //TODO: Add new methods and properties... +} +```` + +You can override any method or add new properties/methods if needed. + +> Notice that we didn't use `[Dependency(ReplaceServices = true)]` or `[ExposeServices(typeof(LoginModel))]` since we don't want to replace the existing class in the dependency injection, we define a new one. + +Copy `Login.cshtml` file into your solution as just described above. Change the **@model** directive to point to the `MyLoginModel`: + +````xml +@page +... +@model Acme.BookStore.Web.Pages.Account.MyLoginModel +... +```` + +That's all! Make any change in the view and run your application. + +#### Replacing Page Model Without Inheritance +You don't have to inherit from the original page model class (like done in the previous example). Instead, you can completely re-implement the page yourself. In this case, just derive from `PageModel`, `AbpPageModel` or any suitable base class you need. \ No newline at end of file diff --git a/docs/en/images/overriding-login-cshtml.png b/docs/en/images/overriding-login-cshtml.png new file mode 100644 index 0000000000000000000000000000000000000000..d6daa4a141f570b417163f8a9fe22ae19b9b7c36 GIT binary patch literal 4655 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 literal 0 HcmV?d00001