Activities of "Leonardo.Willrich"

  • ABP Framework version: v4.2.2
  • UI type: Angular / MVC / Blazor
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes / no
  • Exception message and stack trace:
  • Steps to reproduce the issue:

Hi,

I am using Telerik components in my project and I am trying to use a Server Filtering. To be able to do that, I need to send a parameter from Blazor side to Application Service to filter/sort/group my records as per the grid parameters.

It is working fine, but, when I add some filter, it is raising an exception on Blazor side before calling the method in the Application Service. I am struggling to understand what is wrong with that.

Here is the error in the console:

My Application Service:

 [HttpPost]
public async Task<DataEnvelope<OutageReportDto>> GetOutageReportList([FromBody] DataSourceRequest request)
{
    try
    {
        var time = DateTime.UtcNow.AddDays(-1);
        var outageList = _outageReportRepository
            .Include(x => x.SupplyNetwork).Include(x => x.Cause)
            .Where(x => x.TenantId == CurrentTenant.Id.Value)
            .Where(x => x.RecordedTime >= time)
            .Select(x => ObjectMapper.Map<OutageReport, OutageReportDto>(x)).ToList();

        var output = await outageList.ToDataSourceResultAsync(request);

        DataEnvelope<OutageReportDto> dataToReturn;

        if (request.Groups != null && request.Groups.Count > 0)
        {
            // If there is grouping, use the field for grouped data
            // The app must be able to serialize and deserialize it
            // Example helper methods for this are available in this project
            // See the GroupDataHelper.DeserializeGroups and JsonExtensions.Deserialize methods
            dataToReturn = new DataEnvelope<OutageReportDto>
            {
                GroupedData = output.Data.Cast<AggregateFunctionsGroup>().ToList(),
                TotalItemCount = output.Total
            };
        }
        else
        {
            // When there is no grouping, the simplistic approach of 
            // just serializing and deserializing the flat data is enough
            dataToReturn = new DataEnvelope<OutageReportDto>
            {
                CurrentPageData = output.Data.Cast<OutageReportDto>().ToList(),
                TotalItemCount = output.Total
            };
        }

        return dataToReturn;
    }
    catch (Exception ex)
    {
        Console.WriteLine("Error: ", ex.Message);
        Console.WriteLine(ex);
        throw;
    }
}

My Blazor page code behind code:

using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using Telerik.Blazor.Components;
using Telerik.DataSource;
using TVD_Holdings_Ltd.AvalancheOCP.AOR.OutageReports;

namespace TVD_Holdings_Ltd.AvalancheOCP.Blazor.Pages.AOR
{
    public class OutageReportGridBase : ComponentBase
    {
        [Inject] IOutageReportAppService outageReportService { get; set; }
        
        [Inject] IConfiguration Configuration { get; set; }
        [Inject] HttpClient httpClient { get; set; }
        //
        protected TelerikGrid<object> MainGrid { get; set; }
        protected List<object> OutageReportList { get; set; }
        protected int Total { get; set; }
        //
        private HubConnection hubConnection;
        private DataSourceRequest LastRequest;
        

        protected override async Task OnInitializedAsync()
        {
            var baseUrl = Configuration.GetValue<string>("RemoteServices:Default:BaseUrl");
            hubConnection = new HubConnectionBuilder()
           .WithUrl(baseUrl + "/aor")
           .Build();

            hubConnection.On("OutagesUpdated", LoadData);

            await hubConnection.StartAsync();
        }

        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                await SetGridDefaultSort();
            }
            await base.OnAfterRenderAsync(firstRender);
        }

        private async Task SetGridDefaultSort()
        {
            GridState<object> desiredState = new GridState<object>()
            {
                SortDescriptors = new List<SortDescriptor>()
            {
                new SortDescriptor { Member = nameof(OutageReportDto.RecordedTime), SortDirection = ListSortDirection.Descending }
            }
            };

            await MainGrid.SetState(desiredState);
        }

        private async Task LoadData()
        {
            var result = await outageReportService.GetOutageReportList(LastRequest);

            if (LastRequest.Groups.Count > 0)
            {
                var data = GroupDataHelpers.DeserializeGroups<OutageReportDto>(result.GroupedData);
                OutageReportList = data.Cast<object>().ToList();
            }
            else
            {
                OutageReportList = result.CurrentPageData.Cast<object>().ToList();
            }

            Total = result.TotalItemCount;

            StateHasChanged();
        }

        protected async Task OnReadHandler(GridReadEventArgs args)
        {
            LastRequest = args.Request;
            await LoadData();
        }

    }
}

And my Blazor Page:

@page "/outagereports"

@attribute [Authorize(AvalancheOCPPermissions.OutageReportsGrid.Default)]
@using TVD_Holdings_Ltd.AvalancheOCP.Permissions
@using Microsoft.AspNetCore.Authorization
@using TVD_Holdings_Ltd.AvalancheOCP.Localization
@using Microsoft.Extensions.Localization
@using TVD_Holdings_Ltd.AvalancheOCP.AOR.OutageReports;
@inject IStringLocalizer<AvalancheOCPResource> L
@inject AbpBlazorMessageLocalizerHelper<AvalancheOCPResource> LH
@inherits OutageReportGridBase

<Card>
    <CardHeader>
        <Row Class="justify-content-between">
            <Column ColumnSize="ColumnSize.IsAuto">
                <h2>@L["OutageReportGrid"]</h2>
            </Column>
        </Row>
    </CardHeader>
    <CardBody>
        <TelerikRootComponent>
            <TelerikGrid Data=@OutageReportList @ref="@MainGrid"
                         OnRead="@OnReadHandler" TotalCount=@Total
                         Sortable="true"
                         Groupable="true"
                         FilterMode="@GridFilterMode.FilterMenu"
                         Pageable="true" PageSize="50">
                <GridColumns>
                    <GridColumn Field="@nameof(OutageReportDto.SupplyNetworkName)" FieldType="@(typeof(string))" Title="@L["OutageReportGrid.SupplyNetworkName"]"/>
                    <GridColumn Field="@nameof(OutageReportDto.RecordedTime)" FieldType="@(typeof(DateTime))" Title="@L["OutageReportGrid.RecordedTime"]" DisplayFormat="{0:ddd dd-MMM-yyyy HH:mm}" />
                    <GridColumn Field="@nameof(OutageReportDto.CreationTime)" FieldType="@(typeof(DateTime))" Title="@L["OutageReportGrid.CreationTime"]" DisplayFormat="{0:ddd dd-MMM-yyyy HH:mm}"/>
                    <GridColumn Field="@nameof(OutageReportDto.NotifiedTime)" FieldType="@(typeof(DateTime?))" Title="@L["OutageReportGrid.NotifiedTime"]" DisplayFormat="{0:ddd dd-MMM-yyyy HH:mm}" />
                    <GridColumn Field="Location" FieldType="@(typeof(string))" Title="@L["OutageReportGrid.Location"]" />
                    <GridColumn Field="@nameof(OutageReportDto.Suburb)" FieldType="@(typeof(string))" Title="@L["OutageReportGrid.Suburb"]" />
                    <GridColumn Field="@nameof(OutageReportDto.CauseName)" FieldType="@(typeof(string))" Title="@L["OutageReportGrid.CauseName"]" />
                    <GridColumn Field="@nameof(OutageReportDto.ContactPhoneNumber)" FieldType="@(typeof(string))" Title="@L["OutageReportGrid.ContactPhoneNumber"]" />
                </GridColumns>
            </TelerikGrid>
        </TelerikRootComponent>
    </CardBody>
</Card>

Hi,

I have removed WebDAVModule and not it is working. Also, I've done changes as image below:

source: https://stackoverflow.com/questions/12440277/how-do-i-enable-http-put-and-delete-for-asp-net-mvc-in-iis

My new Web.Config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
			<modules>
				<remove name="WebDAVModule" />
			</modules>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
				<remove name="WebDAV" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\TVD_Holdings_Ltd.AvalancheOCP.HttpApi.Host.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
    </system.webServer>
  </location>
</configuration>
<!--ProjectGuid: 96e5259e-59a3-4faf-bcd1-5bf8e74ef82c-->
  • ABP Framework version: v4.2.2
  • UI type: Blazor
  • DB provider: EF Core / MongoDB
  • Tiered (MVC) or Identity Server Separated (Angular): yes / no
  • Exception message and stack trace:
  • Steps to reproduce the issue:

Hi,

In my local machine all CRUD operations work fine. But, when I deploy to IIS Server the Update and Delete don't work.

I've tried to remove WebDAV in the Web.Config, but still getting errors. My Web.Config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
				<remove name="WebDAV" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\TVD_Holdings_Ltd.AvalancheOCP.HttpApi.Host.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="InProcess" />
    </system.webServer>
  </location>
</configuration>
<!--ProjectGuid: 96e5259e-59a3-4faf-bcd1-5bf8e74ef82c-->

In the console I am getting these messages:

What should I change in my config to make it work?

  • ABP Framework version: v4.2.2
  • UI type: Blazor
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes / no
  • Exception message and stack trace:
  • Steps to reproduce the issue:

Hi,

I'd like to know how to perform orderby passing a string as parameter when I have two tables connect by join in the method GetListAsync in a CrudAppService class.

In the Tutorial, Item 10. Book and Author Relation, in the method GetListAsync we have this comment:

orderby input.Sorting //TODO: Can not sort like that!

In AspNetZero project I have an extension for OrderBy and PageBy that make life easy. But, I haven't found those extensions for Abp.IO Blazor UI project.

Here is my code:

public override async Task<PagedResultDto<SupplyNetworkDto>> GetListAsync(PagedAndSortedResultRequestDto input)
{
    //Set a default sorting, if not provided
    if (input.Sorting.IsNullOrEmpty())
    {
        input.Sorting = nameof(SupplyNetworkDto.Name);
    }

    //Get the IQueryable<Book> from the repository
    var queryable = await Repository.GetQueryableAsync();

    //Prepare a query to join books and authors
    var query = from supplyNetwork in queryable
                join networkType in _networkTypeRepository on supplyNetwork.NetworkTypeId equals networkType.Id
                orderby input.Sorting // It is not working as per example in ABP.IO Documentation Example
                select new { supplyNetwork, networkType };

    query = query
        .Skip(input.SkipCount)
        .Take(input.MaxResultCount);

    //Execute the query and get a list
    var queryResult = await AsyncExecuter.ToListAsync(query);

    //Convert the query result to a list of BookDto objects
    var dtos = queryResult.Select(x =>
    {
        var dto = ObjectMapper.Map<SupplyNetwork, SupplyNetworkDto>(x.supplyNetwork);
        dto.NetworkTypeName = x.networkType.Name;
        return dto;
    }).ToList();

    //Get the total count with another query
    var totalCount = await Repository.GetCountAsync();

    return new PagedResultDto<SupplyNetworkDto>(
        totalCount,
        dtos
    );
}

Hi,

I've found in the class PermissionDefinitionProvider a parameter for each permission that defines the multiTenancySide. Does that mean to define the menu as well?

public class AvalancheOCPPermissionDefinitionProvider : PermissionDefinitionProvider
    {
        public override void Define(IPermissionDefinitionContext context)
        {
            var myGroup = context.AddGroup(AvalancheOCPPermissions.GroupName);

            myGroup.AddPermission(AvalancheOCPPermissions.Dashboard.Host, L("Permission:Dashboard"), MultiTenancySides.Host);
            myGroup.AddPermission(AvalancheOCPPermissions.Dashboard.Tenant, L("Permission:Dashboard"), MultiTenancySides.Tenant);

            var settings = context.AddGroup(AvalancheOCPPermissions.AvalancheOCPSettings, L("Menu:AvalancheOCPSettings"), MultiTenancySides.Tenant);

            var causes = settings.AddPermission(AvalancheOCPPermissions.Causes.Default, L("Menu:Causes"), MultiTenancySides.Tenant);
            causes.AddChild(AvalancheOCPPermissions.Causes.Create, L("Permission:Causes.Create"), MultiTenancySides.Tenant);
            causes.AddChild(AvalancheOCPPermissions.Causes.Edit, L("Permission:Causes.Edit"), MultiTenancySides.Tenant);
            causes.AddChild(AvalancheOCPPermissions.Causes.Delete, L("Permission:Causes.Delete"), MultiTenancySides.Tenant);

            var supplyNetworks = settings.AddPermission(AvalancheOCPPermissions.SupplyNetworks.Default, L("Menu:SupplyNetworks"), MultiTenancySides.Tenant);
            supplyNetworks.AddChild(AvalancheOCPPermissions.SupplyNetworks.Create, L("Permission:SupplyNetworks.Create"), MultiTenancySides.Tenant);
            supplyNetworks.AddChild(AvalancheOCPPermissions.SupplyNetworks.Edit, L("Permission:SupplyNetworks.Edit"), MultiTenancySides.Tenant);
            supplyNetworks.AddChild(AvalancheOCPPermissions.SupplyNetworks.Delete, L("Permission:SupplyNetworks.Delete"), MultiTenancySides.Tenant);

            myGroup.AddPermission(AvalancheOCPPermissions.OutageReportsGrid.Default, L("Permission:OutageReportGrid"), MultiTenancySides.Tenant);

            //Define your own permissions here. Example:
            //myGroup.AddPermission(AvalancheOCPPermissions.MyPermission1, L("Permission:MyPermission1"));
        }

        private static LocalizableString L(string name)
        {
            return LocalizableString.Create<AvalancheOCPResource>(name);
        }
    }
  • ABP Framework version: v4.2.2
  • UI type: Blazor
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes / no
  • Exception message and stack trace:
  • Steps to reproduce the issue:

Hi, I have added two menus that should be visible only in the Tenant Side. I don't want then on the Host side. How can I do that?

I tried to inject CurrentTenant and check the property IsAvailable, but, the class is instanced manually and dependency injection doesn't work. See my code below:

public class AvalancheOCPMenuContributor : IMenuContributor
    {
        private readonly IConfiguration _configuration;

        public AvalancheOCPMenuContributor(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        public async Task ConfigureMenuAsync(MenuConfigurationContext context)
        {
            if (context.Menu.Name == StandardMenus.Main)
            {
                await ConfigureMainMenuAsync(context);
            }
            else if (context.Menu.Name == StandardMenus.User)
            {
                await ConfigureUserMenuAsync(context);
            }
        }

        //This method was intentionally "async" because ABP Suite will generate asnyc method calls here.
        private static async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
        {
            var l = context.GetLocalizer<AvalancheOCPResource>();

            context.Menu.AddItem(new ApplicationMenuItem(
                AvalancheOCPMenus.Home,
                l["Menu:Home"],
                "/",
                icon: "fas fa-home",
                order: 1
            ));

            // Tenant Side
            **//if (_currentTenant.IsAvailable) // How to do it? Or what is the best way to do that?**
            { 
                var settings = new ApplicationMenuItem(
                    "Settings",
                    l["Menu:AvalancheOCPSettings"],
                    icon: "fa fa-sliders",
                    order: 2
                );
                context.Menu.AddItem(settings);

                if (await context.IsGrantedAsync(AvalancheOCPPermissions.Causes.Default))
                {
                    settings.AddItem(new ApplicationMenuItem(
                        "Settings.Causes",
                        l["Menu:Causes"],
                        url: "/causes"
                    ));
                }

                if (await context.IsGrantedAsync(AvalancheOCPPermissions.SupplyNetworks.Default))
                {
                    settings.AddItem(new ApplicationMenuItem(
                        "Settings.SupplyNetworks",
                        l["Menu:SupplyNetworks"],
                        url: "/supplynetworks"
                    ));
                }
            }

Ok, I got it. Thank you!

Thank you for your answer.

That works fine when I am adding a new entity. When editing, it doesn't work, the Save button is disabled by default. I just have created a new OnStatusChanged method for editing adding the option None. See below the new method:

protected Task OnStatusChangedEditing(ValidationsStatusChangedEventArgs eventArgs)
{
    saveDisabled = eventArgs.Status != ValidationStatus.None && eventArgs.Status != ValidationStatus.Success;
    return Task.CompletedTask;
}
  • ABP Framework version: v4.2.2
  • UI type: Angular / MVC / Blazor
  • DB provider: EF Core / MongoDB
  • Tiered (MVC) or Identity Server Separated (Angular): yes / no
  • Exception message and stack trace:
  • Steps to reproduce the issue:

Hi, I am implemeting my first CRUD using AbpCrudPageBase class. I have two questions about that:

  1. Is it allways required having two MODAL markup and repeat the fields? If the Create and Edit modal are exactly the same, do I need to repeat that?

  2. In events onChange, I have two variables, NewEntity and EditingEntity. How I know if I am editing or creating a new record? The only way that I've found to resolve that was creating two different events and then duplicating code or creating a third method and pass the EntityDto as parameter.

For example, to load an image in the event <FileEdit Changed="">, I did the code below. Is there a better way to do that?

protected async Task OnChangedLogoNew(FileChangedEventArgs e)
{
    await ChangedLogo(e, NewEntity);
}

protected async Task OnChangedLogoEditing(FileChangedEventArgs e)
{
    await ChangedLogo(e, EditingEntity);
}

protected async Task ChangedLogo(FileChangedEventArgs e, CreateUpdateSupplyNetworkDto currentDto)
{
    try
    {
        foreach (var file in e.Files)
        {
            // A stream is going to be the destination stream we're writing to.
            using (var stream = new MemoryStream())
            {
                await file.WriteToStreamAsync(stream);
                stream.Seek(0, SeekOrigin.Begin);
                currentDto.Logo = stream.ToArray();
            }
        }
    }
    catch (Exception exc)
    {
        Console.WriteLine(exc.Message);
    }
    finally
    {
        this.StateHasChanged();
    }
}
Answer

Thank you very much! That works fine for me. I didn't notice that part of documents for ABP Framework > UI > Blazor before.

Showing 171 to 180 of 192 entries
Boost Your Development
ABP Live Training
Packages
See Trainings
Mastering ABP Framework Book
The Official Guide
Mastering
ABP Framework
Learn More
Mastering ABP Framework Book
Made with ❤️ on ABP v10.1.0-preview. Updated on December 17, 2025, 07:08
1
ABP Assistant
🔐 You need to be logged in to use the chatbot. Please log in first.