public async Task CreateAsync(BlogPostDTO blogPostDTO) { // if no Title is provided if (blogPostDTO.Title == null) { throw new ArgumentNullException(nameof(blogPostDTO.Title)); } var adminRoleId = this.roles.AllAsNoTracking().FirstOrDefault(x => x.Name == GlobalConstants.AdministratorRoleName).Id; var user = this.users.All().FirstOrDefault(x => x.Roles.Any(x => x.RoleId == adminRoleId)); var blogPost = new BlogPost { Author = blogPostDTO.Author, Title = blogPostDTO.Title, Details = blogPostDTO.Details, ImageRemoteFileUrl = blogPostDTO.ImageRemoteFileUrl, ImageFileName = blogPostDTO.ImageFileName, ImageFileExtension = blogPostDTO.ImageFileExtension, ExternalPostUrl = blogPostDTO.ExternalPostUrl, Likes = blogPostDTO.Likes, PublishDate = DateTime.Parse(blogPostDTO.PublishDate.Trim(), CultureInfo.InvariantCulture).Date, User = user, }; await this.blogPostsRepository.AddAsync(blogPost); // blogPost.ImageRemoteFileUrl = blogPost.Id; await this.blogPostsRepository.SaveChangesAsync(); }
public void ShouldUpdateBlogPost() { Mock <IAuthorRepository> authorRepositoryMock = new Mock <IAuthorRepository>(); Mock <IBlogPostRepository> blogPostRepositoryMock = new Mock <IBlogPostRepository>(); authorRepositoryMock.Setup(x => x.GetByUserIdAndId(It.IsAny <string>(), It.IsAny <string>())).Returns(new Author { Name = "AuthorTest" }); blogPostRepositoryMock.Setup(x => x.GetByUserIdAndId(It.IsAny <string>(), It.IsAny <string>())).Returns(new BlogPost { Title = "Test" }); var authorData = new BlogPostDTO { Title = "Test2", AuthorId = "5b9d8e952e6adf8005dbcf21", Content = "test content 2" }; var mapper = TestHelper.GetMapper(); var sut = new BlogPostService(authorRepositoryMock.Object, blogPostRepositoryMock.Object, mapper); sut.UpdateBlogPost("12345", "5b9d8e952e6adf8005dbcf17", authorData); }
public SingleBlogPostDTO GetBlogPostBySlug(string slug) { SingleBlogPostDTO singleBlogPostDTO = new SingleBlogPostDTO(); List <string> list = new List <string>(); var blogPost = _blogPostRepository.GetBlogPostBySlug(slug); if (blogPost != null) { BlogPostDTO blogPostDTO = new BlogPostDTO(); blogPostDTO.Title = blogPost.Title; blogPostDTO.Description = blogPost.Description; blogPostDTO.Body = blogPost.Body; blogPostDTO.Slug = blogPost.Slug; blogPostDTO.CreatedAt = blogPost.CreatedAt; blogPostDTO.UpdatedAt = blogPost.UpdatedAt; foreach (var singleTag in blogPost.Tags) { list.Add(singleTag.Title); } string[] tags = list.ToArray(); blogPostDTO.TagList = tags; singleBlogPostDTO.BlogPost = blogPostDTO; } return(singleBlogPostDTO); }
/// <summary> /// /// </summary> /// <param name="newPost"></param> /// <returns></returns> public async Task <bool> CreatePost(BlogPostInputModel newPost) { var client = _clientFactory.CreateClient(); var request = new HttpRequestMessage(HttpMethod.Post, $"{apiRootUrl}BlogPosts/"); var blogPostDTO = new BlogPostDTO() { Author = newPost.Author, Title = newPost.Title, Text = newPost.Text, PublishedDate = DateTime.Now }; if (newPost.ImageFile != null) { newPost.ImageUrl = await _imageFileService.SaveImage(newPost.ImageFile); } // Serialize the model and set it as the content of our request var postJson = JsonSerializer.Serialize(newPost); request.Headers.Add("User-Agent", "IthWeb"); request.Content = new StringContent(postJson, Encoding.UTF8, "application/json"); var response = await client.SendAsync(request); return(response.IsSuccessStatusCode); }
public ActionResult Get(string slug) { BlogPostDTO blogPost = new BlogPostDTO(); blogPost.blogPost = _postService.GetBlogPostBySlug(slug); return(Ok(blogPost)); }
public async Task <ActionResult> Put(long id, [FromBody] BlogPostDTO updatedPost) { //if(!ModelState.IsValid) //[Note] - nie wystarczy, bo model traktowany jest jako prawidłowy chyba, że jakieś właściwości byłyby ustawione jako required - Czy to wystarczy do sprawdzenia poprawności (np. zamiast service'u walidującego) //{ // return BadRequest(); //} //[Note] zwraca się zawsze stan aktualny z bazy, a nie obiekt z parametrów logger.LogInformation("Calling put for object: {@0}", updatedPost); try { updatedPost.Id = id; var modifiedPost = await repository.UpdateAsync(mappingProvider.Map <BlogPost>(updatedPost)); return(Ok(mappingProvider.Map <BlogPostDTO>(modifiedPost))); } catch (InvalidOperationException) //?? Czy muszę osobno przechwytywać wyjątek z duplikacją tytułu i zwracać wtedy 409, czy coś innego? { logger.LogWarning("There was nothing to update"); return(NotFound(id)); } //try //[Note] raczej nie ma potrzeby używać tu try-catch -> zazwyczaj w web dev'ie stosuje się podejście global exception handler'a //Użyć Update, żeby nie zmieniać całego kontekstu //[Note] - jeśli jest tworzony nowy zasób - zwracać tak jak w Post, jeśli jest modyfikowany, nie trzeba zwracać ścieżki, bo jest w wywołaniu URL - Co tu ma być zwrócone, żeby było zgodne z HATEOS'em (żeby zwróciło w responsie url'a?) - to co w Post? //return Ok(updatedPost);//Może być NoContent }
public void UpdateBlogPost(string userId, string _id, BlogPostDTO blogPostData) { var validator = new CreateUpdateBlogPostValidator(); var validationResult = validator.Validate(blogPostData); if (!validationResult.IsValid) { throw new ValidationException(validationResult.Errors); } var post = _blogPostRepository.GetByUserIdAndId(userId, _id); if (post == null) { throw new NotFoundException("Post não encontrado"); } var author = _authorRepository.GetByUserIdAndId(userId, blogPostData.AuthorId); if (author == null) { throw new NotFoundException("Autor não encontrado"); } post = _mapper.Map <BlogPostDTO, BlogPost>(blogPostData); post.Id = ObjectId.Parse(_id); post.UserId = userId; _blogPostRepository.Update(_id, post); }
public async Task <ActionResult <BlogPostDTO> > CreateBlogPost(BlogPostDTO blogPostDTO) { int newBlogPostId = await _blogPostRepository.CreateBlogPost(blogPostDTO); var newBlogPost = await _blogPostRepository.GetBlogPostByIdAsync(newBlogPostId); return(_mapper.Map <BlogPostDTO>(newBlogPost)); }
[ProducesResponseType(typeof(BlogPostDTO), StatusCodes.Status201Created)] //[Note] Co definiuje się w takich przypadkach jako typ zwracany? Muszę podawać zawsze typ rzeczywisty, bo interface nie może być obiektem typeof? ODP: tak, podaje się typ rzeczywisty public async Task <IActionResult> Post([FromBody] BlogPostDTO postToAdd) //[note] Czy tutaj to FromBody jest konieczne? Czy domyślnie typy złożone nie powinny być odczytywane z body? ODP: nie jest konieczne, bo domyślnie są odczytywane z body, ale poprawia czytelność { //TODO: [Przekazać Id - sprawdzić foreign key EF]?? Czy w jakiś sposób mam tutaj przetwarzać typy referencyjne (np. jak z postmana chcę dodać post z autorem już istniejącym, to czy muszę zawsze podawać wszystkie pola, czy mogę podać id?) //np. mam sprawdzać id autora w DTO i jeśli != 0 to próbować go znaleźć w kontekście i przypisać? logger.LogInformation("Calling post for the following object: {@0} ", postToAdd); //?? Czy przy tym nie ma tej automatycznej weryfikacji modelu? W body post'a miałem więcej pól i wszystko przeszło. Czy da się wymusić kontrolę 1:1 (żeby body było w 100% zgodne z modelem? // postToAdd.Modified = DateTime.Now.ToLongDateString(); BlogPost addedPost = await repository.AddAsync(mappingProvider.Map <BlogPostDTO, BlogPost>(postToAdd)); var addedPostDTO = mappingProvider.Map <BlogPostDTO>(addedPost); //[Note] - w tego typu aplikacjach narzut wynikający z mapowania jest powszechnym i akceptowanym minusem, bo mapowanie jest konieczne - Czy to podwójne mapowanie nie jest już za dużym narzutem na taką akcję? return(CreatedAtRoute("GetBlog", new { id = addedPost.Id }, addedPostDTO)); //[note] W jaki sposób przerobić to na pojedynczy punkt wyjścia? Czy jest jakiś typ wspólny dla tych helpersów i czy tak się w ogóle robie w web dev'ie? ODP: nie stosuje się tego podejścia w aplikacjach web'owych //[Note] - createAtRoute wysyła URL w header'ze i stamtąd można odczytać adres - Czy ten middleware CreatedAtRoute nie powienien zwracać też URL'a do nowego obiektu? Postman pokazuje tam tylko w JSON'ie body tego obiektu.s }
public async Task <IActionResult> CreateBlogPost([FromBody] BlogPostDTO blogPostDTO) { var blogPostToCreate = _mapper.Map <BlogPost>(blogPostDTO); blogPostToCreate.Date = DateTime.UtcNow; if (await _repository.EntityExists(blogPostToCreate)) { return(BadRequest("This post has already been created")); } _repository.Add(blogPostToCreate); await _repository.SaveAllChanges(); return(Ok()); }
public static BlogPost AsModel(this BlogPostDTO blogPost) { if (blogPost is null) { throw new ArgumentNullException(nameof(blogPost)); } return(new BlogPost { Url = blogPost.Url, PostedAt = blogPost.When, Content = blogPost.Content }); }
public void ShouldAcceptValidBlogPostDataForCreate() { var authorData = new BlogPostDTO { Title = "Test2", AuthorId = "5b9d8e952e6adf8005dbcf21", Content = "test content 2" }; var sut = new CreateUpdateBlogPostValidator(); var result = sut.Validate(authorData); Assert.True(result.IsValid); }
public void ShouldNotAcceptInvalidBlogPostDataForCreate() { var authorData = new BlogPostDTO { Title = "", AuthorId = "", Content = "" }; var sut = new CreateUpdateBlogPostValidator(); var result = sut.Validate(authorData); Assert.False(result.IsValid); Assert.NotEmpty(result.Errors); }
public async Task <ActionResult <BlogPostDTO> > Get(long id) { logger.LogInformation("Calling get for object with id =" + id); BlogPost post = await repository.GetAsync(id); if (post != null) { BlogPostDTO postToReturn = mappingProvider.Map <BlogPost, BlogPostDTO>(post); //[Note] - konfiguracja początkowa jest niezbędna, bo bez niej automapper nie będzie w stanie niczego rozwiązać. Dodatkowo tutaj nie trzeba podawać obu typów, wystarczy docelowy, jeśli mapowanie jest unikalne (np. nie ma w konfiguracji mapowania jednego źródła na kilka docelowych) - Czy skoro tutaj się tego używa, to ta konfiguracja nie jest zbędna, bo to trochę wygląda na redundancję? A może ja coś źle robię? return(Ok(postToReturn)); } else { logger.LogWarning("No blog post with given id exists"); return(NotFound(id)); } }
public async Task <IActionResult> UpdateBlogPost(int blogPostId, [FromBody] BlogPostDTO blogPostDTO) { // if(blogPostId != blogPostDTO.Id) // return BadRequest("Blogpost not found"); var blogPost = await _repository.GetBlogPost(blogPostId); var blogPostToUpdate = _mapper.Map <BlogPostDTO, BlogPost>(blogPostDTO, blogPost); if (blogPostToUpdate == null) { return(NotFound()); } _repository.Update(blogPostToUpdate); await _repository.SaveAllChanges(); return(Ok()); }
public async Task <int> CreateBlogPost(BlogPostDTO blogPostDTO) { var blogPost = new BlogPost() { Type = (BlogType)Enum.Parse(typeof(BlogType), blogPostDTO.Type), Title = blogPostDTO.Title, CreateDate = DateTime.UtcNow, Content = blogPostDTO.Content, Media = blogPostDTO.Media?.ToList() }; await _context.AddAsync(blogPost); if (await SaveAllChangesAsync()) { return(blogPost.Id); } return(0); }
public SingleBlogDTO GetPost(string slug) { SingleBlogDTO singleBlog = new SingleBlogDTO(); Post post = _unitOfWork.Post.GetPost(slug); BlogPostDTO postDTO = new BlogPostDTO() { slug = post.Slug, title = post.Title, body = post.Body, description = post.Description, createdAt = post.CreatedAt, updatedAt = post.UpdatedAt, tagList = post.TagList }; singleBlog.blogPost = postDTO; return(singleBlog); }
public ActionResult Post([FromBody] BlogPostDTO blogPost) { try { if (blogPost.blogPost.Title == null || blogPost.blogPost.Description == null || blogPost.blogPost.Body == null) { throw new ArgumentException("Title, Description and Body are required fields."); } if (_postService.CheckIfSlugExistByTitle(blogPost.blogPost.Title)) { throw new ArgumentException("Blog Post with this Title already exist."); } BlogPostDTO blogPostToReturn = new BlogPostDTO(); blogPostToReturn.blogPost = _postService.AddNewBlogPost(blogPost.blogPost); return(Ok(blogPostToReturn)); } catch (ArgumentException e) { return(BadRequest(e.Message)); } }
public ActionResult Put(string slug, [FromBody] BlogPostDTO blogPost) { try { if (!_postService.CheckIfSlugExistBySlug(slug)) { throw new ArgumentException("Blog Post with this slug doesn't exist."); } if (blogPost.blogPost.Title != null && _postService.CheckIfSlugExistByTitle(blogPost.blogPost.Title)) { throw new ArgumentException("Blog Post with this Title already exist."); } BlogPostDTO blogPostToReturn = new BlogPostDTO(); blogPostToReturn.blogPost = _postService.UpdateBlogPost(slug, blogPost.blogPost); return(Ok(blogPostToReturn)); } catch (ArgumentException e) { return(BadRequest(e.Message)); } }
public void CreateBlogPost(string userId, BlogPostDTO blogPostData) { var validator = new CreateUpdateBlogPostValidator(); var validationResult = validator.Validate(blogPostData); if (!validationResult.IsValid) { throw new ValidationException(validationResult.Errors); } var author = _authorRepository.GetByUserIdAndId(userId, blogPostData.AuthorId); if (author == null || (author != null && author.UserId != userId)) { throw new NotFoundException("Autor não encontrado"); } var post = _mapper.Map <BlogPostDTO, BlogPost>(blogPostData); post.UserId = userId; _blogPostRepository.Insert(post); }
public MultipleBlogPostsDTO GetBlogPosts(string tag) { if (string.IsNullOrEmpty(tag)) { tag = ""; } var blogPosts = _blogPostRepository.GetBlogPosts(tag); int count = blogPosts.Count(); MultipleBlogPostsDTO multipleBlogPostsDTO = new MultipleBlogPostsDTO(); multipleBlogPostsDTO.BlogPosts = new List <BlogPostDTO>(); foreach (var post in blogPosts) { BlogPostDTO blogPostDTO = new BlogPostDTO(); List <string> list = new List <string>(); blogPostDTO.Title = post.Title; blogPostDTO.Body = post.Body; blogPostDTO.Description = post.Description; blogPostDTO.Slug = post.Slug; blogPostDTO.CreatedAt = post.CreatedAt; blogPostDTO.UpdatedAt = post.UpdatedAt; foreach (var singleTag in post.Tags) { list.Add(singleTag.Title); } string[] tags = list.ToArray(); blogPostDTO.TagList = tags; multipleBlogPostsDTO.BlogPosts.Add(blogPostDTO); } multipleBlogPostsDTO.PostsCount = count; return(multipleBlogPostsDTO); }
/// <summary> /// /// </summary> /// <param name="updatedPost"></param> /// <returns></returns> public async Task <bool> UpdatePost(BlogPostInputModel updatedPost) { var client = _clientFactory.CreateClient(); var request = new HttpRequestMessage(HttpMethod.Put, $"{apiRootUrl}BlogPosts/{updatedPost.Id}"); request.Headers.Add("Accept", "application/json"); request.Headers.Add("User-Agent", "IthWeb"); var editedPost = new BlogPostDTO() { Id = updatedPost.Id, Author = updatedPost.Author, PublishedDate = updatedPost.PublishedDate, Title = updatedPost.Title, Text = updatedPost.Text, ImageUrl = updatedPost.ImageUrl }; if (updatedPost.ImageFile != null) { if (!string.IsNullOrEmpty(updatedPost.ImageUrl)) { var imageFileName = updatedPost.ImageUrl.Split('/').LastOrDefault(); await _imageFileService.DeleteImage(imageFileName); } editedPost.ImageUrl = await _imageFileService.SaveImage(updatedPost.ImageFile); } var postJson = JsonSerializer.Serialize(editedPost); request.Content = new StringContent(postJson, Encoding.UTF8, "application/json"); var response = await client.SendAsync(request); return(response.IsSuccessStatusCode); }
public async Task <IActionResult> Create(BlogPostDTO PostData) { string FilePath = await _filemanager.SaveImage(PostData.MainPhoto); Story NewStory = new Story { Title = PostData.Title, Description = PostData.Description, Body = PostData.Body, Tags = PostData.Tags }; _repo.Add(NewStory); var NewPhoto = new Photo { Url = FilePath, Description = "Descriptive Photo", IsMain = true }; if (await _repo.Commit()) { NewStory.Photos.Add(NewPhoto); if (await _repo.Commit()) { return(CreatedAtRoute( nameof(HomeController.GetPhoto), new { id = NewPhoto.Id })); } return(BadRequest("Could not save the photo")); } return(BadRequest("Could not save the story")); }
public IActionResult Post([FromBody] BlogPostDTO post) { _blogPostService.CreateBlogPost(CurrentUserId, post); return(Ok()); }
public BlogPostDisplayModel(BlogPostDTO dto) { this.Text_Html = dto.Text; this.Date = dto.Date; this.Title = dto.Title; }
public IActionResult Put(string id, [FromBody] BlogPostDTO post) { _blogPostService.UpdateBlogPost(CurrentUserId, id, post); return(Ok()); }
// TODO - does this belong here? private static bool IsMatch(BlogPostDisplayModel first, BlogPostDTO second) { return first.Date == second.Date && first.Text_Html == second.Text && first.Title == second.Title; }