TestAPI is a C# .Net MVC API using Visual Studio as the IDE.
- Quick summary
- Version
- Framework
- Plugins
- Codes
-TestAPI uses SQLite as the database for storing user, and images and etc.
- 1.2
- Microsoft.AspNetCore.App 3.1.2
- Microsoft.NETCode.App 3.1.0
-
-
using QUERY Loggin
- add in
Context
class
public static readonly LoggerFactory DbCommandDebugLoggerFactory = new LoggerFactory(new[] { new DebugLoggerProvider() });
- add in
Context's OnConfiguring()
:
optionsBuilder .UseLoggerFactory(DbCommandDebugLoggerFactory) // to set the logger for DB query .EnableSensitiveDataLogging(); // enable logging
- add in
-
SQL property options add in
OnModelCreating(ModelBuilder modelBuilder)
- using SQLite:
modelBuilder.Entity<User>() .Property(b => b.CreatedAt) .HasDefaultValueSql("datetime('now')");
default value in creating entry: add this in model:
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
modelBuilder.Entity<User>().Property(d => d.Id) .ValueGeneratedOnAdd();
-
-
- Add in Startup.cs ConfigureServices()
services.AddControllers() .AddNewtonsoftJson();
- To change the casing to camel:
services.AddMvc() .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver() { NamingStrategy = new SnakeCaseNamingStrategy() });
- Add in Startup.cs ConfigureServices()
- Summary of set up
- Configuration
- Dependencies
- Database configuration
- How to run tests
- Deployment instructions
- Goto Program.cs
- Create method GetLocalIPv4()
using System.Net.NetworkInformation; using System.Net.Sockets; internal static string GetLocalIPv4(NetworkInterfaceType _type = NetworkInterfaceType.Ethernet) { // Checks your IP adress from the local network connected to a gateway. This to avoid issues with double network cards string output = ""; // default output foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces()) // Iterate over each network interface { // Find the network interface which has been provided in the arguments, break the loop if found //if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up) //{ // Fetch the properties of this adapter IPInterfaceProperties adapterProperties = item.GetIPProperties(); // Check if the gateway adress exist, if not its most likley a virtual network or smth if (adapterProperties.GatewayAddresses.FirstOrDefault() != null) { // Iterate over each available unicast adresses foreach (UnicastIPAddressInformation ip in adapterProperties.UnicastAddresses) { // If the IP is a local IPv4 adress if (ip.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { // we got a match! output = ip.Address.ToString(); break; // break the loop!! } } } //} // Check if we got a result if so break this method if (output != "") { break; } } // Return results return output; }
- Add to CreateHostBuilder property:
webBuilder.UseUrls("http://localhost:5000", $"http://{GetLocalIPv4()}:5000"); // my IP Address
- To run
- in terminal
dotnet run
- Visual Studio Click Run
- Add in
Startup.cs
ConfigureServices()
- using In Memory
services.AddDbContext<TestContext>((opt) => opt.UseInMemoryDatabase("UserList"));
- using SQLite
services.AddDbContext<TestContext>(options => { options.UseSqlite("Filename=./test_context.db"); //create sqlite db in project });
- using SQL
Then ADD in
services.AddDbContext<ConfigurationContext>(options => { options.UseSqlServer(Configuration.GetConnectionString("MyConnection")); });
appsettings.json
orappsettings.Development.json
,"AllowedHosts": "*", "ConnectionStrings": { "MyConnection": "server=.;database=myDb;trusted_connection=true;" }
- For SQL Database using docker (SQL FOR MAC)
- https://hub.docker.com/editions/community/docker-ce-desktop-mac
- https://www.c-sharpcorner.com/article/entity-framework-core-with-sql-server-in-docker-container/
- FOR DOCKER
- Open Docker
- Goto folder
- enter in terminal to build project
docker build -t [dockerfilename]
- enter in terminal to run project server
docker run -d -p 80:80 --name docker-tutorial docker1 01tutorial
- using In Memory
- install PostgreSQL
brew install postgresql
-
To migrate existing data
from a previous major version of PostgreSQL run:brew postgresql-upgrade-database
- To have
launchd start postgresql now and restart at login
:brew services start postgresql
- Or, if you don't want/need a
background service
you can just run:pg_ctl -D /usr/local/var/postgres start
- using psql
- Creating database
psql template1
- to create database
create database [name of database];
- Creating role
create ROLE [role_name] WITH SUPERUSER CREATEDB CREATEROLE LOGIN ENCRYPTED PASSWORD '[role_password]';
- Change Role
psql -d [database_name]] -U [role_name]]
- Creating database
- Adding in c# WEB API
- add Packages if .net version 3.1.2 or Up
- add to
appsettings.json
orappsettings.development.json
where"ConnectionStrings": { "MyPostgresqlConn": "Server=localhost; Port=5432; Database=mydb; Username=csharpuser; Password=csharpuserpassword" }
"MyPostgresqlConn": "Server=localhost; Port=5432; Database=[name of database]; Username=[role_name]; Password=[role_password]"
- add in
Startup.cs
ConfigureServices(IServiceCollection services)
services.AddDbContext<TestContext>(options => options.UseNpgsql(Configuration.GetConnectionString("MyPostgresqlConn")));
- [Required] for Dto request required checking
- [Key] for primary key
- [ForeignKey] for foreign key can be add to object property as reference for fetch via primary key
- _dbContext.Entry(dataObject).Reference(u => u.RefObject).Load(); to use relationship data.
- or _dbContext.Table.Include(u => u.RefObject);
- [Index(nameof(propName),IsUnique =true)] //add in class
- [Column] use for defining column options
- First
dotnet ef migrations add InitialCreate
- Then Add to
Context's Constructor()
if (Database.GetPendingMigrations().Any()) { Database.Migrate(); }
- [Authorize] to add authorization in controller or controller method or actions
- [AllowAnonymous] add in action to even if controller is [Authorize] it can still be access with out authorization
-
- First install nugger
- Microsoft.AspNetCore.Identity
- Microsoft.AspNetCore.Authentication.JwtBearer
- Then add in appsettings.json
, "JWT": { "ValidAudience": "http://localhost:4200", "ValidIssuer": "http://localhost:61955", "Secret": "ByYM000OLlMQG6VVVp1OH7Xzyr7gHuw1qvUC5dcGt3SNM" }
- Then add UserRoles *optional
public static class UserRoles { public const string Admin = "Admin"; public const string User = "User"; }
- Then add in StartUp's ConfigureServices
// Adding Authentication
services.AddAuthentication(options =>
{
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
})
// Adding Jwt Bearer
.AddJwtBearer(options =>
{
options.SaveToken = true;
options.RequireHttpsMetadata = false;
options.TokenValidationParameters = new TokenValidationParameters()
{
ValidateIssuer = true,
ValidateAudience = true,
ValidAudience = Configuration["JWT:ValidAudience"],
ValidIssuer = Configuration["JWT:ValidIssuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JWT:Secret"]))
};
});
- Then add in StartUp's Configure
//after app.UseRouting()
app.UseAuthentication()
.UseAuthorization()
- Then use to create token
public string CreateToker(string username)
{
var authClaims = new List<Claim>
{
new Claim(ClaimTypes.Name, username),
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
new Claim(ClaimTypes.Role, "User"),
};
//if user has many roles
//foreach (var userRole in userRoles)
//{
// authClaims.Add(new Claim(ClaimTypes.Role, userRole));
//}
SymmetricSecurityKey authSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:Secret"]));
JwtSecurityToken token = new JwtSecurityToken(
issuer: _configuration["JWT:ValidIssuer"],
audience: _configuration["JWT:ValidAudience"],
expires: DateTime.Now.AddHours(3),
claims: authClaims,
signingCredentials: new SigningCredentials(authSigningKey, SecurityAlgorithms.HmacSha256)
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
- First insall nuget - Swashbuckle.AspNetCore - Swashbuckle.AspNetCore.Annotations - Swashbuckle.AspNetCore.Newtonsoft
- Then add to `StartUp's Configure()'
app.UseSwagger() .UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/v1.0/swagger.json", "Test Api"); });
- Then add to `StartUp's ConfigureServices()'
//NOTE: To use swagger services .AddSwaggerGen(c => { c.SwaggerDoc("v1.0", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "TestC# API", Version = "v1.0" }); c.ResolveConflictingActions(apidescription => apidescription.First()); }) //NOTE: added Newtonsoft for Swagger .AddSwaggerGenNewtonsoftSupport() .AddLogging();
- To get exception in Controller Action
var exceptionHandlerFeature = HttpContext.Features.Get<IExceptionHandlerFeature>()!;