--- description: "ABP MVC and Razor Pages UI patterns" globs: - "**/*.cshtml" - "**/Pages/**/*.cs" - "**/Views/**/*.cs" - "**/Controllers/**/*.cs" alwaysApply: false --- # ABP MVC / Razor Pages UI > **Docs**: https://abp.io/docs/latest/framework/ui/mvc-razor-pages/overall ## Razor Page Model ```csharp public class IndexModel : AbpPageModel { private readonly IBookAppService _bookAppService; public List Books { get; set; } public IndexModel(IBookAppService bookAppService) { _bookAppService = bookAppService; } public async Task OnGetAsync() { var result = await _bookAppService.GetListAsync( new PagedAndSortedResultRequestDto() ); Books = result.Items.ToList(); } } ``` ## Razor Page View ```html @page @model IndexModel

@L["Books"]

@L["Name"] @L["Price"] @L["Actions"] @foreach (var book in Model.Books) { @book.Name @book.Price }
``` ## ABP Tag Helpers ### Cards ```html Header Content Footer ``` ### Buttons ```html ``` ### Forms ```html ``` ### Tables ```html ``` ## Localization ```html @* In Razor views/pages *@

@L["Books"]

@* With parameters *@

@L["WelcomeMessage", Model.UserName]

``` ## JavaScript API ```javascript // Localization var text = abp.localization.getResource('BookStore')('Books'); // Authorization if (abp.auth.isGranted('BookStore.Books.Create')) { // Show create button } // Settings var maxCount = abp.setting.get('BookStore.MaxItemCount'); // Ajax with automatic error handling abp.ajax({ url: '/api/app/book', type: 'POST', data: JSON.stringify(bookData) }).then(function(result) { // Success }); // Notifications abp.notify.success('Book created successfully!'); abp.notify.error('An error occurred!'); // Confirmation abp.message.confirm('Are you sure?').then(function(confirmed) { if (confirmed) { // User confirmed } }); ``` ## DataTables Integration ```javascript var dataTable = $('#BooksTable').DataTable( abp.libs.datatables.normalizeConfiguration({ serverSide: true, paging: true, ajax: abp.libs.datatables.createAjax(bookService.getList), columnDefs: [ { title: l('Name'), data: 'name' }, { title: l('Price'), data: 'price', render: function(data) { return data.toFixed(2); } }, { title: l('Actions'), rowAction: { items: [ { text: l('Edit'), visible: abp.auth.isGranted('BookStore.Books.Edit'), action: function(data) { editModal.open({ id: data.record.id }); } }, { text: l('Delete'), visible: abp.auth.isGranted('BookStore.Books.Delete'), confirmMessage: function(data) { return l('BookDeletionConfirmationMessage', data.record.name); }, action: function(data) { bookService.delete(data.record.id).then(function() { abp.notify.success(l('SuccessfullyDeleted')); dataTable.ajax.reload(); }); } } ] } } ] }) ); ``` ## Modal Pages **CreateModal.cshtml:** ```html @page @model CreateModalModel ``` **CreateModal.cshtml.cs:** ```csharp public class CreateModalModel : AbpPageModel { [BindProperty] public CreateBookDto Book { get; set; } private readonly IBookAppService _bookAppService; public CreateModalModel(IBookAppService bookAppService) { _bookAppService = bookAppService; } public async Task OnPostAsync() { await _bookAppService.CreateAsync(Book); return NoContent(); } } ``` ## Bundle & Minification ```csharp Configure(options => { options.StyleBundles.Configure( StandardBundles.Styles.Global, bundle => bundle.AddFiles("/styles/my-styles.css") ); }); ```