Hi Anjali_Musmade,
Thanks for your reply, it is useful, the event of button works fine now.
But how to invoke method of IndexModel.Handle(Index.cshtml.cs) from index.js?
OK, there are my codes
Index.cshtml
@page
@using Microsoft.AspNetCore.Authorization
@using Volo.Abp.AspNetCore.Mvc.UI.Layout
@using Microsoft.AspNetCore.Mvc.Localization
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using XTC.BaaSo.ProductService.Localization
@using XTC.BaaSo.ProductService.Web.Menus
@using XTC.BaaSo.ProductService.Web.Pages.Products
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Card
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Form
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Grid
@using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Table
@using Volo.Abp.AspNetCore.Mvc.UI.Bundling.TagHelpers
@using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Pages.Shared.Components.AbpPageToolbar
@inject IHtmlLocalizer<ProductServiceResource> L
@inject IAuthorizationService Authorization
@model XTC.BaaSo.ProductService.Web.Pages.Products.IndexModel
@inject IPageLayout PageLayout
@{
PageLayout.Content.Title = L["Products"].Value;
PageLayout.Content.MenuItemName = ProductServiceMenus.Products;
}
@section scripts
{
<abp-script src="/Pages/Products/index.js" />
}
@section content_toolbar {
@await Component.InvokeAsync(typeof(AbpPageToolbarViewComponent), new { pageName = typeof(IndexModel).FullName })
}
<abp-card>
<abp-card-body>
<abp-row class="mb-3">
<abp-column size-md="_12">
<form id="SearchForm" autocomplete="off">
<div class="input-group">
<input class="form-control" id="FilterText" placeholder="@L["Search"]"/>
<abp-button button-type="Primary" type="submit" icon="search"/>
</div>
</form>
</abp-column>
<abp-column size-md="_12" class="mt-3">
<a href="javascript:;" id="AdvancedFilterSectionToggler">@L["SeeAdvancedFilters"]</a>
</abp-column>
</abp-row>
<abp-row id="AdvancedFilterSection" style="display: none;">
<abp-column size="_3">
<abp-input asp-for="NameFilter" label="@L["Name"].Value" />
</abp-column>
<abp-column size="_3">
<abp-input asp-for="PriceFilterMin" label="@L["MinPrice"].Value" />
</abp-column>
<abp-column size="_3">
<abp-input asp-for="PriceFilterMax" label="@L["MaxPrice"].Value" />
</abp-column>
</abp-row>
<abp-table striped-rows="true" id="ProductsTable">
<thead>
<tr>
<th>@L["Name"]</th>
<th>@L["Price"]</th>
<th></th>
<th>@L["Actions"]</th>
</tr>
</thead>
</abp-table>
</abp-card-body>
</abp-card>
Index.cshtml.cs
namespace XTC.BaaSo.ProductService.Web.Pages.Products;
public class IndexModel : ProductServicePageModel
{
public string NameFilter { get; set; }
public float? PriceFilterMin { get; set; }
public float? PriceFilterMax { get; set; }
//TODO invoke this method in javascript
public void Handle()
{
}
}
index.js
$(function () {
var l = abp.localization.getResource("ProductService");
var productService = window.xTC.baaSo.productService.products.product;
var createModal = new abp.ModalManager({
viewUrl: abp.appPath + "Products/CreateModal"
});
var editModal = new abp.ModalManager({
viewUrl: abp.appPath + "Products/EditModal"
});
var getFilter = function() {
return {
filterText: $("#FilterText").val(),
name: $("#NameFilter").val(),
priceMin: $("#PriceFilterMin").val(),
priceMax: $("#PriceFilterMax").val()
};
};
var dataTable = $("#ProductsTable").DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
scrollX: true,
autoWidth: false,
scrollCollapse: true,
order: [[1, "asc"]],
ajax: abp.libs.datatables.createAjax(productService.getList, getFilter),
columnDefs: [
{
{ data: "name" },
{ data: "price" },
{
//TODO 1
render: function (data) {
return '<button type="button" class="btn btn-outline-primary"></button>';
}
},
rowAction: {
items:
[
{
text: l("Browse"),
visible: true,
action: function (data) {
console.log(data.record.id);
//TODO 2
}
},
{
text: l("Edit"),
visible: abp.auth.isGranted('ProductService.Products.Edit'),
action: function (data) {
editModal.open({
id: data.record.id
});
}
},
{
text: l("Delete"),
visible: abp.auth.isGranted('ProductService.Products.Delete'),
confirmMessage: function () {
return l("DeleteConfirmationMessage");
},
action: function (data) {
productService.delete(data.record.id)
.then(function () {
abp.notify.info(l("SuccessfullyDeleted"));
dataTable.ajax.reloadEx();
});
}
}
]
}
}
]
}));
createModal.onResult(function () {
dataTable.ajax.reloadEx();
});
editModal.onResult(function () {
dataTable.ajax.reloadEx();
});
$('#AbpContentToolbar button[name=CreateProduct]').click(function (e) {
e.preventDefault();
createModal.open();
});
$("#SearchForm").submit(function (e) {
e.preventDefault();
dataTable.ajax.reloadEx();
});
$('#AdvancedFilterSectionToggler').on('click', function (e) {
$('#AdvancedFilterSection').toggle();
});
$('#AdvancedFilterSection').on('keypress', function (e) {
if (e.which === 13) {
dataTable.ajax.reloadEx();
}
});
$('#AdvancedFilterSection select').change(function() {
dataTable.ajax.reloadEx();
});
});
By the way, I use the microservice-pro, this is my command:
abp new XTC.MyTest -t microservice-pro -u mvc --version 7.3.2
Check the docs before asking a question: https://docs.abp.io/en/commercial/latest/ Check the samples to see the basic tasks: https://docs.abp.io/en/commercial/latest/samples/index The exact solution to your question may have been answered before, and please first use the search on the homepage. Provide us with the following info:
I use the MVC ui, in MyServiceWeb/Pages/Product/index.js, i want to implement two functions, TODO 1 and TODO 2:
var dataTable = $("#ProductTable").DataTable(abp.libs.datatables.normalizeConfiguration({
processing: true,
serverSide: true,
paging: true,
searching: false,
scrollX: true,
autoWidth: false,
scrollCollapse: true,
order: [[0, "asc"]],
ajax: abp.libs.datatables.createAjax(productSpace.getList, getFilter),
columnDefs: [
{ data: "name" },
{ data: "spaceKey" },
{
//TODO 1
render: function (data) {
return '<button type="button" class="btn btn-outline-primary"></button>';
}
},
{
rowAction: {
items:
[
{
text: l("Browse"),
visible: true,
action: function (data) {
console.log(data.record.id);
//TODO 2
}
},
{
text: l("Edit"),
visible: abp.auth.isGranted('XTC.LicenseService.Space.Edit'),
action: function (data) {
editModal.open({
id: data.record.id
});
}
},
{
text: l("Delete"),
visible: abp.auth.isGranted('XTC.LicenseService.Space.Delete'),
confirmMessage: function () {
return l("DeleteConfirmationMessage");
},
action: function (data) {
abp.notify.error(l("NotSupportDeleteFromWeb"));
return;
serviceSpace.delete(data.record.id)
.then(function () {
abp.notify.info(l("SuccessfullyDeleted"));
dataTable.ajax.reloadEx();
});
}
}
]
}
}
]
}));
and my MyServiceWeb/Pages/Product/Index.cshtml.cs like this :
public class IndexModel : LicenseServicePageModel
{
public string NameFilter { get; set; }
public void Handle() {}
}
At //TODO 1 How to add click event for button in table? I saw the https://docs.abp.io/en/abp/latest/UI/AspNetCore/Tag-Helpers/Buttons, but nothing found.
At //TODO 2 How to invoke the IndexModel.Handle() ?
I download the source code of leptonx-demo. but only found some html files.
I use the MVC UI, hope to see how to implement some samples at https://x.leptontheme.com/side-menu, for example https://x.leptontheme.com/side-menu/login-pages/login-2.
Is there a document or source code explain to how to implement components with MVC UI about https://x.leptontheme.com/side-menu?
I saw the https://docs.abp.io/en/commercial/latest/themes/lepton-x/mvc, but nothing about apb-card, abp-table etc.
Our main users are school students, In the teaching phase, the number of users is very large, I noticed the Team/Business/Enterprise only include 3 developer seats. So it's a bit impractical to make each student purchase a license or allocate our developer seats.
We love the many features of abp commercial and include them in our platform. We hope that students will also have the opportunity to use them in their practice.
Whether client can use LeptonX-Lite to develop libraries without login into abp account, auto upgrade it to LeptonX when building and integration in our platform? Or do you have any good suggestions?
I am using the apb commercial to build a cloud project, and use the microservice-pro template. I plan to provide users with an SDK to develop standalone microservices to access our platform.
But I notice LeptonX-pro libraries need commercial license, need login into abp account. So is there a way for users without logging into the ABP account when developing? Or do we provide a project file with license(appsettings.secret.json) for the user to use?
Hi maliming,
Thanks for reply, Around your prompt, I resolved this issue.
abp generate-proxy -t csharp -u https://localhost:44361/ -m vendorService
, and delete files that differ from the ProductService sample and manual modify the VendorService-generate-proxy.json.
resolve: add --without-contracts
and don't make any modifications.context.Services.AddStaticHttpClientProxies
,but the new project, use the context.Services.AddHttpClientProxies
resolve: manual modify context.Services.AddHttpClientProxies
to context.Services.AddStaticHttpClientProxies
in my new service[09:12:19 ERR] ---------- RemoteServiceErrorInfo ---------- { "code": null, "message": "对不起,在处理你的请求期间,产生了一个服务器内部错误!", "details": null, "data": {}, "validationErrors": null }
[09:12:19 ERR] Could not found remote action for method: System.Threading.Tasks.Task1[XTC.BaaSo.VendorService.Vendors.VendorDTO] CreateAsync(XTC.BaaSo.VendorService.Vendors.VendorCreateDTO) on the URL: https://localhost:44380 Volo.Abp.AbpException: Could not found remote action for method: System.Threading.Tasks.Task
1[XTC.BaaSo.VendorService.Vendors.VendorDTO] CreateAsync(XTC.BaaSo.VendorService.Vendors.VendorCreateDTO) on the URL: https://localhost:44380
at Volo.Abp.Http.Client.DynamicProxying.ApiDescriptionFinder.FindActionAsync(HttpClient client, String baseUrl, Type serviceType, MethodInfo method)
at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor1.GetActionApiDescriptionModel(IAbpMethodInvocation invocation) at Volo.Abp.Http.Client.DynamicProxying.DynamicHttpProxyInterceptor
1.InterceptAsync(IAbpMethodInvocation invocation)
at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func
3 proceed)
at Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo)
at Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Validation.ValidationInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter
1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func`3 proceed)
at XTC.BaaSo.VendorService.Web.Pages.Vendors.CreateModalModel.OnPostAsync() in E:\github\BaaSo\BaaSo-Cloud\vs2022\services\vendor\src\XTC.BaaSo.VendorService.Web\Pages\Vendors\CreateModal.cshtml.cs:line 28
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Convert[T](Object taskAsObject)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.GenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.InvokeHandlerMethodAsync()
I found create the product, log like this:
[09:10:04 INF] Executing handler method XTC.BaaSo.ProductService.Web.Pages.Products.CreateModalModel.OnPostAsync - ModelState is Valid
[09:10:04 INF] Start processing HTTP request POST https://localhost:44380/api/product-service/products?api-version=1.0
but create the vendor, log like this:
[09:12:19 INF] Executing handler method XTC.BaaSo.VendorService.Web.Pages.Vendors.CreateModalModel.OnPostAsync - ModelState is Valid
[09:12:19 ERR] ---------- RemoteServiceErrorInfo ----------
{
"code": null,
"message": "对不起,在处理你的请求期间,产生了一个服务器内部错误!",
"details": null,
"data": {},
"validationErrors": null
}
[09:12:19 ERR] Could not found remote action for method: System.Threading.Tasks.Task`1[XTC.BaaSo.VendorService.Vendors.VendorDTO] CreateAsync(XTC.BaaSo.VendorService.Vendors.VendorCreateDTO) on the URL: https://localhost:44380
so i called the /api/vendor-service/vendors use swagger of WebGateway, select the VendorService definition, and i got right response. request:
curl -X 'POST' \
'https://localhost:44361/api/vendor-service/vendors' \
-H 'accept: text/plain' \
-H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjBGREU3QzJGNDhDQjlGMEIzMUQ1NDVBRkVEOTdEQzU2RkJFODhBNEYiLCJ4NXQiOiJEOTU4TDBqTG53c3gxVVd2N1pmY1Z2dm9pazgiLCJ0eXAiOiJhdCtqd3QifQ.eyJzdWIiOiIzYTBkN2E5Yi1lYzM3LTkyM2EtZmI3MC1kNzMwMGJkN2JmYWMiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AYWJwLmlvIiwicm9sZSI6ImFkbWluIiwiZ2l2ZW5fbmFtZSI6ImFkbWluIiwicGhvbmVfbnVtYmVyX3ZlcmlmaWVkIjoiRmFsc2UiLCJlbWFpbF92ZXJpZmllZCI6IkZhbHNlIiwidW5pcXVlX25hbWUiOiJhZG1pbiIsIm9pX3Byc3QiOiJXZWJHYXRld2F5X1N3YWdnZXIiLCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo0NDMwMC8iLCJvaV9hdV9pZCI6IjNhMGQ3YWM2LTJhYTctYjYzNC1mOWQ1LTVkYWJjYmFiZGU1OSIsImNsaWVudF9pZCI6IldlYkdhdGV3YXlfU3dhZ2dlciIsIm9pX3Rrbl9pZCI6IjNhMGQ3YWM2LTJiODQtYTAxNy1jZWZhLTM5M2M3YmI4NWY4MiIsImF1ZCI6IkJ1c2luZXNzVW5pdCIsInNjb3BlIjoiQnVzaW5lc3NVbml0IiwianRpIjoiYzIxYzZiYjAtMDdmMS00YmYzLWI0NzAtZTFjYzE4ZTcyYzBjIiwiZXhwIjoxNjkzOTc1NTkzLCJpYXQiOjE2OTM5NzE5OTN9.PS6Xhh6nNCTaSPUgcbxFoiStaUYCaAd2ZhjqgmaNdjLOSyxJMK3O147OmyibuQD9wepRzDeF2jgrFE0GaOrCiZfek6ceAJvA0OiF6rdgEBoqR-XXsPqnBFxX8EWqmb8zCXYbSks9ISvin3XEV0skLF9slS5ET4rntZpU1Mu6psP1jcKmHZSNalTmrkXD6bJtD5JwXef-JHxXCl4ygS0V1B_n-Fl4t8IfPB5VbStDfVxds-VzzxUDn2oSl3MID3SZOCQJ8otCUoGBeLKcN9x4zNT2VeGHxesFf2_T3iYytrfOkWiRwM8yT5UihrNq14wij5OOvf59gT7kXB_EkEkxzw' \
-H 'Content-Type: application/json' \
-H 'RequestVerificationToken: CfDJ8Fdcgn1lYTlCsW6eEpOaA4s_uqelPSN0IxCtuE8ANzKwx7JkcMAyqWbhFlthOb8YSSDcTUfC80W-_XAEhHWTtXgFYZxGzs4vFrHYeK4cYXOyYCpaxz1TmhLYysNJej40NnrtND8RbzLSEtV4fEqjGNnWnojawoE3ku7o6ry_NxewHMOXbScIYORK3Z6H90zZfA' \
-H 'X-Requested-With: XMLHttpRequest' \
-d '{
"name": "test",
"display": "test1"
}'
response:
{
"name": "test",
"display": "test1",
"isDeleted": false,
"deleterId": null,
"deletionTime": null,
"lastModificationTime": null,
"lastModifierId": null,
"creationTime": "2023-09-06T11:46:50.1886199+08:00",
"creatorId": "3a0d7a9b-ec37-923a-fb70-d7300bd7bfac",
"id": "3a0d7ac6-6cb2-ed66-2de7-f138c7897eed",
"extraProperties": {}
}
and i called the /api/vendor-service/vendors use curl, i got right response too.
request:
curl --location 'https://localhost:44380/api/vendor-service/vendors' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6IjBGREU3QzJGNDhDQjlGMEIzMUQ1NDVBRkVEOTdEQzU2RkJFODhBNEYiLCJ4NXQiOiJEOTU4TDBqTG53c3gxVVd2N1pmY1Z2dm9pazgiLCJ0eXAiOiJhdCtqd3QifQ.eyJzdWIiOiIzYTBkN2E5Yi1lYzM3LTkyM2EtZmI3MC1kNzMwMGJkN2JmYWMiLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJhZG1pbiIsImVtYWlsIjoiYWRtaW5AYWJwLmlvIiwicm9sZSI6ImFkbWluIiwiZ2l2ZW5fbmFtZSI6ImFkbWluIiwicGhvbmVfbnVtYmVyX3ZlcmlmaWVkIjoiRmFsc2UiLCJlbWFpbF92ZXJpZmllZCI6IkZhbHNlIiwidW5pcXVlX25hbWUiOiJhZG1pbiIsIm9pX3Byc3QiOiJXZWJHYXRld2F5X1N3YWdnZXIiLCJpc3MiOiJodHRwczovL2xvY2FsaG9zdDo0NDMwMC8iLCJvaV9hdV9pZCI6IjNhMGQ3YWM2LTJhYTctYjYzNC1mOWQ1LTVkYWJjYmFiZGU1OSIsImNsaWVudF9pZCI6IldlYkdhdGV3YXlfU3dhZ2dlciIsIm9pX3Rrbl9pZCI6IjNhMGQ3YWM2LTJiODQtYTAxNy1jZWZhLTM5M2M3YmI4NWY4MiIsImF1ZCI6IkJ1c2luZXNzVW5pdCIsInNjb3BlIjoiQnVzaW5lc3NVbml0IiwianRpIjoiYzIxYzZiYjAtMDdmMS00YmYzLWI0NzAtZTFjYzE4ZTcyYzBjIiwiZXhwIjoxNjkzOTc1NTkzLCJpYXQiOjE2OTM5NzE5OTN9.PS6Xhh6nNCTaSPUgcbxFoiStaUYCaAd2ZhjqgmaNdjLOSyxJMK3O147OmyibuQD9wepRzDeF2jgrFE0GaOrCiZfek6ceAJvA0OiF6rdgEBoqR-XXsPqnBFxX8EWqmb8zCXYbSks9ISvin3XEV0skLF9slS5ET4rntZpU1Mu6psP1jcKmHZSNalTmrkXD6bJtD5JwXef-JHxXCl4ygS0V1B_n-Fl4t8IfPB5VbStDfVxds-VzzxUDn2oSl3MID3SZOCQJ8otCUoGBeLKcN9x4zNT2VeGHxesFf2_T3iYytrfOkWiRwM8yT5UihrNq14wij5OOvf59gT7kXB_EkEkxzw' \
--data '{
"name": "3",
"display": "33333"
}'
response:
{
"name": "3",
"display": "33333",
"isDeleted": false,
"deleterId": null,
"deletionTime": null,
"lastModificationTime": null,
"lastModifierId": null,
"creationTime": "2023-09-06T11:56:52.4975455+08:00",
"creatorId": "3a0d7a9b-ec37-923a-fb70-d7300bd7bfac",
"id": "3a0d7acf-9d7e-0127-1efa-a46a51918906",
"extraProperties": {}
}
so how can i resolve this error? thanks.