public async Task <ActionResult> CreateUrlItemAsync(UrlItemCreateDto createDto) { // Generate an alphanumerical slug if (string.IsNullOrEmpty(createDto.Slug)) { string slug; do { slug = RandomHelper.NextAlphanumeric(_slugConfiguration.Length); } while (await _context.UrlItems.AnyAsync(u => u.Slug == slug)); createDto.Slug = slug; } // Check for duplicates else if (await _context.UrlItems.AnyAsync(u => u.Slug == createDto.Slug)) { ModelState.AddModelError("Slug", "The slug must be unique"); return(CommonResponse.CreateResponse(modelState: ModelState)); } var urlItem = _mapper.Map <UrlItem>(createDto); _context.UrlItems.Add(urlItem); await _context.SaveChangesAsync(); var viewDto = _mapper.Map <UrlItemViewDto>(urlItem); _logger.LogInformation("{method}: {shortUrl} -> {redirectUrl}, {time} UTC", nameof(CreateUrlItemAsync), viewDto.ShortUrl, viewDto.RedirectUrl, DateTime.UtcNow); return(CommonResponse.CreateResponse(data: viewDto)); }
public async Task <ActionResult> GetAsync(string slug) { var url = await _context.UrlItems.SingleOrDefaultAsync(u => u.Slug == slug); if (url == null) { ModelState.AddModelError("slug", $"Could not find ${slug}"); return(CommonResponse.CreateResponse(modelState: ModelState, status: 404)); } return(CommonResponse.CreateResponse(data: _mapper.Map <AnalyticsViewDto>(url))); }
public async Task <ActionResult> RedirectFromShortUrlAsync(string slug) { var urlItem = await _context.UrlItems.SingleOrDefaultAsync(u => u.Slug == slug); if (urlItem == null) { ModelState.AddModelError("slug", $"Could not find ${slug}"); return(CommonResponse.CreateResponse(modelState: ModelState, status: 404)); } urlItem.Clicks++; await _context.SaveChangesAsync(); _logger.LogInformation("{method}: {shortUrl} -> {redirectUrl}, {time} UTC", nameof(RedirectFromShortUrlAsync), Request.GetEncodedUrl(), urlItem.RedirectUrl, DateTime.UtcNow); return(Redirect(urlItem.RedirectUrl)); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddDbContext <UrlShrtDbContext>(option => option.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddAutoMapper(typeof(Startup)); services.AddControllers(); services.TryAddSingleton <IHttpContextAccessor, HttpContextAccessor>(); services.TryAddScoped <ISlugConfiguration, SlugConfiguration>(); services.AddCors(); services.Configure <ApiBehaviorOptions>(options => { options.InvalidModelStateResponseFactory = context => { return(CommonResponse.CreateResponse(modelState: context.ModelState, status: (int)HttpStatusCode.BadRequest)); }; }); services.Configure <ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; }); }