Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ riderModule.iml
/_ReSharper.Caches/
.fake
.vscode
.vs
Binary file modified .vs/MyFirstBlog/DesignTimeBuild/.dtbcache.v2
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified .vs/MyFirstBlog/v17/.futdcache.v2
Binary file not shown.
Binary file modified .vs/MyFirstBlog/v17/.suo
Binary file not shown.
282 changes: 211 additions & 71 deletions .vs/MyFirstBlog/v17/DocumentLayout.json

Large diffs are not rendered by default.

Binary file modified .vs/ProjectEvaluation/myfirstblog.metadata.v7.bin
Binary file not shown.
Binary file modified .vs/ProjectEvaluation/myfirstblog.projects.v7.bin
Binary file not shown.
12 changes: 12 additions & 0 deletions MyFirstBlog/.config/dotnet-tools.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": 1,
"isRoot": true,
"tools": {
"dotnet-ef": {
"version": "8.0.7",
"commands": [
"dotnet-ef"
]
}
}
}
61 changes: 38 additions & 23 deletions MyFirstBlog/Controllers/PostsController.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,49 @@
namespace MyFirstBlog.Controllers;

using Microsoft.AspNetCore.Mvc;
using MyFirstBlog.Dtos;
using MyFirstBlog.Services;
using MyFirstBlog.Dtos;
using System.Collections.Generic;

namespace MyFirstBlog.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class PostsController : ControllerBase
{
private readonly PostService _postService;

public PostsController(PostService postService)
{
_postService = postService;
}

[ApiController]
[Route("posts")]
[HttpGet]
public ActionResult<IEnumerable<PostDto>> GetPosts()
{
var posts = _postService.GetPosts();
return Ok(posts);
}

public class PostsController : ControllerBase {
private IPostService _postService;
[HttpGet("{slug}")]
public ActionResult<PostDto> GetPost(string slug)
{
var post = _postService.GetPost(slug);
if (post == null)
return NotFound();

public PostsController(IPostService postService) {
_postService = postService;
}
return Ok(post);
}

// Get /posts
[HttpGet]
public IEnumerable<PostDto> GetPosts() {
return _postService.GetPosts();
}
[HttpPost("new")]
public ActionResult<PostDto> AddPost([FromBody] CreatePostDto createPostDto)
{
if (string.IsNullOrWhiteSpace(createPostDto.Title))
{
return BadRequest(new { errors = new[] { "Title cannot be blank" } });
}

// Get /posts/:slug
[HttpGet("{slug}")]
public ActionResult<PostDto> GetPost(string slug) {
var post = _postService.GetPost(slug);
var post = _postService.CreatePost(createPostDto);

if (post is null) {
return NotFound();
return CreatedAtAction(nameof(GetPost), new { slug = post.Slug }, post);
}

return post;
}
}
33 changes: 25 additions & 8 deletions MyFirstBlog/Dtos/PostDto.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,26 @@
namespace MyFirstBlog.Dtos;

public record PostDto {
public Guid Id { get; init; }
public string Title { get; init; } = default!;
public string Slug { get; init; } = default!;
public string Body { get; init; } = default!;
public DateTime CreatedDate { get; init; }
using System;
using System.ComponentModel.DataAnnotations;

namespace MyFirstBlog.Dtos
{
public class PostDto
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Slug { get; set; }
public string Body { get; set; }

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}")]
public DateTime CreatedDate { get; set; }
}

public class CreatePostDto
{
public string Title { get; set; }
public string Slug { get; set; }
public string Body { get; set; }

[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd HH:mm:ss}")]
public DateTime CreatedDate { get; set; }
}
}
17 changes: 10 additions & 7 deletions MyFirstBlog/Entities/Post.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
namespace MyFirstBlog.Entities;
public record Post {
public Guid Id { get; init; }
public string Title { get; init; } = default!;
public string Slug { get; init; } = default!;
public string Body { get; init; } = default!;
public DateTime CreatedDate { get; init; }
namespace MyFirstBlog.Entities
{
public class Post
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Slug { get; set; }
public string Body { get; set; }
public DateTime CreatedDate { get; set; } // Updated to CreatedDate
}
}
25 changes: 11 additions & 14 deletions MyFirstBlog/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
using MyFirstBlog.Dtos;
using MyFirstBlog.Entities;
using System;

namespace MyFirstBlog {
public static class Extensions {
public static PostDto AsDto(this Post post) {
return new PostDto
{
Id = post.Id,
Title = post.Title,
Slug = post.Slug,
Body = post.Body,
CreatedDate = post.CreatedDate
};

namespace MyFirstBlog.Extensions
{
public static class PostExtensions
{
public static void UpdatePost(this PostDto postDto, string title, string body, DateTime createDate)
{
postDto.Title = title;
postDto.Body = body;
postDto.CreatedDate = createDate; // Correct usage of CreateDate
}
}
};
}
51 changes: 26 additions & 25 deletions MyFirstBlog/Helpers/ConnectionHelper.cs
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
namespace MyFirstBlog.Helpers;

using Npgsql;
using Microsoft.Extensions.Configuration;

public static class ConnectionHelper
namespace MyFirstBlog.Helpers
{
public static string GetConnectionString(IConfiguration configuration)
public static class ConnectionHelper
{
var connectionString = configuration.GetConnectionString("DefaultConnection");
var databaseUrl = Environment.GetEnvironmentVariable("DATABASE_URL");
return string.IsNullOrEmpty(databaseUrl) ? connectionString : BuildConnectionString(databaseUrl);
}
public static string GetConnectionString(IConfiguration configuration)
{
var connectionString = configuration.GetConnectionString("DefaultConnection");
var databaseUrl = Environment.GetEnvironmentVariable("DATABASE_URL");
return string.IsNullOrEmpty(databaseUrl) ? connectionString : BuildConnectionString(databaseUrl);
}

//build the connection string from the environment. i.e. Heroku or Railway
private static string BuildConnectionString(string databaseUrl)
{
var databaseUri = new Uri(databaseUrl);
var userInfo = databaseUri.UserInfo.Split(':');
var builder = new NpgsqlConnectionStringBuilder
private static string BuildConnectionString(string databaseUrl)
{
Host = databaseUri.Host,
Port = databaseUri.Port,
Username = userInfo[0],
Password = userInfo[1],
Database = databaseUri.LocalPath.TrimStart('/'),
SslMode = SslMode.Require,
TrustServerCertificate = true
};
return builder.ToString();
}
}
var databaseUri = new Uri(databaseUrl);
var userInfo = databaseUri.UserInfo.Split(':');
var builder = new NpgsqlConnectionStringBuilder
{
Host = databaseUri.Host,
Port = databaseUri.Port,
Username = userInfo[0],
Password = userInfo[1],
Database = databaseUri.LocalPath.TrimStart('/'),
SslMode = SslMode.Require,
TrustServerCertificate = true
};
return builder.ToString();
}
}
}
35 changes: 18 additions & 17 deletions MyFirstBlog/Helpers/DataContext.cs
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
namespace MyFirstBlog.Helpers;

using Microsoft.EntityFrameworkCore;
using MyFirstBlog.Entities;


public class DataContext : DbContext
namespace MyFirstBlog.Helpers
{
protected readonly IConfiguration Configuration;
using Microsoft.EntityFrameworkCore;
using MyFirstBlog.Entities;
using Microsoft.Extensions.Configuration;

public DataContext(IConfiguration configuration)
public class DataContext : DbContext
{
Configuration = configuration;
}
protected readonly IConfiguration Configuration;

protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseNpgsql(ConnectionHelper.GetConnectionString(Configuration));
}
public DataContext(IConfiguration configuration)
{
Configuration = configuration;
}

public DbSet<Post> Posts { get; set; }
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseNpgsql(ConnectionHelper.GetConnectionString(Configuration));
}

public DbSet<Post> Posts { get; set; }
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions MyFirstBlog/Migrations/20240812182313_AddCreatedDateToPosts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace MyFirstBlog.Migrations
{
public partial class AddCreatedDateToPosts : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "CreatedDate",
table: "Posts",
nullable: false,
defaultValue: DateTime.UtcNow);
}

protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "CreatedDate",
table: "Posts");
}
}
}
Loading