Activities of "niall"

Answer

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?

Answer

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
Question

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:

  • ABP Framework version: v7.3.2
  • UI Type: MVC
  • Database System: EF Core (MySQL)
  • Tiered (for MVC) or Auth Server Separated (for Angular): yes

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.

  1. I use 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.
  2. ProductServiceHttpApiClientModule use the 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
  • ABP Framework version: v7.3.2
  • UI Type: MVC
  • Database System: EF Core ( MySQ)
  • Tiered (for MVC) or Auth Server Separated (for Angular): no
  • Exception message and full stack trace:

[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.Task1[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.DynamicHttpProxyInterceptor1.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation invocation, IInvocationProceedInfo proceedInfo, Func3 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.CastleAsyncAbpInterceptorAdapter1.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()

  • Steps to reproduce the issue:
  1. I created a microservice-pro
  2. Follow the ProductService sample to implement my new service VendorService.
  3. generated the clientproxy and migration database.
  4. Run the AuthServer, IdentityService, AdministrationServicce, SaasService, ProducService, VendorService(https://localhost:44361), WebGateway(https://localhost:44380), Web(https://localhost:44381)
  5. GetList, Create, Update, Delete of the ProductService works fine at Web(https://localhost:44381)
  6. GetList of the VendorService works fine and return items at Web(https://localhost:44381), but Create throw the CreateAsync Exception

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.

Showing 71 to 78 of 78 entries
Made with ❤️ on ABP v9.0.0-preview Updated on September 19, 2024, 10:13