<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:SklepConnectionString1 %>"
DeleteCommand="DELETE FROM [Products] WHERE [ProductId] = @ProductId"
InsertCommand="INSERT INTO [Products] ([ProductName], [RecommendedRetailPrice],
[Selling Price]) VALUES (@ProductName, @RecommendedRetailPrice, @Selling_Price)"
ProviderName="<%$ ConnectionStrings:SklepConnectionString1.ProviderName %>"
SelectCommand="SELECT [ProductId], [ProductName], [RecommendedRetailPrice],
[Selling Price] AS Selling_Price FROM [Products]"
UpdateCommand="UPDATE [Products] SET [ProductName] = @ProductName,
[RecommendedRetailPrice] = @RecommendedRetailPrice,
[Selling Price] = @Selling_Price WHERE [ProductId] = @ProductId">
<DeleteParameters>
<asp:Parameter Name="ProductId" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="ProductName" Type="String" />
<asp:Parameter Name="RecommendedRetailPrice" Type="Decimal" />
<asp:Parameter Name="Selling_Price" Type="Decimal" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="ProductName" Type="String" />
<asp:Parameter Name="RecommendedRetailPrice" Type="Decimal" />
<asp:Parameter Name="Selling_Price" Type="Decimal" />
<asp:Parameter Name="ProductId" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime Date { get; set; }
public string Description { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
public string ImageUrl { get; set; }
public string Url { get; set; }
public int Rate { get; set; }
}
public class Category
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public ICollection<Post> Posts { get; set; }
}
public class Webinars
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public string FacebookEventUrl { get; set; }
public string SlidesUrl { get; set; }
public string WatchFacebookLink { get; set; }
public string WatchYoutubeLink { get; set; }
public DateTime Date { get; set; }
public bool AlreadyHappend { get; set; }
}
public class AuditableEntity
{
public string CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public string LastModifiedBy { get; set; }
public DateTime? LastModifiedDate { get; set; }
}
public class Category : AuditableEntity
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public ICollection<Post> Posts { get; set; }
}
public interface IAsyncRepository<T> where T : class
{
Task<T> GetByIdAsync(int id);
Task<IReadOnlyList<T>> GetAllAsync();
Task<T> AddAsync(T entity);
Task UpdateAsync(T entity);
Task DeleteAsync(T entity);
}
public interface IPostRepository
: IAsyncRepository<Post>
{
}
public interface ICategoryRepository
: IAsyncRepository<Category>
{
}
public interface IWebinaryRepository
: IAsyncRepository<Webinars>
{
}
public class GetVideoCoursesListQuery
: IRequest<List<VideoCoursesVideModel>>
{
}
public class GetVideoCoursesQueryHandler
: IRequestHandler<GetVideoCoursesListQuery, List<VideoCoursesVideModel>>
{
public async Task<List<VideoCoursesVideModel>> Handle
(GetVideoCoursesListQuery request,
CancellationToken cancellationToken)
{
}
}
private User TranslateUser(UserViewModel userView)
{
return new User()
{
FirstName = userView.FirstName,
LastName = userView.LastName,
Login = userView.Login,
Role = userView.Role,
UserId = userView.UserId
};
}
public static T2 ConvertToTheSameProperties<T1,T2>(T1 employee) where T2 : new()
{
var prop = employee.GetType().GetProperties();
var prop2 = typeof(T2).GetProperties();
T2 u = new T2();
foreach (var propertyInfo in prop)
{
bool propValue = propertyInfo.PropertyType == typeof (string) ||
propertyInfo.PropertyType == typeof (int) ||
propertyInfo.PropertyType == typeof (long) ||
propertyInfo.PropertyType == typeof (Guid) ||
propertyInfo.PropertyType == typeof (bool) ||
propertyInfo.PropertyType == typeof (bool?);
foreach (var info in prop2)
{
if (propertyInfo.Name == info.Name &&
info.CanWrite &&
propertyInfo.CanRead)
{
if (propValue && propertyInfo.PropertyType == info.PropertyType)
info.SetValue(u, propertyInfo.GetValue(employee));
}
}
}
return u;
}
[ApiController]
[Route("[controller]")]
public class EmployeeController : Controller
{
private readonly IMapper _mapper;
public Employee Index()
{
EmployeeDto eDTO = new EmployeeDto()
{
EmployeeId = 121,
FirstName = "Damian",
LastName = "Morfeus",
Login = "frankodomanamiga",
OrganizationCompanyName = "LichyDzwig",
OrganizationId = 34,
Role = "Sprzątacz podłogi pietra 34",
RootOrganizationCompanyName = "Dobra Winda",
RootOrganizationId = 12,
Type = "Sprzątacz"
};
return _mapper.Map<Employee>(eDTO);
}
}
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<EmployeeDto, Employee>();
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\EduZbieracz.Domain\EduZbieracz.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Functions\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.0" />
<PackageReference Include="MediatR" Version="9.0.0" />
</ItemGroup>
</Project>
public class PostInListViewModel
{
public int PostId { get; set; }
public string Title { get; set; }
public DateTime Date { get; set; }
public string ImageUrl { get; set; }
public int Rate { get; set; }
}
public class GetPostsListQuery
: IRequest<List<PostInListViewModel>>
{
}
public class GetPostsListQueryHandler :
IRequestHandler<GetPostsListQuery, List<PostInListViewModel>>
{
public Task<List<PostInListViewModel>>
Handle(GetPostsListQuery request,
CancellationToken cancellationToken)
{
throw new NotImplementedException();
}
}
public class GetPostsListQueryHandler :
IRequestHandler<GetPostsListQuery, List<PostInListViewModel>>
{
private readonly IAsyncRepository<Post> _postRepository;
private readonly IMapper _mapper;
public GetPostsListQueryHandler
(IMapper mapper,
IAsyncRepository<Post> postRepository)
{
_mapper = mapper;
_postRepository = postRepository;
}
public async Task<List<PostInListViewModel>>
Handle(GetPostsListQuery request,
CancellationToken cancellationToken)
{
var all = await _postRepository.GetAllAsync();
var allordered = all.OrderBy(x => x.Date);
return _mapper.Map<List<PostInListViewModel>>(all);
}
}
private readonly IAsyncRepository<Post> _postRepository;
private readonly IMapper _mapper;
public GetPostsListQueryHandler
(IMapper mapper,
IAsyncRepository<Post> postRepository)
{
_mapper = mapper;
_postRepository = postRepository;
}
public async Task<List<PostInListViewModel>>
Handle(GetPostsListQuery request,
CancellationToken cancellationToken)
{
var all = await _postRepository.GetAllAsync();
var allordered = all.OrderBy(x => x.Date);
return _mapper.Map<List<PostInListViewModel>>(all);
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Post, PostInListViewModel>()
.ReverseMap();
}
}
public class PostDetailViewModel
{
public int PostId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime Date { get; set; }
public string Description { get; set; }
public CategoryDto Category { get; set; }
public string ImageUrl { get; set; }
public string Url { get; set; }
public int Rate { get; set; }
}
public class CategoryDto
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
}
public class GetPostDetailQuery
: IRequest<PostDetailViewModel>
{
public int Id { get; set; }
}
public class GetPostDetailQueryHandler :
IRequestHandler<GetPostDetailQuery, PostDetailViewModel>
{
private readonly IAsyncRepository<Post> _postRepository;
private readonly IAsyncRepository<Category> _categoryRepository;
private readonly IMapper _mapper;
public GetPostDetailQueryHandler(
IAsyncRepository<Post> postRepository,
IAsyncRepository<Category> categoryRepository,
IMapper mapper)
{
_postRepository = postRepository;
_categoryRepository = categoryRepository;
_mapper = mapper;
}
public async Task<PostDetailViewModel> Handle
(GetPostDetailQuery request,
CancellationToken cancellationToken)
{
var post = await _postRepository.GetByIdAsync(request.Id);
var postdetail = _mapper.Map<PostDetailViewModel>(post);
var category = await _categoryRepository.GetByIdAsync(post.CategoryId);
postdetail.Category = _mapper.Map<CategoryDto>(category);
return postdetail;
}
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Post, PostInListViewModel>()
.ReverseMap();
CreateMap<Post, PostDetailViewModel>()
.ReverseMap();
CreateMap<Category, CategoryDto>();
}
}
public static class AddEduZbieraczApplication
{
public static IServiceCollection AddEduZbieraczApplication(this IServiceCollection services)
{
services.AddAutoMapper(Assembly.GetExecutingAssembly());
services.AddMediatR(Assembly.GetExecutingAssembly());
return services;
}
}
public class CategoryInListViewModel
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
}
public class GetCategoriesListQuery
: IRequest<List<CategoryInListViewModel>>
{
}
public class GetCategoriesListQueryHandler :
IRequestHandler<GetCategoriesListQuery, List<CategoryInListViewModel>>
{
private readonly IAsyncRepository<Category> _categoryRepository;
private readonly IMapper _mapper;
public GetCategoriesListQueryHandler(IMapper mapper,
IAsyncRepository<Category> categoryRepository)
{
_mapper = mapper;
_categoryRepository = categoryRepository;
}
public async Task<List<CategoryInListViewModel>> Handle
(GetCategoriesListQuery request, CancellationToken cancellationToken)
{
var all = await _categoryRepository.GetAllAsync();
var ordered = all.OrderBy(a => a.Name);
return _mapper.Map<List<CategoryInListViewModel>>(ordered);
}
}
public class CategoryPostDto
{
public int PostId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime Date { get; set; }
public string ImageUrl { get; set; }
public int Rate { get; set; }
public int CategoryId { get; set; }
}
public class CategoryPostListViewModel
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public ICollection<CategoryPostDto> Posts { get; set; }
}
public class CategoryPostListViewModel
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
public ICollection<CategoryPostDto> Posts { get; set; }
}
public class GetCategoriesWithPostListQuery :
IRequest<List<CategoryPostListViewModel>>
{
public SearchCategoryOptions searchCategory { get; set; }
}
public enum SearchCategoryOptions
{
All = 0,
FirstBestThisMonth = 2,
FirstBestAllTheTime = 3,
}
public class GetCategoriesWithPostListQueryHandler :
IRequestHandler<GetCategoriesWithPostListQuery,
List<CategoryPostListViewModel>>
{
private readonly IAsyncRepository<Category> _categoryRepository;
private readonly IMapper _mapper;
public GetCategoriesWithPostListQueryHandler(IMapper mapper,
IAsyncRepository<Category> categoryRepository)
{
_mapper = mapper;
_categoryRepository = categoryRepository;
}
public Task<List<CategoryPostListViewModel>>
Handle(GetCategoriesWithPostListQuery request,
CancellationToken cancellationToken)
{
var list = await _categoryRepository.
GetCategoriesWithPost(request.searchCategory);
return _mapper.Map<List<CategoryPostListViewModel>>(list);
}
}
public interface ICategoryRepository
: IAsyncRepository<Category>
{
Task<List<Category>>
GetCategoriesWithPost
(SearchCategoryOptions searchCategory);
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Post, PostInListViewModel>()
.ReverseMap();
CreateMap<Post, PostDetailViewModel>()
.ReverseMap();
CreateMap<Category, CategoryDto>();
CreateMap<Category, CategoryInListViewModel>();
CreateMap<Category, CategoryPostDto>();
CreateMap<Category, CategoryPostListViewModel>();
}
}
public class CreatedPostCommand : IRequest<int>
{
public int PostId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime Date { get; set; }
public string Description { get; set; }
public int CategoryId { get; set; }
public string ImageUrl { get; set; }
public string Url { get; set; }
public int Rate { get; set; }
}
public class CreatedPostCommandHandler
: IRequestHandler<CreatedPostCommand, int>
{
private readonly IPostRepository _postRepository;
private readonly IMapper _mapper;
public async Task<int> Handle(CreatedPostCommand request,
CancellationToken cancellationToken)
{
var post = _mapper.Map<Post>(request);
post = await _postRepository.AddAsync(post);
return post.PostId;
}
public CreatedPostCommandHandler(IPostRepository postRepository,
IMapper mapper)
{
_postRepository = postRepository;
_mapper = _mapper;
}
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Post, PostInListViewModel>()
.ReverseMap();
CreateMap<Post, PostDetailViewModel>()
.ReverseMap();
CreateMap<Category, CategoryDto>();
CreateMap<Category, CategoryInListViewModel>();
CreateMap<Category, CategoryPostDto>();
CreateMap<Category, CategoryPostListViewModel>();
CreateMap<Post, CreatedPostCommand>().ReverseMap();
}
}
public class UpdatePostCommand : IRequest
{
public int PostId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime Date { get; set; }
public string Description { get; set; }
public int CategoryId { get; set; }
public string ImageUrl { get; set; }
public string Url { get; set; }
public int Rate { get; set; }
}
public class UpdatePostCommandHandler
: IRequestHandler<UpdatePostCommand>
{
private readonly IPostRepository _postRepository;
private readonly IMapper _mapper;
public async Task<Unit> Handle(UpdatePostCommand request,
CancellationToken cancellationToken)
{
var post = _mapper.Map<Post>(request);
await _postRepository.UpdateAsync(post);
return Unit.Value;
}
public UpdatePostCommandHandler(IPostRepository postRepository,
IMapper mapper)
{
_postRepository = postRepository;
_mapper = mapper;
}
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Post, PostInListViewModel>()
.ReverseMap();
CreateMap<Post, PostDetailViewModel>()
.ReverseMap();
CreateMap<Category, CategoryDto>();
CreateMap<Category, CategoryInListViewModel>();
CreateMap<Category, CategoryPostDto>();
CreateMap<Category, CategoryPostListViewModel>();
CreateMap<Post, CreatedPostCommand>().ReverseMap();
CreateMap<Post, UpdatePostCommand>().ReverseMap();
}
}
public class DeletePostCommand : IRequest
{
public int PostId { get; set; }
}
public class DeletePostCommandHandler : IRequestHandler<DeletePostCommand>
{
private readonly IPostRepository _postRepository;
private readonly IMapper _mapper;
public async Task<Unit> Handle(DeletePostCommand request,
CancellationToken cancellationToken)
{
var posttodelete = await _postRepository.GetByIdAsync(request.PostId);
await _postRepository.DeleteAsync(posttodelete);
return Unit.Value;
}
public DeletePostCommandHandler(IPostRepository postRepository,
IMapper mapper)
{
_postRepository = postRepository;
_mapper = mapper;
}
}
public class Post
{
public int PostId { get; set; }
[Required]
[StringLenght(80)]
public string Title { get; set; }
[StringLenght(40)]
public string Author { get; set; }
.....
[Range(0, 100)]
public int Rate { get; set; }
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\EduZbieracz.Domain\EduZbieracz.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.0" />
<PackageReference Include="FluentValidation" Version="9.4.0" />
<PackageReference Include="FluentValidation.DependencyInjectionExtensions" Version="9.4.0" />
<PackageReference Include="MediatR" Version="9.0.0" />
<PackageReference Include="MediatR.Extensions.Microsoft.DependencyInjection" Version="9.0.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Functions\Categories\Commands\CreateCategory\" />
<Folder Include="Functions\Webinars\Command\" />
<Folder Include="Functions\Webinars\Queries\GetWebinarList\" />
</ItemGroup>
</Project>
public class CreatedPostCommandValidator
: AbstractValidator<CreatedPostCommand>
{
public CreatedPostCommandValidator()
{
RuleFor(p => p.Title)
.NotEmpty()
.WithMessage("{PropertyName} is required")
.NotNull()
.MaximumLength(80)
.WithMessage("{PropertyName} must not exceed 80 characters");
RuleFor(p => p.Date)
.NotEmpty()
.WithMessage("{PropertyName} is required")
.NotNull()
.LessThan(DateTime.Now.AddDays(1));
RuleFor(p => p.Rate)
.InclusiveBetween(0, 100)
.WithMessage("{PropertyName} is beetween 0 to 100");
}
}
public class CreatedPostCommandHandler
: IRequestHandler<CreatedPostCommand, int>
{
......
public async Task<int> Handle(CreatedPostCommand request,
CancellationToken cancellationToken)
{
var validator = new CreatedPostCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
//Co dalej......
var post = _mapper.Map<Post>(request);
post = await _postRepository.AddAsync(post);
return post.PostId;
}
.....
}
public class ValidationEduException : ApplicationException
{
public List<string> ErrorMessages { get; set; }
public ValidationEduException(ValidationResult validationResult)
{
ErrorMessages = new List<String>();
foreach (var item in validationResult.Errors)
{
ErrorMessages.Add(item.ErrorMessage);
}
}
}
public async Task<int> Handle(CreatedPostCommand request,
CancellationToken cancellationToken)
{
var validator = new CreatedPostCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
throw new ValidationEduException(validatorResult);
var post = _mapper.Map<Post>(request);
post = await _postRepository.AddAsync(post);
return post.PostId;
}
public class CreatedPostCommandValidator
: AbstractValidator<CreatedPostCommand>
{
private readonly IPostRepository _postRepository;
public CreatedPostCommandValidator(IPostRepository postRepository)
{
_postRepository = postRepository;
......................
......................
RuleFor(p => p).
MustAsync(IsNameAndAuthorAlreadyExist)
.WithMessage("Post with the same Title and Author already exist");
}
private async Task<bool> IsNameAndAuthorAlreadyExist
(CreatedPostCommand e, CancellationToken cancellationToken)
{
var check = await _postRepository.
IsNameAndAuthorAlreadyExist(e.Title, e.Author);
return !check;
}
}
public interface IPostRepository
: IAsyncRepository<Post>
{
Task<bool>
IsNameAndAuthorAlreadyExist
(string title, string author);
}
public class CreatedPostCommandHandler
: IRequestHandler<CreatedPostCommand, int>
{
private readonly IPostRepository _postRepository;
private readonly IMapper _mapper;
public async Task<int> Handle(CreatedPostCommand request,
CancellationToken cancellationToken)
{
var validator = new CreatedPostCommandValidator
(_postRepository);
//Co dalej ?
//Czy wyrzucanie wyjątków to dobry pomysł?
public class BaseResponse
{
public bool Success { get; set; }
public string Message { get; set; }
public List<string> ValidationErrors { get; set; }
public BaseResponse()
{
ValidationErrors = new List<string>();
Success = true;
}
public BaseResponse(string message = null)
{
ValidationErrors = new List<string>();
Success = true;
Message = message;
}
public BaseResponse(string message, bool success)
{
ValidationErrors = new List<string>();
Success = success;
Message = message;
}
public BaseResponse(ValidationResult validationResult)
{
ValidationErrors = new List<String>();
Success = validationResult.Errors.Count < 0;
foreach (var item in validationResult.Errors)
{
ValidationErrors.Add(item.ErrorMessage);
}
}
}
public class CreatedPostCommandResponse : BaseResponse
{
public int? PostId { get; set; }
public CreatedPostCommandResponse() : base()
{ }
public CreatedPostCommandResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public CreatedPostCommandResponse(string message)
: base(message)
{ }
public CreatedPostCommandResponse(string message, bool success)
: base(message, success)
{ }
public CreatedPostCommandResponse(int postId)
{
PostId = postId;
}
}
public class CreatedPostCommand
: IRequest<CreatedPostCommandResponse>
{
public int PostId { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public DateTime Date { get; set; }
public string Description { get; set; }
public int CategoryId { get; set; }
public string ImageUrl { get; set; }
public string Url { get; set; }
public int Rate { get; set; }
}
public class CreatedPostCommandHandler
: IRequestHandler<CreatedPostCommand, CreatedPostCommandResponse>
{
private readonly IPostRepository _postRepository;
private readonly IMapper _mapper;
public async Task<CreatedPostCommandResponse>
Handle(CreatedPostCommand request,
CancellationToken cancellationToken)
{
var validator = new CreatedPostCommandValidator(_postRepository);
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new CreatedPostCommandResponse(validatorResult);
var post = _mapper.Map<Post>(request);
post = await _postRepository.AddAsync(post);
return new CreatedPostCommandResponse(post.PostId);
}
public CreatedPostCommandHandler(IPostRepository postRepository,
IMapper mapper)
{
_postRepository = postRepository;
_mapper = mapper;
}
}
public enum ResponseStatus
{
Success = 0,
NotFound = 1,
BadQueryRequest = 2,
ValidationError = 3,
Exception = 4,
DataBaseError = 5,
OtherClientApiError = 5,
}
public class BaseResponse
{
public ResponseStatus Status { get; set; }
public bool Success { get; set; }
public string Message { get; set; }
public List<string> ValidationErrors { get; set; }
public class CreatedCategoryCommand
: IRequest<CreatedCategoryCommandResponse>
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string DisplayName { get; set; }
}
public class CreatedCategoryCommandResponse : BaseResponse
{
public int? CategoryId { get; set; }
public CreatedCategoryCommandResponse() : base()
{ }
public CreatedCategoryCommandResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public CreatedCategoryCommandResponse(string message)
: base(message)
{ }
public CreatedCategoryCommandResponse(string message, bool success)
: base(message, success)
{ }
public CreatedCategoryCommandResponse(int categoryId)
{
CategoryId = categoryId;
}
}
public class CreatedCategoryCommandValidator :
AbstractValidator<CreatedCategoryCommand>
{
public CreatedCategoryCommandValidator()
{
RuleFor(c => c.Name)
.MinimumLength(2).MaximumLength(15)
.WithMessage("{PropertName} Length is beewten 2 and 15");
RuleFor(c => c.DisplayName)
.MinimumLength(2).MaximumLength(15)
.WithMessage("{PropertName} Length is beewten 2 and 15");
}
}
public class CreatedCategoryCommandHandler
: IRequestHandler<CreatedCategoryCommand, CreatedCategoryCommandResponse>
{
private readonly ICategoryRepository _categoryRepository;
private readonly IMapper _mapper;
public async Task<CreatedCategoryCommandResponse> Handle(CreatedCategoryCommand request, CancellationToken cancellationToken)
{
var validator = new CreatedCategoryCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new CreatedCategoryCommandResponse(validatorResult);
var category = _mapper.Map<Category>(request);
category = await _categoryRepository.AddAsync(category);
return new CreatedCategoryCommandResponse(category.CategoryId);
}
public CreatedCategoryCommandHandler(ICategoryRepository categoryRepository,
IMapper mapper)
{
_categoryRepository = categoryRepository;
_mapper = mapper;
}
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Post, PostInListViewModel>()
.ReverseMap();
CreateMap<Post, PostDetailViewModel>()
.ReverseMap();
CreateMap<Category, CategoryDto>();
CreateMap<Category, CategoryInListViewModel>();
CreateMap<Category, CategoryPostDto>();
CreateMap<Category, CategoryPostListViewModel>();
CreateMap<Post, CreatedPostCommand>().ReverseMap();
CreateMap<Post, UpdatePostCommand>().ReverseMap();
CreateMap<Category, CreatedCategoryCommand>().ReverseMap();
}
}
public class GetWebinarsByDateQuery
: IRequest<PageWebinarByDateViewModel>
{
public DateTime? Date { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
public SearchOptionsWebinars Options { get; set; }
}
public enum SearchOptionsWebinars
{
Ignore = 0,
Month = 1,
Year = 2,
MonthAndYear = 3
}
public class WebinarsByDateViewModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public string FacebookEventUrl { get; set; }
public string SlidesUrl { get; set; }
public string WatchFacebookLink { get; set; }
public string WatchYoutubeLink { get; set; }
public DateTime Date { get; set; }
}
public class GetWebinarsByDateQueryHandler :
IRequestHandler<GetWebinarsByDateQuery, PageWebinarByDateViewModel>
{
private readonly IWebinaryRepository _webinarRepository;
private readonly IMapper _mapper;
public GetWebinarsByDateQueryHandler(IWebinaryRepository webinarRepository,
IMapper mapper)
{
_webinarRepository = webinarRepository;
_mapper = mapper;
}
public async Task<PageWebinarByDateViewModel> Handle
(GetWebinarsByDateQuery request, CancellationToken cancellationToken)
{
var list = await _webinarRepository.GetPagedWebinarsForDate
(request.Options, request.Page, request.PageSize, request.Date);
var webinars = _mapper.Map<List<WebinarsByDateViewModel>>(list);
var count = await _webinarRepository.GetTotalCountOfWebinarsForDate(request.Options, request.Date);
return new PageWebinarByDateViewModel()
{
AllCount = count,
Webinars = webinars,
Page = request.Page,
PageSize = request.PageSize
};
}
}
public interface IWebinaryRepository : IAsyncRepository<Webinar>
{
Task<int> GetTotalCountOfWebinarsForDate
(SearchOptionsWebinars options, DateTime? date);
Task<List<Webinar>> GetPagedWebinarsForDate
(SearchOptionsWebinars options, int page, int pageSize,
DateTime? date);
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Post, PostInListViewModel>()
.ReverseMap();
CreateMap<Post, PostDetailViewModel>()
.ReverseMap();
CreateMap<Category, CategoryDto>();
CreateMap<Category, CategoryInListViewModel>();
CreateMap<Category, CategoryPostDto>();
CreateMap<Category, CategoryPostListViewModel>();
CreateMap<Post, CreatedPostCommand>().ReverseMap();
CreateMap<Post, UpdatePostCommand>().ReverseMap();
CreateMap<Category, CreatedCategoryCommand>().ReverseMap();
CreateMap<Webinar, WebinarsByDateViewModel>().ReverseMap();
}
}
public class CreatedWebinarCommand :
IRequest<CreatedWebinarCommandResponse>
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public string FacebookEventUrl { get; set; }
public string SlidesUrl { get; set; }
public string WatchFacebookLink { get; set; }
public string WatchYoutubeLink { get; set; }
public DateTime Date { get; set; }
public bool AlreadyHappend { get; set; }
}
public class CreatedWebinarCommandResponse : BaseResponse
{
public int? Id { get; set; }
public CreatedWebinarCommandResponse() : base()
{ }
public CreatedWebinarCommandResponse(ValidationResult validationResult)
: base(validationResult)
{ }
public CreatedWebinarCommandResponse(string message)
: base(message)
{ }
public CreatedWebinarCommandResponse(string message, bool success)
: base(message, success)
{ }
public CreatedWebinarCommandResponse(int webinarId)
{
Id = webinarId;
}
}
public class CreatedWebinarCommandValidator :
AbstractValidator<CreatedWebinarCommand>
{
public CreatedWebinarCommandValidator()
{
RuleFor(w => w.ImageUrl).NotEmpty().NotNull();
RuleFor(w => w.Title).NotEmpty().NotNull()
.MinimumLength(5).MaximumLength(80);
RuleFor(w => w.FacebookEventUrl).NotEmpty().NotNull();
RuleFor(w => w.Date).
GreaterThan
(DateTime.Now.AddYears(-1));
}
}
public class CreatedWebinarCommandHandler
: IRequestHandler<CreatedWebinarCommand, CreatedWebinarCommandResponse>
{
public async Task<CreatedWebinarCommandResponse>
Handle(CreatedWebinarCommand request,
CancellationToken cancellationToken)
{
var validator = new CreatedWebinarCommandValidator();
var validatorResult = await validator.ValidateAsync(request);
if (!validatorResult.IsValid)
return new CreatedWebinarCommandResponse(validatorResult);
var webinar = _mapper.Map<Webinar>(request);
webinar = await _webinaryRepository.AddAsync(webinar);
return new CreatedWebinarCommandResponse(webinar.Id);
}
public CreatedWebinarCommandHandler(IWebinaryRepository webinaryRepository,
IMapper mapper)
{
_webinaryRepository = webinaryRepository;
_mapper = mapper;
}
private readonly IWebinaryRepository _webinaryRepository;
private readonly IMapper _mapper;
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<Post, PostInListViewModel>()
.ReverseMap();
CreateMap<Post, PostDetailViewModel>()
.ReverseMap();
CreateMap<Category, CategoryDto>();
CreateMap<Category, CategoryInListViewModel>();
CreateMap<Category, CategoryPostDto>();
CreateMap<Category, CategoryPostListViewModel>();
CreateMap<Post, CategoryPostDto>();
CreateMap<Post, CreatedPostCommand>().ReverseMap();
CreateMap<Post, UpdatePostCommand>().ReverseMap();
CreateMap<Category, CreatedCategoryCommand>().ReverseMap();
CreateMap<Webinar, WebinarsByDateViewModel>().ReverseMap();
CreateMap<Webinar, CreatedWebinarCommand>().ReverseMap();
CreateMap<Webinar, WebinarViewModel>().ReverseMap();
CreateMap<Webinar, UpdateWebinarCommand>().ReverseMap();
}
}
public static Mock<ICategoryRepository> GetCategoryRepository()
{
var categories = GetCategories();
var mockCategoryRepository = new Mock<ICategoryRepository>();
mockCategoryRepository.
Setup(repo => repo.GetAllAsync()).ReturnsAsync(categories);
mockCategoryRepository.
Setup(repo => repo.GetByIdAsync(It.IsAny<int>())).ReturnsAsync(
(int id) =>
{
var cat = categories.FirstOrDefault(c => c.CategoryId == id);
return cat;
});
mockCategoryRepository.
Setup(repo => repo.AddAsync(It.IsAny<Category>())).ReturnsAsync(
(Category category) =>
{
categories.Add(category);
return category;
});
mockCategoryRepository.
Setup(repo => repo.DeleteAsync(It.IsAny<Category>())).Callback
<Category>((entity) => categories.Remove(entity));
mockCategoryRepository.
Setup(repo => repo.UpdateAsync(It.IsAny<Category>())).Callback
<Category>((entity) => { categories.Remove(entity); categories.Add(entity); });
var categorieswithpost = GetCategoriesWithPosts();
mockCategoryRepository.Setup(repo => repo.GetCategoriesWithPost
(It.IsAny<SearchCategoryOptions>()))
.ReturnsAsync(categorieswithpost);
return mockCategoryRepository;
}
public static Mock<IPostRepository> GetPostRepository()
{
var posts = GetPosts();
var mockpostRepository = new Mock<IPostRepository>();
mockpostRepository.Setup(repo => repo.GetAllAsync()).ReturnsAsync(posts);
mockpostRepository.Setup(repo => repo.GetByIdAsync(It.IsAny<int>())).ReturnsAsync(
(int id) =>
{
var pos = posts.FirstOrDefault(c => c.PostId == id);
return pos;
});
mockpostRepository.Setup(repo => repo.AddAsync(It.IsAny<Post>())).ReturnsAsync(
(Post post) =>
{
posts.Add(post);
return post;
});
mockpostRepository.Setup(repo => repo.DeleteAsync(It.IsAny<Post>())).Callback
<Post>((entity) => posts.Remove(entity));
mockpostRepository.Setup(repo => repo.UpdateAsync(It.IsAny<Post>())).Callback
<Post>((entity) => { posts.Remove(entity); posts.Add(entity); });
mockpostRepository.Setup(repo => repo.IsNameAndAuthorAlreadyExist
(It.IsAny<string>(), It.IsAny<string>()))
.ReturnsAsync((string title, string author) =>
{
var matches = posts.
Any(a => a.Title.Equals(title) && a.Author.Equals(author));
return matches;
});
return mockpostRepository;
}
public static Mock<IWebinaryRepository> GetWebinarRepository()
{
var webinars = GetWebinars();
var mockWebinarRepository = new Mock<IWebinaryRepository>();
mockWebinarRepository.Setup(repo => repo.GetAllAsync()).ReturnsAsync(webinars);
mockWebinarRepository.Setup(repo => repo.GetByIdAsync(It.IsAny<int>())).ReturnsAsync(
(int id) =>
{
var pos = webinars.FirstOrDefault(c => c.Id == id);
return pos;
});
mockWebinarRepository.Setup(repo => repo.AddAsync(It.IsAny<Webinar>())).ReturnsAsync(
(Webinar webinar) =>
{
webinars.Add(webinar);
return webinar;
});
mockWebinarRepository.Setup(repo => repo.DeleteAsync(It.IsAny<Webinar>())).Callback
<Webinar>((entity) => webinars.Remove(entity));
mockWebinarRepository.Setup(repo => repo.UpdateAsync(It.IsAny<Webinar>())).Callback
<Webinar>((entity) => { webinars.Remove(entity); webinars.Add(entity); });
mockWebinarRepository.Setup(repo => repo.GetPagedWebinarsForDate
(It.IsAny<SearchOptionsWebinars>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<DateTime?>()))
.ReturnsAsync((SearchOptionsWebinars s, int page, int pageSize, DateTime date) =>
{
var matches = webinars.Where(x => x.Date.Month == date.Month && x.Date.Year == date.Year)
.Skip((page - 1) * pageSize).Take(pageSize).ToList();
return matches;
});
mockWebinarRepository.Setup(repo => repo.GetTotalCountOfWebinarsForDate
(It.IsAny<SearchOptionsWebinars>(), It.IsAny<DateTime?>()))
.ReturnsAsync((SearchOptionsWebinars s, DateTime date) =>
{
var matches = webinars.Count
(x => x.Date.Month == date.Month && x.Date.Year == date.Year);
return matches;
});
return mockWebinarRepository;
}
public class CreatePostTest
{
private readonly IMapper _mapper;
private readonly Mock<IPostRepository> _mockPostRepository;
public CreatePostTest()
{
_mockPostRepository = RepositoryMocks.GetPostRepository();
var configurationProvider = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MappingProfile>();
}
);
_mapper = configurationProvider.CreateMapper();
}
[Fact]
public async Task Handle_ValidPost_AddedToPostRepo()
{
var handler = new CreatedPostCommandHandler
(_mockPostRepository.Object, _mapper);
var allPostsBeforeCount = (await _mockPostRepository.Object.GetAllAsync()).Count;
var command = new CreatedPostCommand()
{
Title = "TestTest",
Date = DateTime.Now.AddDays(-14),
Rate = 9,
Author = "AAAA"
};
var response = await handler.Handle(command, CancellationToken.None);
var allPosts = await _mockPostRepository.Object.GetAllAsync();
response.Success.ShouldBe(true);
response.ValidationErrors.Count.ShouldBe(0);
allPosts.Count.ShouldBe(allPostsBeforeCount + 1);
response.PostId.ShouldNotBeNull();
}
[Fact]
public async Task Handle_Not_ValidPost_TooLongTitle_81Characters_NotAddedToPostRepo()
{
var handler = new CreatedPostCommandHandler
(_mockPostRepository.Object, _mapper);
var allPostsBeforeCount = (await _mockPostRepository.Object.GetAllAsync()).Count;
var command = new CreatedPostCommand()
{
Title = new string('*', 81),
Date = DateTime.Now.AddDays(-14),
Rate = 9,
Author = "AAAA"
};
var response = await handler.Handle(command, CancellationToken.None);
var allPosts = await _mockPostRepository.Object.GetAllAsync();
response.Success.ShouldBe(false);
response.ValidationErrors.Count.ShouldBe(1);
allPosts.Count.ShouldBe(allPostsBeforeCount);
response.PostId.ShouldBeNull();
}
[Fact]
public async Task Handle_Not_ValidPost_FutureDate_2DayIntoTheFuture_NotAddedToPostRepo()
{
var handler = new CreatedPostCommandHandler
(_mockPostRepository.Object, _mapper);
var allPostsBeforeCount = (await _mockPostRepository.Object.GetAllAsync()).Count;
var command = new CreatedPostCommand()
{
Title = new string('*', 80),
Date = DateTime.Now.AddDays(2),
Rate = 9,
Author = "AAAA"
};
var response = await handler.Handle(command, CancellationToken.None);
var allPosts = await _mockPostRepository.Object.GetAllAsync();
response.Success.ShouldBe(false);
response.ValidationErrors.Count.ShouldBe(1);
allPosts.Count.ShouldBe(allPostsBeforeCount);
response.PostId.ShouldBeNull();
}
[Fact]
public async Task Handle_Not_ValidPost_RateToBig_NotAddedToPostRepo()
{
var handler = new CreatedPostCommandHandler
(_mockPostRepository.Object, _mapper);
var allPostsBeforeCount = (await _mockPostRepository.Object.GetAllAsync()).Count;
var command = new CreatedPostCommand()
{
Title = new string('*', 80),
Date = DateTime.Now.AddDays(-12),
Rate = 101,
Author = "AAAA"
};
var response = await handler.Handle(command, CancellationToken.None);
var allPosts = await _mockPostRepository.Object.GetAllAsync();
response.Success.ShouldBe(false);
response.ValidationErrors.Count.ShouldBe(1);
allPosts.Count.ShouldBe(allPostsBeforeCount);
response.PostId.ShouldBeNull();
}
public class CreateWebinarTest
{
private readonly IMapper _mapper;
private readonly Mock<IWebinaryRepository> _mockWebinarRepository;
public CreateWebinarTest()
{
_mockWebinarRepository = RepositoryMocks.GetWebinarRepository();
var configurationProvider = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MappingProfile>();
}
);
_mapper = configurationProvider.CreateMapper();
}
[Fact]
public async Task Handle_ValidWebinar_AddedToWebinarRepo()
{
var handler = new CreatedWebinarCommandHandler
(_mockWebinarRepository.Object, _mapper);
var allWebinarsBeforeCount = (await _mockWebinarRepository.Object.GetAllAsync()).Count;
var command = new CreatedWebinarCommand()
{
ImageUrl = "TestTest",
Title = new string('*', 80),
FacebookEventUrl = "TestTest",
Date = DateTime.Now.AddDays(-14),
};
var response = await handler.Handle(command, CancellationToken.None);
var allWebinars = await _mockWebinarRepository.Object.GetAllAsync();
response.Success.ShouldBe(true);
response.ValidationErrors.Count.ShouldBe(0);
allWebinars.Count.ShouldBe(allWebinarsBeforeCount + 1);
response.Id.ShouldNotBeNull();
}
}
public class CreateCategoryTests
{
private readonly IMapper _mapper;
private readonly Mock<ICategoryRepository> _mockCategoryRepository;
public CreateCategoryTests()
{
_mockCategoryRepository = RepositoryMocks.GetCategoryRepository();
var configurationProvider = new MapperConfiguration(cfg =>
{
cfg.AddProfile<MappingProfile>();
});
_mapper = configurationProvider.CreateMapper();
}
[Fact]
public async Task Handle_ValidCategory_AddedToCategoriesRepo()
{
var handler = new CreatedCategoryCommandHandler
(_mockCategoryRepository.Object, _mapper);
var allCategoriesBeforeCount =
(await _mockCategoryRepository.Object.GetAllAsync()).Count;
var response = await handler.Handle(new CreatedCategoryCommand()
{ Name = "Test", DisplayName = "Test" }
, CancellationToken.None);
var allCategories = await _mockCategoryRepository.Object.GetAllAsync();
response.Success.ShouldBe(true);
response.ValidationErrors.Count.ShouldBe(0);
allCategories.Count.ShouldBe(allCategoriesBeforeCount + 1);
response.CategoryId.ShouldNotBeNull();
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>EduZbieracz.Persistence.EF</AssemblyName>
<RootNamespace>EduZbieracz.Persistence.EF</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\EduZbieracz.Application\EduZbieracz.Application.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.11" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="5.0.0" />
</ItemGroup>
</Project>
public class DummySeed
{
public static int Csharp = 1;
public static int Aspnet = 2;
public static int TrikiZWindows = 3;
public static int Docker = 4;
public static int Filzofia = 5;
}
public class DummyCategories
{
public static List<Category> Get()
{
Category c1 = new Category()
{
CategoryId = DummySeed.Csharp,
Name = "CSharp",
DisplayName = "C#"
};
Category c2 = new Category()
{
CategoryId = DummySeed.Aspnet,
Name = "aspnet",
DisplayName = "ASP.NET"
};
Category c3 = new Category()
{
CategoryId = DummySeed.TrikiZWindows,
Name = "triki-z-windows",
DisplayName = "Triki z Windows"
};
Category c4 = new Category()
{
CategoryId = DummySeed.Docker,
Name = "docker",
DisplayName = "Docker"
};
Category c5 = new Category()
{
CategoryId = DummySeed.Filzofia,
Name = "filozofia",
DisplayName = "Filozofia"
};
List<Category> p = new List<Category>();
p.Add(c1); p.Add(c3);
p.Add(c2); p.Add(c4);
p.Add(c5);
return p;
}
}
public static class DummyPosts
{
public static List<Post> Get()
{
var cat = DummyCategories.Get();
Post p1 = new Post()
{
Author = "Damian",
Date = DateTime.Now.AddMonths(-6),
Description = @"Nasze aplikacje ASP.NET CORE coraz częściej są tylko aplikacją REST. To oczywiście wymaga Walidacji po stronie klienta i po stronie serwera
Jak taką walidację jak najszybciej zrobić.Może przecież sam napisać takie warunki,
ale przy dużej ilości klas,
które występują jako parametry mija się to z celem.
Możesz też skorzystać z atrybutów i oznaczyć reguły do każdej właściwości.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
PostId = 1,
Rate = 8,
CategoryId = DummySeed.Aspnet,
Title = "Walidacja z FluentValidation w ASP.NET Core + Swagger",
Url = "https://cezarywalenciuk.pl/blog/programing/walidacja-z-fluentvalidation-waspnet-core--swagger"
};
Post p2 = new Post()
{
Author = "Damian",
Date = DateTime.Now.AddMonths(-6),
Description = @"Programiści codziennie tworzą jakąś aplikację sieciową typu REST. Teraz nastaje pytanie, jak najlepiej zrozumieć jak dane API działa. Do tego mamy dokumentacje, ale jeśli pracujesz w szybkich, zamkniętych projektach to takiej dokumentacji może nie być.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
PostId = 2,
CategoryId = DummySeed.Aspnet,
Rate = 7,
Title = "Swagger UI : Dokumentowanie API w ASP.NET CORE",
Url = "https://cezarywalenciuk.pl/blog/programing/swagger-ui--dokumentowanie-api-w-aspnet-core"
};
Post p3 = new Post()
{
Author = "Stefan",
Date = DateTime.Now.AddMonths(-12),
Description = @"W pod koniec roku 2017 zacząłem ćwiczyć. Proste ćwiczenia rzeczywiście robią różnice, gdy masz siedzący tryb życia. A co z bieganiem ?
Pamiętam jak pierwszy raz na bieżni nie byłem w stanie wytrzymać 5 minut normalnego spaceru. Powoli z tygodnia na dzień zacząłem sobie stawiać wyższe progi i tak odkryłem, że o ile jest to na początku bolesne to jak twoje ciało da Ci te endorfiny to już...aż chce się biegać więcej. ",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
PostId = 3,
CategoryId = DummySeed.Filzofia,
Rate = 5,
Title = "Bieganie jak się do tego zmotywować : Zdrowie Programisty",
Url = "https://cezarywalenciuk.pl/blog/programing/bieganie-jak-sie-do-tego-zmotywowac--zdrowie-programisty"
};
Post p4 = new Post()
{
Author = "Damian",
Date = DateTime.Now.AddMonths(-12),
Description = @"Logowanie działania aplikacji. Jak wiedzieć w końcu, gdy coś nie działa. Mój blog jest napisany w C# i działa po ASP.NET CORE. Jak to jednak bywa z napisaną przez siebie aplikacją pojawiają się błędy więc do bloga dodałem mechanizm logowania błędów. W taki sposób znalazłem wiele dziwnych przypadków uszkodzonych wpisów w formacie XML, które rozwalały Parser. Znalazłem też złe zbudowane przez ze mnie lista kursów. ",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
PostId = 4,
CategoryId = DummySeed.Aspnet,
Rate = 5,
Title = "NLog z ASP.NET Core : Logowanie błędów w aplikacji",
Url = "https://cezarywalenciuk.pl/blog/programing/nlog-z-aspnet-core--logowanie-b%C5%82edow-w-aplikacji"
};
Post p5 = new Post()
{
Author = "Damian",
Date = DateTime.Now.AddMonths(-12),
Description = @"Logowanie działania aplikacji. Jak wiedzieć w końcu, gdy coś nie działa. Mój blog jest napisany w C# i działa po ASP.NET CORE. Jak to jednak bywa z napisaną przez siebie aplikacją pojawiają się błędy więc do bloga dodałem mechanizm logowania błędów. W taki sposób znalazłem wiele dziwnych przypadków uszkodzonych wpisów w formacie XML, które rozwalały Parser. Znalazłem też złe zbudowane przez ze mnie lista kursów. ",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
PostId = 5,
CategoryId = DummySeed.Aspnet,
Rate = 5,
Title = "NLog z ASP.NET Core : Logowanie błędów w aplikacji",
Url = "https://cezarywalenciuk.pl/blog/programing/nlog-z-aspnet-core--logowanie-b%C5%82edow-w-aplikacji"
};
Post p6 = new Post()
{
Author = "Damian",
Date = DateTime.Now.AddMonths(-8),
Description = @"W tym artykule zobaczymy jak zintegrować AutoMapper z ASP.NET CORE dla .NET 5, chociaż bądźmy szczerzy możesz skorzystać z tej biblioteki w każdym projekcie w C#.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
PostId = 6,
CategoryId = DummySeed.Aspnet,
Rate = 9,
Title = "AutoMapper z ASP.NET CORE czyli mapowanie klas",
Url = "https://cezarywalenciuk.pl/blog/programing/automapper-z-aspnet-core"
};
Post p7 = new Post()
{
Author = "Adrian",
Date = DateTime.Now.AddMonths(-14),
Description = @"Nagrywanie Gif - ów ? Robienie obrazków na bloga ? Jak to robić jeszcze szybciej ? ",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
PostId = 7,
CategoryId = DummySeed.TrikiZWindows,
Rate = 4,
Title = "ShareX : Lepszy PrintScreen oraz robienie Gif-ów twojego pulpitu?",
Url = "https://cezarywalenciuk.pl/blog/programing/sharex-lepszy-printscreen-oraz-robienie-gif-ow"
};
Post p8 = new Post()
{
Author = "Adrian",
Date = DateTime.Now.AddMonths(-15),
Description = @"Jak jeszcze lepiej ulepszyć system operacyjny Windows.
Czy być może programy tobie, które za chwilę to śmieci, które nie będą ci potrzebne?
Zazwyczaj w tym cyklu pokazuje programy, z które moim bardzo zmieniają przepływ mojej pracy.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
PostId = 8,
CategoryId = DummySeed.TrikiZWindows,
Rate = 5,
Title = "QuickLook, TeraCopy, ProcessExplorer czy to potrzebne jest ?",
Url = "https://cezarywalenciuk.pl/blog/programing/sharex-lepszy-printscreen-oraz-robienie-gif-ow"
};
Post p9 = new Post()
{
Author = "Adrian",
Date = DateTime.Now.AddMonths(-15),
Description = @"Jak jeszcze lepiej ulepszyć system operacyjny Windows.
Czy być może programy tobie, które za chwilę to śmieci, które nie będą ci potrzebne?
Zazwyczaj w tym cyklu pokazuje programy, z które moim bardzo zmieniają przepływ mojej pracy.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
PostId = 9,
CategoryId = DummySeed.Docker,
Rate = 9,
Title = "Docker File dla Go, ASP.NET Core, .NET 5, Java Spring, NodeJS, Python",
Url = "https://cezarywalenciuk.pl/blog/programing/docker-file-dla-go-aspnet-core-net-5-java-spring-nodejs-python"
};
List<Post> p = new List<Post>();
p.Add(p1); p.Add(p3);
p.Add(p2); p.Add(p4);
p.Add(p5); p.Add(p6);
p.Add(p8); p.Add(p7);
p.Add(p9);
return p;
}
}
\
public class DummyWebinars
{
public static List<Webinar> Get()
{
List<Webinar> w = new List<Webinar>();
var w1 = new Webinar()
{
Title = "Aplikacja C# od Zera Architektura, CQRS, Dobre praktyki",
AlreadyHappend = false,
Date = DateTime.Now.AddDays(10),
Description = @"Ustalenie architektury nie jest prostym zadaniem. Każda decyzja może mieć wielkie komplikacje potem.",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
Id = 1,
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/17_apliacjacsharpodzeraarchitekturacqrs.jpg",
SlidesUrl = "",
WatchFacebookLink = "",
WatchYoutubeLink = "",
};
w.Add(w1);
var w2 = new Webinar()
{
Title = "Kubernetes i Docker : Wytłumacz mi i pokaż",
AlreadyHappend = false,
Date = DateTime.Now.AddDays(-40),
Description = @"Kontenery są tutaj. Kubernetes jest de facto platformą do ich uruchamiania i zarządzania.",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
Id = 2,
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/17_apliacjacsharpodzeraarchitekturacqrs.jpg",
SlidesUrl = "https://panniebieski.github.io/webinar-Kubernetes-Docker-Wytlumacz-mi-i-pokaz/",
WatchFacebookLink = "https://www.facebook.com/watch/live/?v=2775230679405348&ref=watch_permalink",
WatchYoutubeLink = "https://www.youtube.com/watch?v=7g00wOg9Jto",
};
w.Add(w2);
var w3 = new Webinar()
{
Title = "C# 9, Rekordy i duże zmiany w .NET 5",
AlreadyHappend = false,
Date = DateTime.Now.AddDays(-60),
Description = @"Jak utworzyć projekt w .NET 5?",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
Id = 3,
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg",
SlidesUrl = "https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/",
WatchFacebookLink = "https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink",
WatchYoutubeLink = "https://www.youtube.com/watch?v=ATbLEyd_1Kg",
};
w.Add(w3);
var w4 = new Webinar()
{
Title = "Szybki Trening Sql Server 2",
AlreadyHappend = false,
Date = DateTime.Now.AddDays(-70),
Description = @"Czasami jedyne czego potrzebujemy to dobrego przykładu.",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
Id = 4,
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg",
SlidesUrl = "https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/",
WatchFacebookLink = "https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink",
WatchYoutubeLink = "https://www.youtube.com/watch?v=ATbLEyd_1Kg",
};
w.Add(w4);
var w5 = new Webinar()
{
Title = "Pytania rekrutacyjne czyli dalsza kariera",
AlreadyHappend = false,
Date = DateTime.Now.AddDays(-90),
Description = @"Jak wygląda szukanie pracy jako programista w 2020 roku? Czy jest lepiej, czy jest gorzej?",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
Id = 5,
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg",
SlidesUrl = "https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/",
WatchFacebookLink = "https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink",
WatchYoutubeLink = "https://www.youtube.com/watch?v=ATbLEyd_1Kg",
};
w.Add(w5);
return w;
}
}
public class EduZbieraczContext : DbContext
{
public EduZbieraczContext(DbContextOptions<EduZbieraczContext> options)
: base(options)
{
}
public DbSet<Post> Posts { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Webinar> Webinars { get; set; }
public override Task<int> SaveChangesAsync
(CancellationToken cancellationToken = new CancellationToken())
{
foreach (var entry in ChangeTracker.Entries<AuditableEntity>())
{
switch (entry.State)
{
case EntityState.Added:
entry.Entity.CreatedDate = DateTime.Now;
break;
case EntityState.Modified:
entry.Entity.LastModifiedDate = DateTime.Now;
break;
}
}
return base.SaveChangesAsync(cancellationToken);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.
ApplyConfigurationsFromAssembly
(typeof(EduZbieraczContext).Assembly);
foreach (var item in DummyCategories.Get())
{
modelBuilder.Entity<Category>().HasData(item);
}
foreach (var item in DummyPosts.Get())
{
modelBuilder.Entity<Post>(b =>
{
b.HasData(item);
});
}
foreach (var item in DummyWebinars.Get())
{
modelBuilder.Entity<Webinar>().HasData(item);
}
}
public class PostConfiguration
: IEntityTypeConfiguration<Post>
{
public void Configure(EntityTypeBuilder<Post> builder)
{
builder.Property(e => e.Title)
.IsRequired()
.HasMaxLength(80);
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.
ApplyConfigurationsFromAssembly
(typeof(EduZbieraczContext).Assembly);
public class BaseRepository<T> : IAsyncRepository<T> where T : class
{
protected readonly EduZbieraczContext _dbContext;
public BaseRepository(EduZbieraczContext dbContext)
{
_dbContext = dbContext;
}
public async Task<T> AddAsync(T entity)
{
await _dbContext.Set<T>().AddAsync(entity);
await _dbContext.SaveChangesAsync();
return entity;
}
public async Task DeleteAsync(T entity)
{
_dbContext.Set<T>().Remove(entity);
await _dbContext.SaveChangesAsync();
}
public async Task<IReadOnlyList<T>> GetAllAsync()
{
return await _dbContext.Set<T>().ToListAsync();
}
public async Task<T> GetByIdAsync(int id)
{
return await _dbContext.Set<T>().FindAsync(id);
}
public async Task UpdateAsync(T entity)
{
_dbContext.Entry(entity).State = EntityState.Modified;
await _dbContext.SaveChangesAsync();
}
}
public class PostRepository : BaseRepository<Post>, IPostRepository
{
public PostRepository(EduZbieraczContext dbContext) : base(dbContext)
{ }
public Task<bool> IsNameAndAuthorAlreadyExist(string title, string author)
{
var matches = _dbContext.Posts.
Any(a => a.Title.Equals(title) && a.Author.Equals(author));
return Task.FromResult(matches);
}
}
public class CategoryRepository : BaseRepository<Category>, ICategoryRepository
{
public CategoryRepository(EduZbieraczContext dbContext) : base(dbContext)
{ }
public async Task<List<Category>> GetCategoriesWithPost
(SearchCategoryOptions searchCategory)
{
var allCategories = await _dbContext.Categories.Include(p => p.Posts).ToListAsync();
if (searchCategory == SearchCategoryOptions.FirstBestAllTheTime)
{
return GetOneMaxPost(allCategories);
}
else if (searchCategory == SearchCategoryOptions.FirstBestThisMonth)
{
DateTime d = DateTime.Now;
allCategories = allCategories.Where(c =>
c.Posts.Any(p => (p.Date.Month == d.Month && d.Year == p.Date.Year)))
.ToList();
return GetOneMaxPost(allCategories);
}
return allCategories;
}
private List<Category> GetOneMaxPost(List<Category> allCategories)
{
foreach (var c in allCategories)
{
Post max = null;
foreach (var p in c.Posts)
{
if (max == null)
{
max = p;
break;
}
if (max.Rate < p.Rate)
max = p;
}
c.Posts = new List<Post>();
if (max != null)
c.Posts.Add(max);
}
return allCategories;
}
}
public class WebinaryRepository : BaseRepository<Webinar>, IWebinaryRepository
{
public WebinaryRepository(EduZbieraczContext dbContext) : base(dbContext)
{ }
public async Task<List<Webinar>> GetPagedWebinarsForDate(SearchOptionsWebinars options,
int page, int pageSize, DateTime? date)
{
if (options == SearchOptionsWebinars.MonthAndYear && date.HasValue)
{
return await _dbContext.Webinars.Where(x => x.Date.Month == date.Value.Month
&& x.Date.Year == date.Value.Year)
.Skip((page - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
if (options == SearchOptionsWebinars.Year && date.HasValue)
{
return await _dbContext.Webinars.Where(x => x.Date.Year == date.Value.Year)
.Skip((page - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
if (options == SearchOptionsWebinars.Month && date.HasValue)
{
return await _dbContext.Webinars.Where(x => x.Date.Month == date.Value.Month)
.Skip((page - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
return await _dbContext.Webinars
.Skip((page - 1) * pageSize).Take(pageSize).AsNoTracking().ToListAsync();
}
public async Task<int> GetTotalCountOfWebinarsForDate(SearchOptionsWebinars options,
DateTime? date)
{
if (options == SearchOptionsWebinars.MonthAndYear && date.HasValue)
{
return await _dbContext.Webinars.CountAsync
(x => x.Date.Month == date.Value.Month
&& x.Date.Year == date.Value.Year);
}
if (options == SearchOptionsWebinars.Year && date.HasValue)
{
return await _dbContext.Webinars.CountAsync
(x => x.Date.Year == date.Value.Year);
}
if (options == SearchOptionsWebinars.Month && date.HasValue)
{
return await _dbContext.Webinars.CountAsync
(x => x.Date.Year == date.Value.Year);
}
return await _dbContext.Webinars.CountAsync();
}
}
public static class PersistenceWithEFRegistration
{
public static IServiceCollection AddPersistenceServices(this IServiceCollection services,
IConfiguration configuration)
{
services.AddDbContext<EduZbieraczContext>(options =>
options.UseSqlServer(configuration.
GetConnectionString("EduZbieraczConnectionString")));
services.AddScoped(typeof(IAsyncRepository<>), typeof(BaseRepository<>));
services.AddScoped<ICategoryRepository, CategoryRepository>();
services.AddScoped<IWebinaryRepository, WebinaryRepository>();
services.AddScoped<IPostRepository, IPostRepository>();
return services;
}
}
public class Startup
{
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddEduZbieraczApplication();
services.AddEduZbieraczPersistenceEFServices(Configuration);
}
public void ConfigureServices(IServiceCollection services)
{
services.AddEduZbieraczApplication();
services.AddEduZbieraczPersistenceEFServices(Configuration);
services.AddControllers();
services.AddCors(options =>
{
options.AddPolicy("Open",
builder => builder.AllowAnyOrigin()
.AllowAnyHeader().AllowAnyMethod());
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("Open");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
{
"ConnectionStrings": {
"EduZbieraczConnectionString": "Data Source=CEZMSI\SQLEXPRESS;
Initial Catalog=EduZbieracz;Integrated Security=True;Pooling=False"
}
}
public partial class Init : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Categories",
columns: table => new
{
CategoryId = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
CreatedBy = table.Column<string>(nullable: true),
CreatedDate = table.Column<DateTime>(nullable: false),
LastModifiedBy = table.Column<string>(nullable: true),
LastModifiedDate = table.Column<DateTime>(nullable: true),
Name = table.Column<string>(nullable: true),
DisplayName = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Categories", x => x.CategoryId);
});
migrationBuilder.CreateTable(
name: "Webinars",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(nullable: true),
Description = table.Column<string>(nullable: true),
ImageUrl = table.Column<string>(nullable: true),
FacebookEventUrl = table.Column<string>(nullable: true),
SlidesUrl = table.Column<string>(nullable: true),
WatchFacebookLink = table.Column<string>(nullable: true),
WatchYoutubeLink = table.Column<string>(nullable: true),
Date = table.Column<DateTime>(nullable: false),
AlreadyHappend = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Webinars", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Posts",
columns: table => new
{
PostId = table.Column<int>(nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Title = table.Column<string>(maxLength: 80, nullable: false),
Author = table.Column<string>(nullable: true),
Date = table.Column<DateTime>(nullable: false),
Description = table.Column<string>(nullable: true),
CategoryId = table.Column<int>(nullable: false),
ImageUrl = table.Column<string>(nullable: true),
Url = table.Column<string>(nullable: true),
Rate = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Posts", x => x.PostId);
table.ForeignKey(
name: "FK_Posts_Categories_CategoryId",
column: x => x.CategoryId,
principalTable: "Categories",
principalColumn: "CategoryId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.InsertData(
table: "Categories",
columns: new[] { "CategoryId", "CreatedBy", "CreatedDate", "DisplayName", "LastModifiedBy", "LastModifiedDate", "Name" },
values: new object[,]
{
{ 1, null, new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), "C#", null, null, "CSharp" },
{ 3, null, new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), "Triki z Windows", null, null, "triki-z-windows" },
{ 2, null, new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), "ASP.NET", null, null, "aspnet" },
{ 4, null, new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), "Docker", null, null, "docker" },
{ 5, null, new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), "Filozofia", null, null, "filozofia" }
});
migrationBuilder.InsertData(
table: "Webinars",
columns: new[] { "Id", "AlreadyHappend", "Date", "Description", "FacebookEventUrl", "ImageUrl", "SlidesUrl", "Title", "WatchFacebookLink", "WatchYoutubeLink" },
values: new object[,]
{
{ 1, false, new DateTime(2021, 1, 28, 10, 3, 58, 620, DateTimeKind.Local).AddTicks(5513), "Ustalenie architektury nie jest prostym zadaniem. Każda decyzja może mieć wielkie komplikacje potem.", "https://www.facebook.com/events/407358067213893/", "https://cezarywalenciuk.pl/posts/fileswebinars/17_apliacjacsharpodzeraarchitekturacqrs.jpg", "", "Aplikacja C# od Zera Architektura, CQRS, Dobre praktyki", "", "" },
{ 2, false, new DateTime(2020, 12, 9, 10, 3, 58, 621, DateTimeKind.Local).AddTicks(7359), "Kontenery są tutaj. Kubernetes jest de facto platformą do ich uruchamiania i zarządzania.", "https://www.facebook.com/events/407358067213893/", "https://cezarywalenciuk.pl/posts/fileswebinars/17_apliacjacsharpodzeraarchitekturacqrs.jpg", "https://panniebieski.github.io/webinar-Kubernetes-Docker-Wytlumacz-mi-i-pokaz/", "Kubernetes i Docker : Wytłumacz mi i pokaż", "https://www.facebook.com/watch/live/?v=2775230679405348&ref=watch_permalink", "https://www.youtube.com/watch?v=7g00wOg9Jto" },
{ 3, false, new DateTime(2020, 11, 19, 10, 3, 58, 621, DateTimeKind.Local).AddTicks(7537), "Jak utworzyć projekt w .NET 5?", "https://www.facebook.com/events/407358067213893/", "https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg", "https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/", "C# 9, Rekordy i duże zmiany w .NET 5", "https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink", "https://www.youtube.com/watch?v=ATbLEyd_1Kg" },
{ 4, false, new DateTime(2020, 11, 9, 10, 3, 58, 621, DateTimeKind.Local).AddTicks(7547), "Czasami jedyne czego potrzebujemy to dobrego przykładu.", "https://www.facebook.com/events/407358067213893/", "https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg", "https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/", "Szybki Trening Sql Server 2", "https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink", "https://www.youtube.com/watch?v=ATbLEyd_1Kg" },
{ 5, false, new DateTime(2020, 10, 20, 10, 3, 58, 621, DateTimeKind.Local).AddTicks(7554), "Jak wygląda szukanie pracy jako programista w 2020 roku? Czy jest lepiej, czy jest gorzej?", "https://www.facebook.com/events/407358067213893/", "https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg", "https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/", "Pytania rekrutacyjne czyli dalsza kariera", "https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink", "https://www.youtube.com/watch?v=ATbLEyd_1Kg" }
});
migrationBuilder.InsertData(
table: "Posts",
columns: new[] { "PostId", "Author", "CategoryId", "Date", "Description", "ImageUrl", "Rate", "Title", "Url" },
values: new object[,]
{
{ 8, "Adrian", 3, new DateTime(2019, 10, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7507), @"Jak jeszcze lepiej ulepszyć system operacyjny Windows.
Czy być może programy tobie, które za chwilę to śmieci, które nie będą ci potrzebne?
Zazwyczaj w tym cyklu pokazuje programy, z które moim bardzo zmieniają przepływ mojej pracy.", "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png", 5, "QuickLook, TeraCopy, ProcessExplorer czy to potrzebne jest ?", "https://cezarywalenciuk.pl/blog/programing/sharex-lepszy-printscreen-oraz-robienie-gif-ow" },
{ 7, "Adrian", 3, new DateTime(2019, 11, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7503), "Nagrywanie Gif - ów ? Robienie obrazków na bloga ? Jak to robić jeszcze szybciej ? ", "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png", 4, "ShareX : Lepszy PrintScreen oraz robienie Gif-ów twojego pulpitu?", "https://cezarywalenciuk.pl/blog/programing/sharex-lepszy-printscreen-oraz-robienie-gif-ow" },
{ 1, "Damian", 2, new DateTime(2020, 7, 18, 10, 3, 58, 614, DateTimeKind.Local).AddTicks(6597), @"Nasze aplikacje ASP.NET CORE coraz częściej są tylko aplikacją REST. To oczywiście wymaga Walidacji po stronie klienta i po stronie serwera
Jak taką walidację jak najszybciej zrobić.Może przecież sam napisać takie warunki,
ale przy dużej ilości klas,
które występują jako parametry mija się to z celem.
Możesz też skorzystać z atrybutów i oznaczyć reguły do każdej właściwości.", "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png", 8, "Walidacja z FluentValidation w ASP.NET Core + Swagger", "https://cezarywalenciuk.pl/blog/programing/walidacja-z-fluentvalidation-waspnet-core--swagger" },
{ 2, "Damian", 2, new DateTime(2020, 7, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7347), "Programiści codziennie tworzą jakąś aplikację sieciową typu REST. Teraz nastaje pytanie, jak najlepiej zrozumieć jak dane API działa. Do tego mamy dokumentacje, ale jeśli pracujesz w szybkich, zamkniętych projektach to takiej dokumentacji może nie być.", "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png", 7, "Swagger UI : Dokumentowanie API w ASP.NET CORE", "https://cezarywalenciuk.pl/blog/programing/swagger-ui--dokumentowanie-api-w-aspnet-core" },
{ 4, "Damian", 2, new DateTime(2020, 1, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7491), "Logowanie działania aplikacji. Jak wiedzieć w końcu, gdy coś nie działa. Mój blog jest napisany w C# i działa po ASP.NET CORE. Jak to jednak bywa z napisaną przez siebie aplikacją pojawiają się błędy więc do bloga dodałem mechanizm logowania błędów. W taki sposób znalazłem wiele dziwnych przypadków uszkodzonych wpisów w formacie XML, które rozwalały Parser. Znalazłem też złe zbudowane przez ze mnie lista kursów. ", "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png", 5, "NLog z ASP.NET Core : Logowanie błędów w aplikacji", "https://cezarywalenciuk.pl/blog/programing/nlog-z-aspnet-core--logowanie-b%C5%82edow-w-aplikacji" },
{ 5, "Damian", 2, new DateTime(2020, 1, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7495), "Logowanie działania aplikacji. Jak wiedzieć w końcu, gdy coś nie działa. Mój blog jest napisany w C# i działa po ASP.NET CORE. Jak to jednak bywa z napisaną przez siebie aplikacją pojawiają się błędy więc do bloga dodałem mechanizm logowania błędów. W taki sposób znalazłem wiele dziwnych przypadków uszkodzonych wpisów w formacie XML, które rozwalały Parser. Znalazłem też złe zbudowane przez ze mnie lista kursów. ", "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png", 5, "NLog z ASP.NET Core : Logowanie błędów w aplikacji", "https://cezarywalenciuk.pl/blog/programing/nlog-z-aspnet-core--logowanie-b%C5%82edow-w-aplikacji" },
{ 6, "Damian", 2, new DateTime(2020, 5, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7499), "W tym artykule zobaczymy jak zintegrować AutoMapper z ASP.NET CORE dla .NET 5, chociaż bądźmy szczerzy możesz skorzystać z tej biblioteki w każdym projekcie w C#.", "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png", 9, "AutoMapper z ASP.NET CORE czyli mapowanie klas", "https://cezarywalenciuk.pl/blog/programing/automapper-z-aspnet-core" },
{ 9, "Adrian", 4, new DateTime(2019, 10, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7512), @"Jak jeszcze lepiej ulepszyć system operacyjny Windows.
Czy być może programy tobie, które za chwilę to śmieci, które nie będą ci potrzebne?
Zazwyczaj w tym cyklu pokazuje programy, z które moim bardzo zmieniają przepływ mojej pracy.", "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png", 9, "Docker File dla Go, ASP.NET Core, .NET 5, Java Spring, NodeJS, Python", "https://cezarywalenciuk.pl/blog/programing/docker-file-dla-go-aspnet-core-net-5-java-spring-nodejs-python" },
{ 3, "Stefan", 5, new DateTime(2020, 1, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7480), @"W pod koniec roku 2017 zacząłem ćwiczyć. Proste ćwiczenia rzeczywiście robią różnice, gdy masz siedzący tryb życia. A co z bieganiem ?
Pamiętam jak pierwszy raz na bieżni nie byłem w stanie wytrzymać 5 minut normalnego spaceru. Powoli z tygodnia na dzień zacząłem sobie stawiać wyższe progi i tak odkryłem, że o ile jest to na początku bolesne to jak twoje ciało da Ci te endorfiny to już...aż chce się biegać więcej. ", "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png", 5, "Bieganie jak się do tego zmotywować : Zdrowie Programisty", "https://cezarywalenciuk.pl/blog/programing/bieganie-jak-sie-do-tego-zmotywowac--zdrowie-programisty" }
});
migrationBuilder.CreateIndex(
name: "IX_Posts_CategoryId",
table: "Posts",
column: "CategoryId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Posts");
migrationBuilder.DropTable(
name: "Webinars");
migrationBuilder.DropTable(
name: "Categories");
}
}
// <auto-generated />
using System;
using EduZbieracz.Persistence;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace EduZbieracz.Persistence.EF.Migrations
{
[DbContext(typeof(EduZbieraczContext))]
partial class EduZbieraczContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.11")
.HasAnnotation("Relational:MaxIdentifierLength", 128)
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
modelBuilder.Entity("EduZbieracz.Domain.Entities.Category", b =>
{
b.Property<int>("CategoryId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("CreatedBy")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreatedDate")
.HasColumnType("datetime2");
b.Property<string>("DisplayName")
.HasColumnType("nvarchar(max)");
b.Property<string>("LastModifiedBy")
.HasColumnType("nvarchar(max)");
b.Property<DateTime?>("LastModifiedDate")
.HasColumnType("datetime2");
b.Property<string>("Name")
.HasColumnType("nvarchar(max)");
b.HasKey("CategoryId");
b.ToTable("Categories");
b.HasData(
new
{
CategoryId = 1,
CreatedDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
DisplayName = "C#",
Name = "CSharp"
},
new
{
CategoryId = 3,
CreatedDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
DisplayName = "Triki z Windows",
Name = "triki-z-windows"
},
new
{
CategoryId = 2,
CreatedDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
DisplayName = "ASP.NET",
Name = "aspnet"
},
new
{
CategoryId = 4,
CreatedDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
DisplayName = "Docker",
Name = "docker"
},
new
{
CategoryId = 5,
CreatedDate = new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified),
DisplayName = "Filozofia",
Name = "filozofia"
});
});
modelBuilder.Entity("EduZbieracz.Domain.Entities.Post", b =>
{
b.Property<int>("PostId")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<string>("Author")
.HasColumnType("nvarchar(max)");
b.Property<int>("CategoryId")
.HasColumnType("int");
b.Property<DateTime>("Date")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("ImageUrl")
.HasColumnType("nvarchar(max)");
b.Property<int>("Rate")
.HasColumnType("int");
b.Property<string>("Title")
.IsRequired()
.HasColumnType("nvarchar(80)")
.HasMaxLength(80);
b.Property<string>("Url")
.HasColumnType("nvarchar(max)");
b.HasKey("PostId");
b.HasIndex("CategoryId");
b.ToTable("Posts");
b.HasData(
new
{
PostId = 1,
Author = "Damian",
CategoryId = 2,
Date = new DateTime(2020, 7, 18, 10, 3, 58, 614, DateTimeKind.Local).AddTicks(6597),
Description = @"Nasze aplikacje ASP.NET CORE coraz częściej są tylko aplikacją REST. To oczywiście wymaga Walidacji po stronie klienta i po stronie serwera
Jak taką walidację jak najszybciej zrobić.Może przecież sam napisać takie warunki,
ale przy dużej ilości klas,
które występują jako parametry mija się to z celem.
Możesz też skorzystać z atrybutów i oznaczyć reguły do każdej właściwości.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
Rate = 8,
Title = "Walidacja z FluentValidation w ASP.NET Core + Swagger",
Url = "https://cezarywalenciuk.pl/blog/programing/walidacja-z-fluentvalidation-waspnet-core--swagger"
},
new
{
PostId = 3,
Author = "Stefan",
CategoryId = 5,
Date = new DateTime(2020, 1, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7480),
Description = @"W pod koniec roku 2017 zacząłem ćwiczyć. Proste ćwiczenia rzeczywiście robią różnice, gdy masz siedzący tryb życia. A co z bieganiem ?
Pamiętam jak pierwszy raz na bieżni nie byłem w stanie wytrzymać 5 minut normalnego spaceru. Powoli z tygodnia na dzień zacząłem sobie stawiać wyższe progi i tak odkryłem, że o ile jest to na początku bolesne to jak twoje ciało da Ci te endorfiny to już...aż chce się biegać więcej. ",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
Rate = 5,
Title = "Bieganie jak się do tego zmotywować : Zdrowie Programisty",
Url = "https://cezarywalenciuk.pl/blog/programing/bieganie-jak-sie-do-tego-zmotywowac--zdrowie-programisty"
},
new
{
PostId = 2,
Author = "Damian",
CategoryId = 2,
Date = new DateTime(2020, 7, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7347),
Description = "Programiści codziennie tworzą jakąś aplikację sieciową typu REST. Teraz nastaje pytanie, jak najlepiej zrozumieć jak dane API działa. Do tego mamy dokumentacje, ale jeśli pracujesz w szybkich, zamkniętych projektach to takiej dokumentacji może nie być.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
Rate = 7,
Title = "Swagger UI : Dokumentowanie API w ASP.NET CORE",
Url = "https://cezarywalenciuk.pl/blog/programing/swagger-ui--dokumentowanie-api-w-aspnet-core"
},
new
{
PostId = 4,
Author = "Damian",
CategoryId = 2,
Date = new DateTime(2020, 1, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7491),
Description = "Logowanie działania aplikacji. Jak wiedzieć w końcu, gdy coś nie działa. Mój blog jest napisany w C# i działa po ASP.NET CORE. Jak to jednak bywa z napisaną przez siebie aplikacją pojawiają się błędy więc do bloga dodałem mechanizm logowania błędów. W taki sposób znalazłem wiele dziwnych przypadków uszkodzonych wpisów w formacie XML, które rozwalały Parser. Znalazłem też złe zbudowane przez ze mnie lista kursów. ",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
Rate = 5,
Title = "NLog z ASP.NET Core : Logowanie błędów w aplikacji",
Url = "https://cezarywalenciuk.pl/blog/programing/nlog-z-aspnet-core--logowanie-b%C5%82edow-w-aplikacji"
},
new
{
PostId = 5,
Author = "Damian",
CategoryId = 2,
Date = new DateTime(2020, 1, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7495),
Description = "Logowanie działania aplikacji. Jak wiedzieć w końcu, gdy coś nie działa. Mój blog jest napisany w C# i działa po ASP.NET CORE. Jak to jednak bywa z napisaną przez siebie aplikacją pojawiają się błędy więc do bloga dodałem mechanizm logowania błędów. W taki sposób znalazłem wiele dziwnych przypadków uszkodzonych wpisów w formacie XML, które rozwalały Parser. Znalazłem też złe zbudowane przez ze mnie lista kursów. ",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
Rate = 5,
Title = "NLog z ASP.NET Core : Logowanie błędów w aplikacji",
Url = "https://cezarywalenciuk.pl/blog/programing/nlog-z-aspnet-core--logowanie-b%C5%82edow-w-aplikacji"
},
new
{
PostId = 6,
Author = "Damian",
CategoryId = 2,
Date = new DateTime(2020, 5, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7499),
Description = "W tym artykule zobaczymy jak zintegrować AutoMapper z ASP.NET CORE dla .NET 5, chociaż bądźmy szczerzy możesz skorzystać z tej biblioteki w każdym projekcie w C#.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
Rate = 9,
Title = "AutoMapper z ASP.NET CORE czyli mapowanie klas",
Url = "https://cezarywalenciuk.pl/blog/programing/automapper-z-aspnet-core"
},
new
{
PostId = 8,
Author = "Adrian",
CategoryId = 3,
Date = new DateTime(2019, 10, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7507),
Description = @"Jak jeszcze lepiej ulepszyć system operacyjny Windows.
Czy być może programy tobie, które za chwilę to śmieci, które nie będą ci potrzebne?
Zazwyczaj w tym cyklu pokazuje programy, z które moim bardzo zmieniają przepływ mojej pracy.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
Rate = 5,
Title = "QuickLook, TeraCopy, ProcessExplorer czy to potrzebne jest ?",
Url = "https://cezarywalenciuk.pl/blog/programing/sharex-lepszy-printscreen-oraz-robienie-gif-ow"
},
new
{
PostId = 7,
Author = "Adrian",
CategoryId = 3,
Date = new DateTime(2019, 11, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7503),
Description = "Nagrywanie Gif - ów ? Robienie obrazków na bloga ? Jak to robić jeszcze szybciej ? ",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
Rate = 4,
Title = "ShareX : Lepszy PrintScreen oraz robienie Gif-ów twojego pulpitu?",
Url = "https://cezarywalenciuk.pl/blog/programing/sharex-lepszy-printscreen-oraz-robienie-gif-ow"
},
new
{
PostId = 9,
Author = "Adrian",
CategoryId = 4,
Date = new DateTime(2019, 10, 18, 10, 3, 58, 617, DateTimeKind.Local).AddTicks(7512),
Description = @"Jak jeszcze lepiej ulepszyć system operacyjny Windows.
Czy być może programy tobie, które za chwilę to śmieci, które nie będą ci potrzebne?
Zazwyczaj w tym cyklu pokazuje programy, z które moim bardzo zmieniają przepływ mojej pracy.",
ImageUrl = "https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png",
Rate = 9,
Title = "Docker File dla Go, ASP.NET Core, .NET 5, Java Spring, NodeJS, Python",
Url = "https://cezarywalenciuk.pl/blog/programing/docker-file-dla-go-aspnet-core-net-5-java-spring-nodejs-python"
});
});
modelBuilder.Entity("EduZbieracz.Domain.Entities.Webinar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("int")
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
b.Property<bool>("AlreadyHappend")
.HasColumnType("bit");
b.Property<DateTime>("Date")
.HasColumnType("datetime2");
b.Property<string>("Description")
.HasColumnType("nvarchar(max)");
b.Property<string>("FacebookEventUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("ImageUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("SlidesUrl")
.HasColumnType("nvarchar(max)");
b.Property<string>("Title")
.HasColumnType("nvarchar(max)");
b.Property<string>("WatchFacebookLink")
.HasColumnType("nvarchar(max)");
b.Property<string>("WatchYoutubeLink")
.HasColumnType("nvarchar(max)");
b.HasKey("Id");
b.ToTable("Webinars");
b.HasData(
new
{
Id = 1,
AlreadyHappend = false,
Date = new DateTime(2021, 1, 28, 10, 3, 58, 620, DateTimeKind.Local).AddTicks(5513),
Description = "Ustalenie architektury nie jest prostym zadaniem. Każda decyzja może mieć wielkie komplikacje potem.",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/17_apliacjacsharpodzeraarchitekturacqrs.jpg",
SlidesUrl = "",
Title = "Aplikacja C# od Zera Architektura, CQRS, Dobre praktyki",
WatchFacebookLink = "",
WatchYoutubeLink = ""
},
new
{
Id = 2,
AlreadyHappend = false,
Date = new DateTime(2020, 12, 9, 10, 3, 58, 621, DateTimeKind.Local).AddTicks(7359),
Description = "Kontenery są tutaj. Kubernetes jest de facto platformą do ich uruchamiania i zarządzania.",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/17_apliacjacsharpodzeraarchitekturacqrs.jpg",
SlidesUrl = "https://panniebieski.github.io/webinar-Kubernetes-Docker-Wytlumacz-mi-i-pokaz/",
Title = "Kubernetes i Docker : Wytłumacz mi i pokaż",
WatchFacebookLink = "https://www.facebook.com/watch/live/?v=2775230679405348&ref=watch_permalink",
WatchYoutubeLink = "https://www.youtube.com/watch?v=7g00wOg9Jto"
},
new
{
Id = 3,
AlreadyHappend = false,
Date = new DateTime(2020, 11, 19, 10, 3, 58, 621, DateTimeKind.Local).AddTicks(7537),
Description = "Jak utworzyć projekt w .NET 5?",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg",
SlidesUrl = "https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/",
Title = "C# 9, Rekordy i duże zmiany w .NET 5",
WatchFacebookLink = "https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink",
WatchYoutubeLink = "https://www.youtube.com/watch?v=ATbLEyd_1Kg"
},
new
{
Id = 4,
AlreadyHappend = false,
Date = new DateTime(2020, 11, 9, 10, 3, 58, 621, DateTimeKind.Local).AddTicks(7547),
Description = "Czasami jedyne czego potrzebujemy to dobrego przykładu.",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg",
SlidesUrl = "https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/",
Title = "Szybki Trening Sql Server 2",
WatchFacebookLink = "https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink",
WatchYoutubeLink = "https://www.youtube.com/watch?v=ATbLEyd_1Kg"
},
new
{
Id = 5,
AlreadyHappend = false,
Date = new DateTime(2020, 10, 20, 10, 3, 58, 621, DateTimeKind.Local).AddTicks(7554),
Description = "Jak wygląda szukanie pracy jako programista w 2020 roku? Czy jest lepiej, czy jest gorzej?",
FacebookEventUrl = "https://www.facebook.com/events/407358067213893/",
ImageUrl = "https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg",
SlidesUrl = "https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/",
Title = "Pytania rekrutacyjne czyli dalsza kariera",
WatchFacebookLink = "https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink",
WatchYoutubeLink = "https://www.youtube.com/watch?v=ATbLEyd_1Kg"
});
});
modelBuilder.Entity("EduZbieracz.Domain.Entities.Post", b =>
{
b.HasOne("EduZbieracz.Domain.Entities.Category", "Category")
.WithMany("Posts")
.HasForeignKey("CategoryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
#pragma warning restore 612, 618
}
}
}
IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL
BEGIN
CREATE TABLE [__EFMigrationsHistory] (
[MigrationId] nvarchar(150) NOT NULL,
[ProductVersion] nvarchar(32) NOT NULL,
CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
);
END;
GO
CREATE TABLE [Categories] (
[CategoryId] int NOT NULL IDENTITY,
[CreatedBy] nvarchar(max) NULL,
[CreatedDate] datetime2 NOT NULL,
[LastModifiedBy] nvarchar(max) NULL,
[LastModifiedDate] datetime2 NULL,
[Name] nvarchar(max) NULL,
[DisplayName] nvarchar(max) NULL,
CONSTRAINT [PK_Categories] PRIMARY KEY ([CategoryId])
);
GO
CREATE TABLE [Webinars] (
[Id] int NOT NULL IDENTITY,
[Title] nvarchar(max) NULL,
[Description] nvarchar(max) NULL,
[ImageUrl] nvarchar(max) NULL,
[FacebookEventUrl] nvarchar(max) NULL,
[SlidesUrl] nvarchar(max) NULL,
[WatchFacebookLink] nvarchar(max) NULL,
[WatchYoutubeLink] nvarchar(max) NULL,
[Date] datetime2 NOT NULL,
[AlreadyHappend] bit NOT NULL,
CONSTRAINT [PK_Webinars] PRIMARY KEY ([Id])
);
GO
CREATE TABLE [Posts] (
[PostId] int NOT NULL IDENTITY,
[Title] nvarchar(80) NOT NULL,
[Author] nvarchar(max) NULL,
[Date] datetime2 NOT NULL,
[Description] nvarchar(max) NULL,
[CategoryId] int NOT NULL,
[ImageUrl] nvarchar(max) NULL,
[Url] nvarchar(max) NULL,
[Rate] int NOT NULL,
CONSTRAINT [PK_Posts] PRIMARY KEY ([PostId]),
CONSTRAINT [FK_Posts_Categories_CategoryId] FOREIGN KEY ([CategoryId]) REFERENCES [Categories] ([CategoryId]) ON DELETE CASCADE
);
GO
IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'CategoryId', N'CreatedBy', N'CreatedDate', N'DisplayName', N'LastModifiedBy', N'LastModifiedDate', N'Name') AND [object_id] = OBJECT_ID(N'[Categories]'))
SET IDENTITY_INSERT [Categories] ON;
INSERT INTO [Categories] ([CategoryId], [CreatedBy], [CreatedDate], [DisplayName], [LastModifiedBy], [LastModifiedDate], [Name])
VALUES (1, NULL, '0001-01-01T00:00:00.0000000', N'C#', NULL, NULL, N'CSharp'),
(3, NULL, '0001-01-01T00:00:00.0000000', N'Triki z Windows', NULL, NULL, N'triki-z-windows'),
(2, NULL, '0001-01-01T00:00:00.0000000', N'ASP.NET', NULL, NULL, N'aspnet'),
(4, NULL, '0001-01-01T00:00:00.0000000', N'Docker', NULL, NULL, N'docker'),
(5, NULL, '0001-01-01T00:00:00.0000000', N'Filozofia', NULL, NULL, N'filozofia');
IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'CategoryId', N'CreatedBy', N'CreatedDate', N'DisplayName', N'LastModifiedBy', N'LastModifiedDate', N'Name') AND [object_id] = OBJECT_ID(N'[Categories]'))
SET IDENTITY_INSERT [Categories] OFF;
GO
IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'AlreadyHappend', N'Date', N'Description', N'FacebookEventUrl', N'ImageUrl', N'SlidesUrl', N'Title', N'WatchFacebookLink', N'WatchYoutubeLink') AND [object_id] = OBJECT_ID(N'[Webinars]'))
SET IDENTITY_INSERT [Webinars] ON;
INSERT INTO [Webinars] ([Id], [AlreadyHappend], [Date], [Description], [FacebookEventUrl], [ImageUrl], [SlidesUrl], [Title], [WatchFacebookLink], [WatchYoutubeLink])
VALUES (1, CAST(0 AS bit), '2021-01-28T10:03:58.6205513+01:00', N'Ustalenie architektury nie jest prostym zadaniem. Każda decyzja może mieć wielkie komplikacje potem.', N'https://www.facebook.com/events/407358067213893/', N'https://cezarywalenciuk.pl/posts/fileswebinars/17_apliacjacsharpodzeraarchitekturacqrs.jpg', N'', N'Aplikacja C# od Zera Architektura, CQRS, Dobre praktyki', N'', N''),
(2, CAST(0 AS bit), '2020-12-09T10:03:58.6217359+01:00', N'Kontenery są tutaj. Kubernetes jest de facto platformą do ich uruchamiania i zarządzania.', N'https://www.facebook.com/events/407358067213893/', N'https://cezarywalenciuk.pl/posts/fileswebinars/17_apliacjacsharpodzeraarchitekturacqrs.jpg', N'https://panniebieski.github.io/webinar-Kubernetes-Docker-Wytlumacz-mi-i-pokaz/', N'Kubernetes i Docker : Wytłumacz mi i pokaż', N'https://www.facebook.com/watch/live/?v=2775230679405348&ref=watch_permalink', N'https://www.youtube.com/watch?v=7g00wOg9Jto'),
(3, CAST(0 AS bit), '2020-11-19T10:03:58.6217537+01:00', N'Jak utworzyć projekt w .NET 5?', N'https://www.facebook.com/events/407358067213893/', N'https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg', N'https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/', N'C# 9, Rekordy i duże zmiany w .NET 5', N'https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink', N'https://www.youtube.com/watch?v=ATbLEyd_1Kg'),
(4, CAST(0 AS bit), '2020-11-09T10:03:58.6217547+01:00', N'Czasami jedyne czego potrzebujemy to dobrego przykładu.', N'https://www.facebook.com/events/407358067213893/', N'https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg', N'https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/', N'Szybki Trening Sql Server 2', N'https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink', N'https://www.youtube.com/watch?v=ATbLEyd_1Kg'),
(5, CAST(0 AS bit), '2020-10-20T10:03:58.6217554+01:00', N'Jak wygląda szukanie pracy jako programista w 2020 roku? Czy jest lepiej, czy jest gorzej?', N'https://www.facebook.com/events/407358067213893/', N'https://cezarywalenciuk.pl/posts/fileswebinars/15_csharpirekordy.jpg', N'https://panniebieski.github.io/webinar_CSharp9-Rekordy-i-duze-zamiany-w-net-5/', N'Pytania rekrutacyjne czyli dalsza kariera', N'https://www.facebook.com/watch/live/?v=2835303250091399&ref=watch_permalink', N'https://www.youtube.com/watch?v=ATbLEyd_1Kg');
IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'Id', N'AlreadyHappend', N'Date', N'Description', N'FacebookEventUrl', N'ImageUrl', N'SlidesUrl', N'Title', N'WatchFacebookLink', N'WatchYoutubeLink') AND [object_id] = OBJECT_ID(N'[Webinars]'))
SET IDENTITY_INSERT [Webinars] OFF;
GO
IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'PostId', N'Author', N'CategoryId', N'Date', N'Description', N'ImageUrl', N'Rate', N'Title', N'Url') AND [object_id] = OBJECT_ID(N'[Posts]'))
SET IDENTITY_INSERT [Posts] ON;
INSERT INTO [Posts] ([PostId], [Author], [CategoryId], [Date], [Description], [ImageUrl], [Rate], [Title], [Url])
VALUES (8, N'Adrian', 3, '2019-10-18T10:03:58.6177507+01:00', N'Jak jeszcze lepiej ulepszyć system operacyjny Windows.
Czy być może programy tobie, które za chwilę to śmieci, które nie będą ci potrzebne?
Zazwyczaj w tym cyklu pokazuje programy, z które moim bardzo zmieniają przepływ mojej pracy.', N'https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png', 5, N'QuickLook, TeraCopy, ProcessExplorer czy to potrzebne jest ?', N'https://cezarywalenciuk.pl/blog/programing/sharex-lepszy-printscreen-oraz-robienie-gif-ow'),
(7, N'Adrian', 3, '2019-11-18T10:03:58.6177503+01:00', N'Nagrywanie Gif - ów ? Robienie obrazków na bloga ? Jak to robić jeszcze szybciej ? ', N'https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png', 4, N'ShareX : Lepszy PrintScreen oraz robienie Gif-ów twojego pulpitu?', N'https://cezarywalenciuk.pl/blog/programing/sharex-lepszy-printscreen-oraz-robienie-gif-ow'),
(1, N'Damian', 2, '2020-07-18T10:03:58.6146597+01:00', N'Nasze aplikacje ASP.NET CORE coraz częściej są tylko aplikacją REST. To oczywiście wymaga Walidacji po stronie klienta i po stronie serwera
Jak taką walidację jak najszybciej zrobić.Może przecież sam napisać takie warunki,
ale przy dużej ilości klas,
które występują jako parametry mija się to z celem.
Możesz też skorzystać z atrybutów i oznaczyć reguły do każdej właściwości.', N'https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png', 8, N'Walidacja z FluentValidation w ASP.NET Core + Swagger', N'https://cezarywalenciuk.pl/blog/programing/walidacja-z-fluentvalidation-waspnet-core--swagger'),
(2, N'Damian', 2, '2020-07-18T10:03:58.6177347+01:00', N'Programiści codziennie tworzą jakąś aplikację sieciową typu REST. Teraz nastaje pytanie, jak najlepiej zrozumieć jak dane API działa. Do tego mamy dokumentacje, ale jeśli pracujesz w szybkich, zamkniętych projektach to takiej dokumentacji może nie być.', N'https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png', 7, N'Swagger UI : Dokumentowanie API w ASP.NET CORE', N'https://cezarywalenciuk.pl/blog/programing/swagger-ui--dokumentowanie-api-w-aspnet-core'),
(4, N'Damian', 2, '2020-01-18T10:03:58.6177491+01:00', N'Logowanie działania aplikacji. Jak wiedzieć w końcu, gdy coś nie działa. Mój blog jest napisany w C# i działa po ASP.NET CORE. Jak to jednak bywa z napisaną przez siebie aplikacją pojawiają się błędy więc do bloga dodałem mechanizm logowania błędów. W taki sposób znalazłem wiele dziwnych przypadków uszkodzonych wpisów w formacie XML, które rozwalały Parser. Znalazłem też złe zbudowane przez ze mnie lista kursów. ', N'https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png', 5, N'NLog z ASP.NET Core : Logowanie błędów w aplikacji', N'https://cezarywalenciuk.pl/blog/programing/nlog-z-aspnet-core--logowanie-b%C5%82edow-w-aplikacji'),
(5, N'Damian', 2, '2020-01-18T10:03:58.6177495+01:00', N'Logowanie działania aplikacji. Jak wiedzieć w końcu, gdy coś nie działa. Mój blog jest napisany w C# i działa po ASP.NET CORE. Jak to jednak bywa z napisaną przez siebie aplikacją pojawiają się błędy więc do bloga dodałem mechanizm logowania błędów. W taki sposób znalazłem wiele dziwnych przypadków uszkodzonych wpisów w formacie XML, które rozwalały Parser. Znalazłem też złe zbudowane przez ze mnie lista kursów. ', N'https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png', 5, N'NLog z ASP.NET Core : Logowanie błędów w aplikacji', N'https://cezarywalenciuk.pl/blog/programing/nlog-z-aspnet-core--logowanie-b%C5%82edow-w-aplikacji'),
(6, N'Damian', 2, '2020-05-18T10:03:58.6177499+01:00', N'W tym artykule zobaczymy jak zintegrować AutoMapper z ASP.NET CORE dla .NET 5, chociaż bądźmy szczerzy możesz skorzystać z tej biblioteki w każdym projekcie w C#.', N'https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png', 9, N'AutoMapper z ASP.NET CORE czyli mapowanie klas', N'https://cezarywalenciuk.pl/blog/programing/automapper-z-aspnet-core'),
(9, N'Adrian', 4, '2019-10-18T10:03:58.6177512+01:00', N'Jak jeszcze lepiej ulepszyć system operacyjny Windows.
Czy być może programy tobie, które za chwilę to śmieci, które nie będą ci potrzebne?
Zazwyczaj w tym cyklu pokazuje programy, z które moim bardzo zmieniają przepływ mojej pracy.', N'https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png', 9, N'Docker File dla Go, ASP.NET Core, .NET 5, Java Spring, NodeJS, Python', N'https://cezarywalenciuk.pl/blog/programing/docker-file-dla-go-aspnet-core-net-5-java-spring-nodejs-python'),
(3, N'Stefan', 5, '2020-01-18T10:03:58.6177480+01:00', N'W pod koniec roku 2017 zacząłem ćwiczyć. Proste ćwiczenia rzeczywiście robią różnice, gdy masz siedzący tryb życia. A co z bieganiem ?
Pamiętam jak pierwszy raz na bieżni nie byłem w stanie wytrzymać 5 minut normalnego spaceru. Powoli z tygodnia na dzień zacząłem sobie stawiać wyższe progi i tak odkryłem, że o ile jest to na początku bolesne to jak twoje ciało da Ci te endorfiny to już...aż chce się biegać więcej. ', N'https://cezarywalenciuk.pl/Posts/programing/icons/_withbackground/R2/656_walidacja-z-fluentvalidation-waspnet-core--swagger.png', 5, N'Bieganie jak się do tego zmotywować : Zdrowie Programisty', N'https://cezarywalenciuk.pl/blog/programing/bieganie-jak-sie-do-tego-zmotywowac--zdrowie-programisty');
IF EXISTS (SELECT * FROM [sys].[identity_columns] WHERE [name] IN (N'PostId', N'Author', N'CategoryId', N'Date', N'Description', N'ImageUrl', N'Rate', N'Title', N'Url') AND [object_id] = OBJECT_ID(N'[Posts]'))
SET IDENTITY_INSERT [Posts] OFF;
GO
CREATE INDEX [IX_Posts_CategoryId] ON [Posts] ([CategoryId]);
GO
INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20210118090359_Init', N'3.1.11');
GO
[Route("api/[controller]")]
[ApiController]
public class PostController : ControllerBase
{
private readonly IMediator _mediator;
public PostController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet(Name = "GetAllPosts")]
public async Task<ActionResult<List<PostInListViewModel>>> GetAllPosts()
{
var list = await _mediator.Send(new GetPostsListQuery());
return Ok(list);
}
[HttpGet("{id}", Name = "GetPostById")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesDefaultResponseType]
public async Task<ActionResult<PostDetailViewModel>> GetPostById(int id)
{
var detailViewModel = await _mediator.Send
(new GetPostDetailQuery() { Id = id });
return Ok(detailViewModel);
}
[HttpPost(Name = "AddPost")]
public async Task<ActionResult<int>> Create([FromBody] CreatedPostCommand createPostCommand)
{
var result = await _mediator.Send(createPostCommand);
return Ok(result.PostId);
}
[HttpPut(Name = "UpdatePost")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesDefaultResponseType]
public async Task<ActionResult> Update([FromBody] UpdatePostCommand updatePostCommand)
{
await _mediator.Send(updatePostCommand);
return NoContent();
}
[HttpDelete("{id}", Name = "DeletePost")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesDefaultResponseType]
public async Task<ActionResult> Delete(int id)
{
var deletepostCommand = new DeletePostCommand() { PostId = id };
await _mediator.Send(deletepostCommand);
return NoContent();
}
[Route("api/[controller]")]
[ApiController]
public class WebinarController : Controller
{
private readonly IMediator _mediator;
public WebinarController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet("/getwebinarfordate", Name = "GetPagedWebinarsForDate")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesDefaultResponseType]
public async Task<ActionResult<PageWebinarByDateViewModel>> GetPagedWebinarsForMonth(SearchOptionsWebinars searchOptionsWebinars, int page, int pagesize, DateTime? date)
{
var getWebinarForMonthQuery = new GetWebinarsByDateQuery()
{ Date = date, Page = page, PageSize = pagesize, Options = searchOptionsWebinars };
var pageWebinarsByDateViewModel = await _mediator.Send(getWebinarForMonthQuery);
return Ok(pageWebinarsByDateViewModel);
}
[HttpPost(Name = "AddWebinar")]
public async Task<ActionResult<int>> Create([FromBody] CreatedWebinarCommand createWebinarCommand)
{
var result = await _mediator.Send(createWebinarCommand);
return Ok(result.Id);
}
[HttpGet("{id}", Name = "GetWebinar")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesDefaultResponseType]
public async Task<ActionResult<WebinarViewModel>> GetWebinarById(int id)
{
var result = await _mediator.Send((new GetWebinarQuery() { Id = id }));
return Ok(result);
}
[HttpPut(Name = "UpdateWebinar")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesDefaultResponseType]
public async Task<ActionResult> Update([FromBody] UpdateWebinarCommand updatePostCommand)
{
await _mediator.Send(updatePostCommand);
return NoContent();
}
[HttpDelete("{id}", Name = "DeleteWebinar")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesDefaultResponseType]
public async Task<ActionResult> Delete(int id)
{
var deletepostCommand = new DeleteWebinarCommand() { WebinarId = id };
await _mediator.Send(deletepostCommand);
return NoContent();
}
}
[Route("api/[controller]")]
[ApiController]
public class CategoriesController : Controller
{
private readonly IMediator _mediator;
public CategoriesController(IMediator mediator)
{
_mediator = mediator;
}
[HttpGet("all", Name = "GetAllCategories")]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<List<CategoryInListViewModel>>> GetAllCategories()
{
var categoryInListViewModel = await _mediator.Send(new GetCategoriesListQuery());
return Ok(categoryInListViewModel);
}
[HttpGet("allwithposts", Name = "GetCategoriesWithPosts")]
[ProducesDefaultResponseType]
[ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<List<CategoryPostListViewModel>>> GetCategoriesWithPosts
(SearchCategoryOptions searchOptions)
{
GetCategoriesWithPostListQuery getCategoriesListWithPostsQuery =
new GetCategoriesWithPostListQuery() { searchCategory = searchOptions };
var dtos = await _mediator.Send(getCategoriesListWithPostsQuery);
return Ok(dtos);
}
[HttpPost(Name = "addCategory")]
public async Task<ActionResult<CreatedCategoryCommandResponse>> Create
([FromBody] CreatedCategoryCommand createCategoryCommand)
{
var response = await _mediator.Send(createCategoryCommand);
return Ok(response);
}
}
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\EduZbieracz.Application\EduZbieracz.Application.csproj" />
<ProjectReference Include="..\EduZbieracz.Persistence\EduZbieracz.Persistence.EF.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.11">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.6.3" />
</ItemGroup>
</Project>
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Version = "v1",
Title = "Edu Zbieracz API",
});
});
services.AddEduZbieraczApplication();
services.AddEduZbieraczPersistenceEFServices(Configuration);
services.AddControllers();
services.AddCors(options =>
{
options.AddPolicy("Open",
builder => builder.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("swagger/v1/swagger.json", "Edu Zbieracz API");
});
app.UseCors("Open");
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Pages\CategoryList.razor.cs" />
</ItemGroup>
<ItemGroup>
<Content Remove="Pages\CategoryList.razor" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="10.1.1" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="8.1.0" />
<PackageReference Include="Blazored.LocalStorage" Version="3.0.0" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" Version="5.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.Authorization" Version="5.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.2" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.2" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Http" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
</ItemGroup>
</Project>
public partial interface IClient
{
System.Net.Http.HttpClient HttpClient { get; }
......
public partial class Client : IClient
{
private string _baseUrl = "";
private System.Net.Http.HttpClient _httpClient;
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
public Client(string baseUrl, System.Net.Http.HttpClient httpClient)
{
BaseUrl = baseUrl;
_httpClient = httpClient;
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
public partial class Client : IClient
{
private string _baseUrl = "";
private System.Net.Http.HttpClient _httpClient;
private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;
public Client(System.Net.Http.HttpClient httpClient)
{
_httpClient = httpClient;
_settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings);
}
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("#app");
builder.Services.AddAutoMapper(Assembly.GetExecutingAssembly());
//builder.Services.AddBlazoredLocalStorage();
string a = "https://localhost:5001/";
builder.Services.AddSingleton(new HttpClient
{
BaseAddress = new Uri("https://localhost:5001")
});
builder.Services.AddHttpClient<IClient, Client>
(client => client.BaseAddress = new Uri("https://localhost:5001"));
builder.Services.AddScoped<ICategoryService, CategoryService>();
builder.Services.AddScoped<IWebinarService, WebinarService>();
builder.Services.AddScoped<IPostServices, PostServices>();
await builder.Build().RunAsync();
}
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iis": {
"applicationUrl": "http://localhost/EduZbieracz.Api",
"sslPort": 0
},
"iisExpress": {
"applicationUrl": "http://localhost:5005",
"sslPort": 44366
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"EduZbieracz.Api": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
},
"Localhost": {
"commandName": "IIS"
}
}
}
public class MappingProfile : Profile
{
public MappingProfile()
{
CreateMap<PostInListViewModel, PostInListBlazorVM>().ReverseMap();
CreateMap<PostDetailViewModel, PostDetailBlazorVM>().ReverseMap();
CreateMap<PostDetailBlazorVM, CreatedPostCommand>().ReverseMap();
CreateMap<PostDetailBlazorVM, UpdatePostCommand>().ReverseMap();
CreateMap<CategoryPostDto, PostInsideCategoryBlazorVM>().ReverseMap();
CreateMap<CategoryDto, CategoryBlazorVM>().ReverseMap();
CreateMap<CategoryInListViewModel, CategoryBlazorVM>().ReverseMap();
CreateMap<CategoryPostListViewModel, CategoryWithPostsBlazorVM>().ReverseMap();
CreateMap<CreatedCategoryCommand, CategoryBlazorVM>().ReverseMap();
CreateMap<WebinarsByDateViewModel, WebinarForDateListBlazorVM>().ReverseMap();
CreateMap<PageWebinarByDateViewModel, WebinarPagedForDateBlazorVM>().ReverseMap();
CreateMap<WebinarViewModel, WebinarBlazorVM>().ReverseMap();
CreateMap<CreatedWebinarCommand, WebinarBlazorVM>().ReverseMap();
CreateMap<UpdateWebinarCommand, WebinarBlazorVM>().ReverseMap();
}
}
[Route("api/[controller]")]
[ApiController]
public class LoginController : ControllerBase
{
private readonly IAuthenticationService _authenticationService;
public LoginController(IAuthenticationService authenticationService)
{
_authenticationService = authenticationService;
}
[HttpPost("authenticate", Name = "Authenticate")]
public async Task<ActionResult<AuthenticationResponse>> AuthenticateAsync(AuthenticationRequest request)
{
return Ok(await _authenticationService.AuthenticateAsync(request));
}
[HttpPost("register", Name = "Register")]
public async Task<ActionResult<RegistrationResponse>> RegisterAsync(RegistrationRequest request)
{
return Ok(await _authenticationService.RegisterAsync(request));
}
}