none
Web APi RRS feed

  • Question

  • Hi i have two user tables and groups that have multiple relationships.how do I assign a user to multiple groups or vice versa in Asp Core web api by repositorypattern.help me.
    Sunday, November 24, 2019 7:02 AM

All replies

  • The repository pattern is a domain pattern. It is not a data access pattern in application architecture, although the ADO.NET Entity Framework uses the repositroy pattern.  

    https://martinfowler.com/eaaCatalog/repository.html

    And in general, the generic repository pattern, which is generally taught in ASP.NET MVC,  is not an optimal pattern to use, becuase its too generic. And somehow in using the ASP.NET MVC pattern and WebAPI uses the ASP.NET MVC pattern too, the repository pattern got twisted into something else.

    https://blog.sapiensworks.com/post/2012/03/05/The-Generic-Repository-Is-An-Anti-Pattern.aspx

    https://blog.sapiensworks.com/post/2012/03/05/The-Generic-Repository-Is-An-Anti-Pattern.aspx

    https://www.thereformedprogrammer.net/is-the-repository-pattern-useful-with-entity-framework-core/

    Myself, I use the DAO pattern, which is used on a per table basis.

    If I were going to use the repository pattern, it would be non generic,  and it would be using the DAO pattern with DTO pattern. 

    https://blog.sapiensworks.com/post/2012/11/01/Repository-vs-DAO.aspx

    https://en.wikipedia.org/wiki/Data_access_object

    https://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5

    Example of ASP.NET Core solution using what I have given you information on about patterns. The VM suffix means View Model, and the DM means Domain Model. 

    The DTO is kept in a classlib project called Entities and all the other projects that need to know about the DTO have reference to the Entities classlib project. And you can see how DAOArticle in the data access layer (DAL) using the repository pattern that Entity Framework has implemented.  

    ASP.NET Core and ASP.NET WebAPI can be discussed at  the ASP.NET forums.

    http://forums.asp.net/

    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace PublishingCompany.Models
    {
        public class ArticleVM
        {
            public class Article
            {
                public int ArticleId { get; set; }
                public int AuthorId { get; set; }
                public string AuthorName { get; set; }
    
                [Required(ErrorMessage = "Title is required")]
                [StringLength(50)]
                public string Title { get; set; }
                public string Body { get; set; }
            }
    
            public List<Article> Articles { get; set; } = new List<Article>();
        }
    }

    using Microsoft.AspNetCore.Mvc; using PublishingCompany.Models; namespace PublishingCompany.Controllers { public class AuthorController : Controller { private IAuthorDM adm; public AuthorController(IAuthorDM authorDM) { adm = authorDM; } public IActionResult Index() { return View(adm.GetAll()); } public IActionResult Detail(int id = 0) { return id == 0 ? null : View(adm.Find(id)); } public IActionResult Create() { return View(adm.Add()); } [HttpPost] public ActionResult Create(AuthorVM.Author author, string submit) { if (submit == "Cancel") return RedirectToAction("Index"); if (!ModelState.IsValid) return View(author); adm.Add(author); return RedirectToAction("Index"); } public ActionResult Edit(int id = 0) { return id == 0 ? null : View(adm.Update(id)); } [HttpPost] public ActionResult Edit(AuthorVM.Author author, string submit) { if (submit == "Cancel") return RedirectToAction("Index"); if (!ModelState.IsValid) return View(author); adm.Update(author); return RedirectToAction("Index"); }

    public IActionResult Delete(int id = 0) { if (id > 0) adm.Delete(id); return RedirectToAction("Index"); } public ActionResult Cancel() { return RedirectToAction("Index", "Home"); } } }

    namespace PublishingCompany.Models
    {
        public interface IArticleDM
        {
            ArticleVM GetAll();
            ArticleVM GetArticlesByAuthorId(int id);
            ArticleVM.Article Find(int id);
            ArticleVM.Article Add(int id);
            void Add(ArticleVM.Article author);
            ArticleVM.Article Update(int id);
            void Update(ArticleVM.Article author);
            void Delete(int id);
        }
    }
    using System.Linq;
    using Entities;
    using ServiceLayer;
    
    namespace PublishingCompany.Models
    {
        public class ArticleDM : IArticleDM
        {
            private IArticleSvc svc;
            public ArticleDM(IArticleSvc articleSvc)
            {
                svc = articleSvc;
            }
    
            public ArticleVM GetAll()
            {
                var vm = new ArticleVM();
    
                var dtos = svc.GetAll().ToList();
    
                vm.Articles.AddRange(dtos.Select(dto => new ArticleVM.Article()
                {
                    ArticleId = dto.ArticleId,
                    AuthorId = dto.AuthorId,
                    Title = dto.Title,
                    Body = dto.Body
                }).ToList());
    
                return vm;
            }
    
            public ArticleVM GetArticlesByAuthorId(int id)
            {
                var vm = new ArticleVM();
    
                var dtos = svc.GetArticlesByAuthorId(id).ToList();
    
                vm.Articles.AddRange(dtos.Select(dto => new ArticleVM.Article()
                {
                    ArticleId = dto.ArticleId,
                    AuthorId = dto.AuthorId,
                    AuthorName = dto.AuthorName,
                    Title = dto.Title,
                    Body = dto.Body
                }).ToList());
    
                return vm;
            }
            public ArticleVM.Article Find(int id)
            {
                var dto = svc.Find(id);
    
                var article = new ArticleVM.Article
                {
                    ArticleId = dto.ArticleId,
                    AuthorId = dto.AuthorId,
                    Title = dto.Title,
                    Body = dto.Body
                };
    
                return article;
            }
    
            public ArticleVM.Article Add(int id)
            {
                return new ArticleVM.Article{AuthorId = id};
            }
    
            public void Add(ArticleVM.Article article)
            {
                var dto = new DtoArticle
                {
                    AuthorId = (int) article.AuthorId,
                    Title = article.Title,
                    Body = article.Body
                };
    
                svc.Add(dto);
            }
    
            public ArticleVM.Article Update(int id)
            {
                var dto = Find(id);
    
                var article = new ArticleVM.Article
                {
                    ArticleId = dto.ArticleId,
                    AuthorId = dto.AuthorId,
                    Title = dto.Title,
                    Body = dto.Body
                };
    
                return article;
            }
    
            public void Update(ArticleVM.Article article)
            {
                var dto = new DtoArticle
                {
                    ArticleId = article.ArticleId,
                    AuthorId = article.AuthorId,
                    Title = article.Title,
                    Body = article.Body
                };
    
                svc.Update(dto);
            }
    
            public void Delete(int id)
            {
                var dto = new DtoId
                {
                    Id = id
                };
    
                svc.Delete(dto);
            }
        }
    }

    using System.Collections.Generic;
    using Entities;
    
    namespace ServiceLayer
    {
        public interface IArticleSvc
        {
            List<DtoArticle> GetAll();
            List<DtoArticle> GetArticlesByAuthorId(int id);
            DtoArticle Find(int id);
            void Add(DtoArticle dto);
            void Update(DtoArticle dto);
            void Delete(DtoId dto);
        }
    }

    using System;
    using System.Collections.Generic;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Text;
    using Entities;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    
    namespace ServiceLayer
    {
        public class ArticleSvc :IArticleSvc
        {
            public List<DtoArticle> GetAll()
            {
                var dtoarticles = new List<DtoArticle>();
    
                using (var client = new HttpClient())
                {
                    var uri = new Uri("http://localhost/WebAPI/api/article/GetAll");
    
                    var response = client.GetAsync(uri).Result;
    
                    if (!response.IsSuccessStatusCode)
                        throw new Exception(response.ToString());
    
                    var responseContent = response.Content;
                    var responseString = responseContent.ReadAsStringAsync().Result;
    
                    dynamic articles = JArray.Parse(responseString) as JArray;
    
                    foreach (var obj in articles)
                    {
                        DtoArticle dto = obj.ToObject<DtoArticle>();
    
                        dtoarticles.Add(dto);
                    }
                }
    
                return dtoarticles;
            }
    
            public List<DtoArticle> GetArticlesByAuthorId(int id)
            {
                var dtoarticles = new List<DtoArticle>();
    
                using (var client = new HttpClient())
                {
                    var uri = new Uri("http://localhost/WebAPI/api/article/GetArticlesByAuthorId?id=" + id);
    
                    var response = client.GetAsync(uri).Result;
    
                    if (!response.IsSuccessStatusCode)
                        throw new Exception(response.ToString());
    
                    var responseContent = response.Content;
                    var responseString = responseContent.ReadAsStringAsync().Result;
    
                    dynamic articles = JArray.Parse(responseString) as JArray;
    
                    foreach (var obj in articles)
                    {
                        DtoArticle dto = obj.ToObject<DtoArticle>();
    
                        dtoarticles.Add(dto);
                    }
                }
    
                return dtoarticles;
            }
            public DtoArticle Find(int id)
            {
                DtoArticle dto;
    
                using (var client = new HttpClient())
                {
                    var uri = new Uri("http://localhost/WebAPI/api/article/Find?id=" + id);
                    HttpResponseMessage getResponseMessage = client.GetAsync(uri).Result;
    
                    if (!getResponseMessage.IsSuccessStatusCode)
                        throw new Exception(getResponseMessage.ToString());
    
                    var responsemessage = getResponseMessage.Content.ReadAsStringAsync().Result;
    
                    dynamic article = JsonConvert.DeserializeObject(responsemessage);
    
                    dto = article.ToObject<DtoArticle>();
                }
    
                return dto;
            }
    
            public void Add(DtoArticle dto)
            {
                using (var client = new HttpClient { BaseAddress = new Uri("http://localhost") })
                {
                    string serailizeddto = JsonConvert.SerializeObject(dto);
    
                    var inputMessage = new HttpRequestMessage
                    {
                        Content = new StringContent(serailizeddto, Encoding.UTF8, "application/json")
                    };
    
                    inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    HttpResponseMessage message =
                        client.PostAsync("WebAPI/api/article/Add", inputMessage.Content).Result;
    
                    if (!message.IsSuccessStatusCode)
                        throw new Exception(message.ToString());
                }
            }
    
            public void Update(DtoArticle dto)
            {
                using (var client = new HttpClient { BaseAddress = new Uri("http://localhost") })
                {
                    string serailizeddto = JsonConvert.SerializeObject(dto);
    
                    var inputMessage = new HttpRequestMessage
                    {
                        Content = new StringContent(serailizeddto, Encoding.UTF8, "application/json")
                    };
    
                    inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    HttpResponseMessage message =
                        client.PostAsync("WebAPI/api/article/Update", inputMessage.Content).Result;
    
                    if (!message.IsSuccessStatusCode)
                        throw new Exception(message.ToString());
                }
            }
    
            public void Delete(DtoId dto)
            {
                using (var client = new HttpClient { BaseAddress = new Uri("http://localhost") })
                {
                    string serailizeddto = JsonConvert.SerializeObject(dto);
    
                    var inputMessage = new HttpRequestMessage
                    {
                        Content = new StringContent(serailizeddto, Encoding.UTF8, "application/json")
                    };
    
                    inputMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    
                    HttpResponseMessage message =
                        client.PostAsync("WebAPI/api/article/Delete", inputMessage.Content).Result;
    
                    if (!message.IsSuccessStatusCode)
                        throw new Exception(message.ToString());
                }
            }
        }
    }

    using System.Collections.Generic;
    using System.Threading.Tasks;
    using DAL;
    using Entities;
    using Microsoft.AspNetCore.Mvc;
    
    namespace WebAPI.Controllers
    {
        [Produces("application/json")]
        [Route("api/[controller]")]
        [ApiController]
        public class ArticleController : ControllerBase
        {
            private IDaoArticle dao;
            public ArticleController(IDaoArticle daoArticle)
            {
                dao = daoArticle;
            }
    
            [HttpGet]
            [Route("GetAll")]
            public async Task<List<DtoArticle>> GetAll()
            {
                return await dao.GetAll();
            }
    
            [HttpGet]
            [Route("GetArticlesByAuthorId")]
            public async Task<List<DtoArticle>> GetArticlesByAuthorId(int id)
            {
                return await dao.GetArticlesByAuthorId(id);
            }
    
    
            [HttpGet]
            [Route("Find")]
            public async Task<DtoArticle> Find(int id)
            {
                return await dao.Find(id);
            }
    
            [HttpPost]
            [Route("Add")]
            public async Task Add(DtoArticle dto)
            {
                await dao.Add(dto);
            }
    
            [HttpPost]
            [Route("Update")]
            public async Task Update(DtoArticle dto)
            {
                await dao.Update(dto);
            }
    
            [HttpPost]
            [Route("Delete")]
            public async Task Delete(DtoId dto)
            {
                await dao.Delete(dto.Id);
            }
        }
    }

    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Entities;
    
    namespace DAL
    {
        public interface IDaoArticle
        {
            Task<List<DtoArticle>> GetAll();
            Task<List<DtoArticle>> GetArticlesByAuthorId(int id);
            Task<DtoArticle> Find(int id);
            Task Add(DtoArticle dto);
            Task Update(DtoArticle dto);
            Task Delete(int id);
        }
    }

    using System;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using DAL.Models;
    using Entities;
    using Microsoft.EntityFrameworkCore;
    
    namespace DAL
    {
        public class DaoArticle :IDaoArticle
        {
            private PublishingCompanyContext pc;
            private IDaoAuthor _daoAuthor;
    
            public DaoArticle(PublishingCompanyContext dbcontext, IDaoAuthor daoAuthor)
            { 
                pc = dbcontext;
                _daoAuthor = daoAuthor;
            }
            public async Task<List<DtoArticle>> GetAll()
            {
                var dtos = new List<DtoArticle>();
    
                var articles = await pc.Article.ToListAsync();
    
                dtos.AddRange(articles.Select(article => new DtoArticle()
                {
                    ArticleId = article.ArticleId,
                    AuthorId = article.AuthorId,
                    Title = article.Title,
                    Body = article.Body
                }).ToList());
    
                return dtos;
            }
    
            public async Task<List<DtoArticle>> GetArticlesByAuthorId(int id)
            {
                var dtos = new List<DtoArticle>();
    
                var articles = await pc.Article.Where(a => a.AuthorId.ToString().Contains(id.ToString())).ToListAsync();
               
                foreach (var article in articles)
                {
                    var intid = (int)article.AuthorId;
    
                    var dtoauthor = await _daoAuthor.Find(intid);
    
                    var dto = new DtoArticle
                    {
                        ArticleId = article.ArticleId,
                        AuthorId = article.AuthorId,
                        AuthorName = dtoauthor.LastName +", " + dtoauthor.FirstName,
                        Title = article.Title,
                        Body = article.Body
                    };
    
                    dtos.Add(dto);
                }
                 
                return dtos;
            }
            public async Task<DtoArticle> Find(int id)
            {
                var dto = new DtoArticle();
    
                var article = await pc.Article.FindAsync(id);
                
                if (article != null)
                {
                    dto.ArticleId = article.ArticleId;
                    dto.AuthorId = article.AuthorId;
                    dto.Title = article.Title;
                    dto.Body = article.Body;
                }
                else
                {
                    throw new Exception($"Article with ID = {id} was not found.");
                }
    
                return dto;
    
            }
    
            public async Task Add(DtoArticle dto)
            {
                var article = new Article
                {
                    AuthorId = dto.AuthorId,
                    Title = dto.Title,
                    Body = dto.Body
                };
    
                pc.Article.Add(article);
                await pc.SaveChangesAsync();
    
            }
    
            public async Task Update(DtoArticle dto)
            {
                var article = new Article
                {
                    ArticleId = dto.ArticleId,
                    AuthorId = dto.AuthorId,
                    Title = dto.Title,
                    Body = dto.Body
                };
    
                pc.Entry(article).State = EntityState.Modified;
                await pc.SaveChangesAsync();
    
            }
    
            public async Task Delete(int id)
            {
                var article = pc.Article.Find(id);
    
                if (article != null)
                {
                    pc.Article.Remove(article);
                    await pc.SaveChangesAsync();
                }
            }
    
        }
    }
    

    using System;
    
    namespace Entities
    {
        public class DtoArticle
        {
            public int ArticleId { get; set; }
            public string Title { get; set; }
            public string Body { get; set; }
            public int AuthorId { get; set; }
            public string AuthorName { get; set; }
        }
    }




    • Edited by DA924x Sunday, November 24, 2019 9:31 AM
    Sunday, November 24, 2019 9:25 AM
  • Repository pattern is used to reincarnate exists domain object from some type of repo (file, database, cloud, etc…). It is not primarily to be used as gate into database. 

    Fist you need some application layer which will implements use cases. One use case can be Add user into group. So there will be method AddUserIntoGroup(string userName, string groupName). 

    Implementation this method will be very easy because it loads user from database by DAO pattern, loads group from database by DAO pattern, checks if user/group exists and then create new UserInGroup object, set UserId, GroupId and save it to database by DAO pattern.

    Data layer will have three classes UserDAO, GroupDAO, UserInGroupDAO. User will have GetByUserName(string userName) method, Group will have GetByGroupName(string groupName) method and UserInGroup will have Insert(UserInGroup userInGroup) which do insert operation into database. 

    Super easy solution.

    Monday, November 25, 2019 1:53 PM
  • To satisfy your requirement with ASP.NET Core you should look into using ASP.NET Core Identity. There is no reason to implement this yourself using the repository pattern.

    There is a lot of documentation and tutorials online for ASP.NET Core Identity.


    william xifaras


    Monday, November 25, 2019 3:30 PM