Activities of "hakan.uskaner"

  • ABP Framework version: v5.1.3
  • UI type: Blazor Server
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes

Hi , i am using Syncfusion Blazor Componentsto to handle upload and dowload like in this ApiController Code:

    [RemoteService]
    [Area("app")]
    [ControllerName("FileManager")]
    [Route("api/app/filemanager")]
    [IgnoreAntiforgeryToken]
    public class FileManagerController : AbpController, IFileManagerAppService
    {
    {
        // Processing the Download operation
        [Route("Download")]
        public IActionResult Download(string downloadInput)
        {
            //Invoking download operation with the required paramaters
            // path - Current path where the file is downloaded; Names - Files to be downloaded;
            FileManagerDirectoryContent args = JsonConvert.DeserializeObject<FileManagerDirectoryContent>(downloadInput);
            return operation.Download(args.Path, args.Names);
        }
  

       // Processing the Upload operation
        [Route("Upload")]
        public IActionResult Upload(string path, IList<IFormFile> uploadFiles, string action)
        {
            //Invoking upload operation with the required paramaters
            // path - Current path where the file is to uploaded; uploadFiles - Files to be uploaded; action - name of the operation(upload)
            FileManagerResponse uploadResponse;
            uploadResponse = operation.Upload(path, uploadFiles, action, null);
            if (uploadResponse.Error != null)
            {
                Response.Clear();
                Response.ContentType = "application/json; charset=utf-8";
                Response.StatusCode = Convert.ToInt32(uploadResponse.Error.Code);
                Response.HttpContext.Features.Get<IHttpResponseFeature>().ReasonPhrase = uploadResponse.Error.Message;
            }
            return Content("");
        }

}

Here all the work is done in the ApiController.

I want to be able to integrate that ApiCalls in an ApplicationService, so i can easly access it, from other Applicationservices and UI. Normally an ApiController just call the same method in Application Service, but this time it should be otherwise.

I tried this so far:

   public interface IFileManagerAppService : IApplicationService
   {
   
        Task<IActionResult> Download(string downloadInput);

        Task<IActionResult> Upload(string path, IList<IFormFile> uploadFiles, string action);

    }
    
    public class FileManagerAppService : ApplicationService , IFileManagerAppService
    {
        public FileManagerAppService()
        {
        }

	 How should i implement them here, if the work is done in apicontroller ?
         // Task<IActionResult> Download(string downloadInput)

         //Task<IActionResult> Upload(string path, IList<IFormFile> uploadFiles, string action)

         }

I doesn't seem to be a good way to implement all logic in appication layer, because its an lowlevel api, which also uses a physical Layer etc . A lot more is done in that layer. look here : https://blazor.syncfusion.com/documentation/file-manager/getting-started

So how can i solve this ? I would like to be to call these Method after injection at Blazor Client-side .

For thos who also searched around for this infos:

My solution for filtering properties and id now looks like this.:

   public static class QueryableExtensions
    {
        public static Expression<Func<T, T>> DynamicSelectGenerator<T>(string filterProperties)
        {
            string[] entityProperties;
            if (filterProperties.IsNullOrEmpty())

                // get Properties of the T
                entityProperties = typeof(T).GetProperties().Select(propertyInfo => propertyInfo.Name).ToArray();
            else
            {
                // at least Id must be include besides a property (Case sensitive !)
                if (!filterProperties.Contains("Id"))
                    filterProperties +=",Id";
                    
                entityProperties = filterProperties.Split(',');
            }

            // input parameter "o"
            var xParameter = Expression.Parameter(typeof(T), "o");

            // new statement like "new Data()"
            var xNew = Expression.New(typeof(T));

            // create initializers
            var bindings = entityProperties.Select(o => o.Trim())
                .Select(o =>
                {

                // property "Field1"
                var mi = typeof(T).GetProperty(o);

                // original value "o.Field1"
                var xOriginal = Expression.Property(xParameter, mi);

                // set value "Field1 = o.Field1"
                return Expression.Bind(mi, xOriginal);
                }
            );

            // initialization "new Data { Field1 = o.Field1, Field2 = o.Field2 }"
            var xInit = Expression.MemberInit(xNew, bindings);

            // expression "o => new Data { Field1 = o.Field1, Field2 = o.Field2 }"
            var lambda = Expression.Lambda<Func<T, T>>(xInit, xParameter);

            // return expression
            return lambda;
        }


        // Extend IQuerable to use DynanimcSelector for Select
        public static IQueryable<T> Select<T>(this IQueryable<T> source, string parameters)
        {
            return source.Select(DynamicSelectGenerator<T>(parameters));
        }

        // Extend IQuerable to be able to use IncludeFilter
        public static IQueryable<T> IncludeFilter<T>(this IQueryable<T> queryable, List<Guid> filterIds, string filterProperties)
                where T : Entity<Guid>
        {
            return queryable
                .WhereIf(!filterIds.IsNullOrEmpty(), t => filterIds.Contains(t.Id))
                .Select(filterProperties);
        }

    }

Within an Repository i then call it like this, and also set Sorting (because DefaultSorting can fail if you omit the default parameter used for sorting) :

var query = ApplyFilter((await GetQueryableAsync()), filterText, name, description);
 // Add IncludeFilter to Query and adjust sorting
query = query.IncludeFilter(filterIds, filterProperties);
if (!filterProperties.IsNullOrEmpty())
  sorting = filterProperties.Split(",").First();

query = query.OrderBy(string.IsNullOrWhiteSpace(sorting) ? MyEntityConsts.GetDefaultSorting(false) : sorting);
return await query.PageBy(skipCount, maxResultCount).ToListAsync(cancellationToken);

To be able to use these both fields for my InputDto i used this:

 public class GlobalInputDto : PagedAndSortedResultRequestDto
    {
        /// Filter for specific Ids.
        public List<Guid> FilterIds { get; set; }

        /// Filter Properties (case-sensitive) p.E. "Name,Description,Id"
        public string FilterProperties { get; set; }

    }

To use it in for an Entity you only need to replacein your InputDtos PagedAndSortedResultRequestDto inheritance through GlobalInputDto

Hope this helps..

  • ABP Framework version: v5.1.3
  • UI type: Blazor Server
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes

In my Application Module i would like to configure the JsonIgnoreCondition. I did take a look at https://docs.abp.io/en/abp/latest/JSON I used AbpSystemTextJsonSerializerOptions, what did not work as expected.

I use this code in my Application Module:

I am not sure this is a bug or i am missing something ? I would expect after reading the documentation that the first way should work.

I had some trouble here to paste the code from above. all strings between the square brackets are deleted : this becomes: options.AddMaps(), (a bug here in the editor ?)

I thank you. I will take a look at it

Hi Ensin,

i thank you for your quick response. This works lika charm. Do you also got an idea for the second part on howto limit the properties with an paramter List<string> propertyList to generate a dynamic select statement which then can be added to the query like describes above.

If you're creating a bug/problem report, please include followings:

  • ABP Framework version: v5.1.3
  • UI type: Blazor Server
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): yes

We generated our base code with abp suite. It does generate in every entity repository a IQueryable<T> ApplyFilter Function. Asume that you have over 100.000 Entries for an entity.

a) We would like to have the ability to get only a few selected items (as List<Guid>) from the database. So similar to filterText we want to add a parameter filterIds to be able to get only these Ids as result.

Normally you would provide for every Entity like Car something like this:

   public static class QueryableExtensions
   {
        public static IQueryable<Car> IncludeFilterIds(
          this IQueryable<Car> queryable,
          List<Guid> filterIds = null)
        {
            if (!filterIds.IsNullOrEmpty())
            {
                return queryable
                    .WhereIf(!filterIds.IsNullOrEmpty(), e => filterIds.Contains(e.Id));
            }
            return queryable;
        }
   }

I would like to have this ability for every entity, so i tried;

    public static class QueryableExtensions
    {
        public static IQueryable<IEntity<Guid>> IncludeFilterIds(
          this IQueryable<IEntity<Guid>> queryable,
         List<Guid> filterIds = null)
        {
            if (!filterIds.IsNullOrEmpty())
            {
                return queryable
                    .WhereIf(!filterIds.IsNullOrEmpty(), e => filterIds.Contains(e.Id));
            }
            return queryable;
        }

I did call it with:

  var query = ApplyFilter((await GetQueryableAsync()), filterText, filterIds, name, description);
       query = (IQueryable<Car>) query.IncludeFilterIds(filterIds);

But this wont work as expected.causing a casting exception. Of course i can us instead of "IEntity<Guid>" "dynamic" as type, but then i wont have the Id Field, and will need to get it per reflection.

What is here the best approach ? In your examples at https://docs.abp.io/en/abp/latest/Repositories you implement the IQueryable Logic at Application Level. Is this suggested instead of Entity Framework Level ?

b) I further would like to limit the properties in a generic way. Sometimes you need only one field like Id instead the whole table. ( so instead select * from db , i would use select id from db) For a known data type i could expand above solution with:

return queryable
 .WhereIf(!filterIds.IsNullOrEmpty(), e => filterIds.Contains(e.Id));
 .Select(p => new { p.Id });

But again if i want to do it an an generic way , i will first need to implement a parameter like List<string> proplist and then add it to the query without knowing the datatype. Do you got an idea howto achieve that ?

I think both functionaltities can be used everywhere..

Hope, you could help.,

Yes this would be great. If you share the Filemanager source i will contribute if i got it working it with chunk files and large files.

I dont got access to your source code.. So i will need to implement it my own. There are more things missing like progress etc.. It will take a look at devexpress componets we already got.

@maliming : Do you got a Chunkupload for large files in ABP ? I didn't use ABP Filemanager because i need to be able to upload big files like 50GB as chunkupload.. Maybe i could overwrite the upload method from abp for that.

I think i found the issue.. I use two Syncfusion Components in that example the Filemanager and a SfUploader , which can handle chunk uploads. After choosing files with the filemanager i cancel the upload through filemanager and start an upload with the sfupload. But although i cancel the upload from filemanager it seems it tries to start the upload before i cancel it and so it blocks the process.

If i only us the sfuploader it works..

So this error isn't abp specific altough this did work without Problem with 4.3.2. and this error occured after update to 4.4.2

Showing 51 to 60 of 81 entries
Made with ❤️ on ABP v9.1.0-rc.1. Updated on January 17, 2025, 14:13