Base solution for your next web application
Open Closed

Extending RAD Tool Entity / UI #4729


User avatar
0
cyklussoftware created

I am using ASP.NET Core + jQuery version 5.2.

So, I've successfully created two new entities with their respective UIs. Location and LocationCategory.

Location contains several properties including a Name. LocationCategory contains a single property called Name.

Since the entities created with the RAD tool are basically Existing Entities, I am following the tutorial found here: [https://aspnetzero.com/Documents/Extending-Existing-Entities]).

Because the RAD tool doesn't support Relationships yet, I manually added a Many to 1 relationship between Location (many) and Location Category (1), applied migration, and updated the database. My database changed as I expected (a Location has one LocationCategory).

I get stuck starting at the "SHOW ADDRESS ON THE UI" section of the Extending Existing Entities tutorial. The data table is set up through the Index.js page and I need to add a column definition.

My first question is: How would I show the Name property of a LocationCategory that is associated with a Location in the data table through the Index.js page? This is an example column definition for the Name property of Location in the Index.js file:

            {
                targets: 1,
                data: "name"
            }

3 Answer(s)
  • User Avatar
    0
    faisalalam created

    Best option would be add foreign key support to RAD tool. I am waiting for the same.

    Meanwhile I am working with this -- look into this tool below might help. <a class="postlink" href="https://www.junnark.com/Products/AspCoreGen2MVC/">https://www.junnark.com/Products/AspCoreGen2MVC/</a>

  • User Avatar
    0
    cyklussoftware created

    Thanks for the suggestion. I think I will be able to figure my way through this eventually. I'll re-create my solution when foreign key support is added. In the mean time, it's good for me to learn about the way ASP.NET Zero works.

    I am currently struggling with DTO circular references. I have the following entities:

    [Table("Location")]
        public class Location : Entity , IMustHaveTenant
        {
            public int TenantId { get; set; }
    
            [Required]
            public virtual string Name { get; set; }
    
            public virtual int Radius { get; set; }
    
            public virtual LocationCategory.LocationCategory Category { get; set; }
        }
    
    [Table("LocationCategory")]
        public class LocationCategory : Entity , IMustHaveTenant
        {
            public int TenantId { get; set; }
    
            [Required]
            public virtual string Name { get; set; }
    
            public ICollection<Location.Location> Locations { get; set; }
        }
    

    and the corresponding DTOs:

    public class LocationDto : EntityDto
        {
            public string Name { get; set; }
    
            public int Radius { get; set; }
    
            public LocationCategory.Dtos.LocationCategoryDto Category { get; set; }
        }
    
    public class LocationCategoryDto : EntityDto
        {
            public string Name { get; set; }
    
            public Collection<Location.Dtos.LocationDto> Locations { get; set; }
        }
    

    I have set up my LocationAppService and LocationCategoryAppService using the ".Include" method so that the navigation properties for the Entities are filled.

    When I test the "getAll" method using the Google Chrome console, I get a 500 Internal Server Error. Eventually, I figured out that if I comment out either "public LocationCategory.Dtos.LocationCategoryDto Category { get; set; }" OR "public Collection<Location.Dtos.LocationDto> Locations { get; set; }" I am able to view the data in the database. So I clearly have a circular reference error.

    My questions are these:

    1. Is it possible to change the JSON serializer settings or is it still embedded in ABP stuff?

    2. Without changing the JSON serializer settings, is there a way to resolve the circular reference issues?

    Note: Both Locations and LocationCategories will have their own dedicated UI pages (as generated by the RAD Tool). I will want to look up (through navigation properties) which Locations belong to a LocationCategory and vice-versa from each UI set.

  • User Avatar
    0
    yekalkan created

    Hi @CyklusSoftware,

    Here are the steps:

    1. Create a new dto like below (dto name doesn't matter)
    public class LocationListDto
     {
            public LocationDto Location{ get; set; }
    
            public string LocationCategoryName { get; set; }
     }
    
    1. Modify your GetAll method of LocationAppService
    public async Task<PagedResultDto<LocationListDto>> GetAll(GetAllLocationsInput input) //Also modify ILocationAppService
            {
                var isFilterNullOrEmpty = string.IsNullOrEmpty(input.Filter);
    
                var locations = _locationRepository.GetAll().WhereIf(!isFilterNullOrEmpty, d => true); // insert your filter here
    
                var locationCategories= _locationCategoryRepository.GetAll(); // inject locationCategoryRepository in constructor
    
                var query = (from l in locations
                            join lc in locationCategories on l.LocationCategoryId equals lc.Id into gj
                            from subpet in gj.DefaultIfEmpty()
                            select new LocationListDto() {Location= ObjectMapper.Map<LocationDto>(l), LocationCategoryName = subpet == null?"": subpet.Name});
    
                var totalCount = await query.CountAsync();
    
                var locationsSortedAndPaged = await query
                    .OrderBy(input.Sorting ?? "location.id asc")
                    .PageBy(input)
                    .ToListAsync();
    
                return new PagedResultDto<LocationListDto>(
                    totalCount,
                    locationsSortedAndPaged 
                );
            }
    
    1. Add new field in index.js and modify existing ones
    {
          targets: 2, // set your own target value
           data: "locationCategoryName"
     }
    
    {
           targets: 1,
           data: "location.myField" // old version was data:"myField" . We added "location.". You have to do it for all existing fields
     }
    
    1. Add header in index.cshtml
    <th>@L("LocationCategoryName")</th>
    

    Thats all. It should work if i didn't forget to paste any code.