Starts in:
1 DAY
16 HRS
50 MIN
23 SEC
Starts in:
1 D
16 H
50 M
23 S
Open Closed

Many to many relationship with entities using Manager class abstraction #1497


User avatar
0
Neozzz created

Consider the case of a bookstore where 1 author can have many books and 1 book can have many authors. At the time of creation of books, we add the authors. We are assuming that the books being entered have unique authors, hence we are not fetching authors and then relating to the book entity. . Let us consider the following Author and book entity classes in the domain layer.

public class Book : AuditedAggregateRoot<Guid>
    {
        public string Name { get; set; }

        public BookType Type { get; set; }

        public DateTime PublishDate { get; set; }

        public float Price { get; set; }

        //Nav property
        public ICollection<Author> Authors { get; } = new List<Author>();

        private Book()
        {
            //ORM stuff
        }
//Other methods to insert and change are written. I’ve added a method to map authors as well.
private void MapAuthors(ICollection<AuthorReverse> authors)
        {
            var authorsList = new List<Author>();
            foreach(var x in authors )
            {
                
                Authors.Add(new Author(Guid.NewGuid(), x.Name, x.BirthDate, null, x.ShortBio));
            }
        }
}

The above MapAuthors method is used inside the bookManager class and we’re using a AuthorReverse class in the common namespace under the domain.shared project to assign values between layers as the domain entities have private constructors, the accessibility is only through its methods. I want to know if this mapping would actually work in real time.

Let’s see the author entity class.

public class Author : FullAuditedAggregateRoot<Guid>
    {
        public string Name { get; private set; }
        public DateTime BirthDate { get; set; }
        public string ShortBio { get; set; }

        //Nav property
        public virtual ICollection<Book> Books { get; set; }

        private Author()
        {
            /* This constructor is for deserialization / ORM purpose */
        }
}//other similar code in book follows.

When I hit the api I get the following error from the logs:

2021-06-18 09:51:55.557 +04:00 [INF] Request finished HTTP/2 POST https://localhost:44319/api/app/book application/json 152 - 400 - - 238.6686ms
2021-06-18 09:52:38.249 +04:00 [INF] Request starting HTTP/2 POST https://localhost:44319/api/app/book application/json 152
2021-06-18 09:52:38.253 +04:00 [INF] No CORS policy found for the specified request.
2021-06-18 09:52:38.253 +04:00 [DBG] PermissionStore.GetCacheItemAsync: pn:U,pk:572d895c-6fec-4eb2-b140-39fd2011486f,n:BookStore.Books
2021-06-18 09:52:38.254 +04:00 [DBG] Found in the cache: pn:U,pk:572d895c-6fec-4eb2-b140-39fd2011486f,n:BookStore.Books
2021-06-18 09:52:38.254 +04:00 [DBG] PermissionStore.GetCacheItemAsync: pn:R,pk:admin,n:BookStore.Books
2021-06-18 09:52:38.254 +04:00 [DBG] Found in the cache: pn:R,pk:admin,n:BookStore.Books
2021-06-18 09:52:38.254 +04:00 [INF] Authorization was successful.
2021-06-18 09:52:38.256 +04:00 [INF] Executing endpoint 'Acme.BookStore.Books.BookAppService.CreateAsync (Acme.BookStore.Application)'
2021-06-18 09:52:38.256 +04:00 [INF] Route matched with {action = "Create", controller = "Book", area = "", page = ""}. Executing controller action with signature System.Threading.Tasks.Task`1[Acme.BookStore.Books.BookDto] CreateAsync(Acme.BookStore.Books.CreateUpdateBookDto) on controller Acme.BookStore.Books.BookAppService (Acme.BookStore.Application).
2021-06-18 09:52:38.256 +04:00 [ERR] The required antiforgery header value "RequestVerificationToken" is not present.
2021-06-18 09:52:38.256 +04:00 [INF] Authorization failed for the request at filter 'Volo.Abp.AspNetCore.Mvc.AntiForgery.AbpAutoValidateAntiforgeryTokenAuthorizationFilter'.
2021-06-18 09:52:38.257 +04:00 [INF] Executing HttpStatusCodeResult, setting HTTP status code 400
2021-06-18 09:52:38.257 +04:00 [INF] Executed action Acme.BookStore.Books.BookAppService.CreateAsync (Acme.BookStore.Application) in 0.7605ms
2021-06-18 09:52:38.257 +04:00 [INF] Executed endpoint 'Acme.BookStore.Books.BookAppService.CreateAsync (Acme.BookStore.Application)'
2021-06-18 09:52:38.264 +04:00 [DBG] Added 0 entity changes to the current audit log
2021-06-18 09:52:38.264 +04:00 [DBG] Added 0 entity changes to the current audit log
2021-06-18 09:52:38.265 +04:00 [INF] Request finished HTTP/2 POST https://localhost:44319/api/app/book application/json 152 - 400 - - 15.9554ms

This is in spite of adding the following to the appsettings.json in the web project.

The database migrations have created the expected structure of 3 tables.

Please let me know a. why are we facing this cors issue b. is it recommended to have many to many relationship on entities that uses private constructors and use manager classes.


2 Answer(s)
  • User Avatar
    0
    gterdem created
    Senior .NET Developer

    Your question is not related with ABP but general in domain driven design.

    If you want to design and build your application in DDD:

    1. I would suggest stop using navigation properties in aggragate roots.
    2. Refer other aggragate root in an aggrate root by only using Id's, not navigation properties.
    3. I would suggest reading Implementing DDD E-Book. Free and great book.

    a. why are we facing this cors issue

    2021-06-18 09:52:38.256 +04:00 [ERR] The required antiforgery header value "RequestVerificationToken" is not present. You are not facing cors issue, it is antiforgery error related with our post body. You are getting Http 400 error which means your frontend request to server is faulty.

    b. is it recommended to have many to many relationship on entities that uses private constructors and use manager classes.

    If you read the book above, there are very nice samples about ddd implementations including many-to-many relations.

  • User Avatar
    0
    ServiceBot created
    Support Team Automatic process manager

    This question has been automatically marked as stale because it has not had recent activity.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06