Changing the output DTO (return value) of the GetAll method in an AsyncCrudAppService

application-layer asp.net-mvc aspnetboilerplate dto entity-framework-6

Question

I'm using ABP's AsyncCrudAppService in my AppServices. Here's my interface:

public interface IAssetRequisitionAppService : IAsyncCrudAppService
    <AssetRequisitionDto, Guid, GetAllInput, AssetRequisitionDto, AssetRequisitionDto, AssetRequisitionDetailsDto>
{ }

And the service:

public class AssetRequisitionAppService : AsyncCrudAppService
    <AssetRequisition, AssetRequisitionDto, Guid, GetAllInput, AssetRequisitionDto, AssetRequisitionDto, AssetRequisitionDetailsDto>, 
    IAssetRequisitionAppService
{
    public AssetRequisitionAppService(IRepository<AssetRequisition, Guid> repository) : base(repository)
    { }
}

Now, I believe all these standard CRUD methods will return the default type (which is AssetRequisitionDto in my case). But, what I want to do is to return a different type for Get() and GetAll() methods.

Get() should have a much more detailed DTO with subproperties of the Navigation props. But GetAll() should have a much less detailed one just to populate a table.

Is there a way to override the return types in some way?

1
0
7/16/2018 1:09:08 PM

Accepted Answer

Well I noticed I'll eventually need more complex filtering methods anyway. So, I created my custom types and methods.

First, I created my own GetAllInput derived from PagedAndSortedResultRequestDto. It's suited for most of my services, as I usually need to query the data related to employees and locations:

public class GetAllInput : PagedAndSortedResultRequestDto
{
    public long? PersonId { get; set; }
    public long? LocationId { get; set; }
    public EEmployeeType? EmployeeType { get; set; }
}

After that I wrote a GetAll method for each of my services. They all return a PagedResultDto<> so I can use it's functionalities in presentation layer. Here's one example below:

//MovableAppService

    public PagedResultDto<MovableLineDto> GetAllLinesRelatedToUser(GetAllInput input)
    {
        Logger.Info("Loading all movables related to current user");

        IQueryable<Movable> queryable = null;
        if (input.PersonId.HasValue)
        {
            if (input.EmployeeType == EEmployeeType.Recorder)
            {
                var recorder = _personRepository.GetAll()
                .OfType<Employee>()
                .FirstOrDefault(x => x.Id == input.PersonId);
                var authorizedStorageIds = recorder.StoragesAuthorized.Select(y => y.Id);

                queryable = _repository.GetAll()
                    .Where(x => authorizedStorageIds.Contains(x.StorageOfOriginId));
            }
            else if (input.EmployeeType == EEmployeeType.UnitManager)
            {
                var locationCodes = _locationRepository.GetAll()
                    .Where(x => x.ManagerInChargeId == input.PersonId)
                    .Select(x => x.Code);

                foreach (var code in locationCodes)
                {
                    queryable = _locationRepository.GetAll()
                        .Where(x => x.Code.StartsWith(code))
                        .SelectMany(x => x.AssignmentDocs)
                        .SelectMany(x => x.Movements)
                        .OfType<Assignment>()
                        .Where(x => x.TimeOfReturn == null)
                        .Select(x => x.Asset)
                        .OfType<Movable>();
                    queryable = queryable.Concat(queryable);
                }
            }
            else if (input.TenantIdsOversee.Count() > 0)
            {
                var overseer = _personRepository.GetAll()
                    .OfType<Overseer>()
                    .FirstOrDefault(x => x.Id == input.PersonId);
                var overseeingTenantIds = overseer.TenantsOversee.Select(y => y.Id);

                queryable = _repository.GetAll()
                   .Where(x => overseeingTenantIds.Contains((int)x.TenantId));
            }
            else if (input.EmployeeType == EEmployeeType.Employee)
            {
                queryable = _personRepository.GetAll()
                    .OfType<Employee>()
                    .Where(x => x.Id == input.PersonId)
                    .SelectMany(x => x.AssignmentDocs)
                    .SelectMany(x => x.Movements)
                    .OfType<Assignment>()
                    .Where(x => x.TimeOfReturn == null)
                    .Select(x => x.Asset)
                    .OfType<Movable>();
            }
        }
        var list = queryable.ToList()
                .OrderBy(x => x.Category.Definition);
        var items = _objectMapper.Map<IReadOnlyList<MovableLineDto>>(list);

        return new PagedResultDto<MovableLineDto>(items.Count, items);
    }

Btw, aaron's answer is probably valid for ASP.NET Core projects. But my project is in MVC EF6, so those annotations are not available for me.

Now I'm marking this as the answer but if there's a more elegant way, I'm happy to see and I'll change my mark then.

0
8/20/2018 12:49:04 PM

Popular Answer

Yes, there is some way.

// using Microsoft.AspNetCore.Mvc;

[ActionName(nameof(GetAll))]
public PagedResultRequestDto MyGetAll(PagedResultRequestDto input)
{
    return input;
}

[NonAction]
public override Task<PagedResultDto<UserDto>> GetAll(PagedResultRequestDto input)
{
    return base.GetAll(input);
}

Reference: https://github.com/aspnetboilerplate/aspnetboilerplate/issues/2859



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow