example values und aufräumen
This commit is contained in:
@@ -1,45 +1,47 @@
|
|||||||
|
// --- Core Frameworks & Libraries ---
|
||||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||||
using Microsoft.AspNetCore.HttpOverrides; // For UseForwardedHeaders
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
using Microsoft.AspNetCore.Identity;
|
using Microsoft.AspNetCore.Identity;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging; // For ILogger
|
|
||||||
using Microsoft.IdentityModel.Tokens;
|
using Microsoft.IdentityModel.Tokens;
|
||||||
using Microsoft.OpenApi.Models; // For Swagger OpenAPI models
|
using Microsoft.OpenApi.Models;
|
||||||
using Resend;
|
using Resend;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using Webshop.Api.SwaggerFilters; // For AuthorizeOperationFilter
|
|
||||||
using Webshop.Application.Services.Admin; // AdminUserService, AdminProductService
|
// --- Eigene Namespaces ---
|
||||||
|
using Webshop.Api.SwaggerFilters;
|
||||||
|
using Webshop.Application.Services.Admin;
|
||||||
using Webshop.Application.Services.Admin.Interfaces;
|
using Webshop.Application.Services.Admin.Interfaces;
|
||||||
using Webshop.Application.Services.Auth; // IAuthService, AuthService
|
using Webshop.Application.Services.Auth;
|
||||||
using Webshop.Application.Services.Customers;
|
using Webshop.Application.Services.Customers;
|
||||||
using Webshop.Application.Services.Customers.Interfaces;
|
using Webshop.Application.Services.Customers.Interfaces;
|
||||||
using Webshop.Application.Services.Public; // ProductService
|
using Webshop.Application.Services.Public;
|
||||||
using Webshop.Application.Services.Public.Interfaces;
|
using Webshop.Application.Services.Public.Interfaces;
|
||||||
using Webshop.Domain.Entities;
|
using Webshop.Domain.Entities;
|
||||||
using Webshop.Domain.Identity;
|
using Webshop.Domain.Identity;
|
||||||
using Webshop.Domain.Interfaces; // IProductRepository
|
using Webshop.Domain.Interfaces;
|
||||||
using Webshop.Infrastructure.Data; // ApplicationDbContext
|
using Webshop.Infrastructure.Data;
|
||||||
using Webshop.Infrastructure.Repositories; // ProductRepository
|
using Webshop.Infrastructure.Repositories;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
// --- START: DIENSTE ZUM CONTAINER HINZUF<55>GEN ---
|
// --- 1. Dependency Injection Konfiguration ---
|
||||||
|
|
||||||
// 1. Datenbank-Kontext (DbContext) registrieren
|
// Datenbank-Kontext
|
||||||
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
builder.Services.AddDbContext<ApplicationDbContext>(options =>
|
||||||
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"))
|
options.UseNpgsql(builder.Configuration.GetConnectionString("DefaultConnection"))
|
||||||
);
|
);
|
||||||
|
|
||||||
// 2. ASP.NET Core Identity f<EFBFBD>r Benutzerverwaltung registrieren
|
// ASP.NET Core Identity mit ApplicationUser
|
||||||
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
|
builder.Services.AddIdentity<ApplicationUser, IdentityRole>(options =>
|
||||||
{
|
{
|
||||||
options.SignIn.RequireConfirmedAccount = true;
|
options.SignIn.RequireConfirmedEmail = true;
|
||||||
})
|
})
|
||||||
.AddEntityFrameworkStores<ApplicationDbContext>() // Stellen Sie sicher, dass Ihr DbContext-Name hier korrekt ist
|
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||||
.AddDefaultTokenProviders();
|
.AddDefaultTokenProviders();
|
||||||
|
|
||||||
// Optional: Passe die Anforderungen f<>r Passw<EFBFBD>rter f<>r die Entwicklung an
|
// Passwort-Anforderungen f<>r die Entwicklung lockern
|
||||||
builder.Services.Configure<IdentityOptions>(options =>
|
builder.Services.Configure<IdentityOptions>(options =>
|
||||||
{
|
{
|
||||||
options.Password.RequireDigit = false;
|
options.Password.RequireDigit = false;
|
||||||
@@ -47,14 +49,11 @@ builder.Services.Configure<IdentityOptions>(options =>
|
|||||||
options.Password.RequireNonAlphanumeric = false;
|
options.Password.RequireNonAlphanumeric = false;
|
||||||
options.Password.RequireUppercase = false;
|
options.Password.RequireUppercase = false;
|
||||||
options.Password.RequireLowercase = false;
|
options.Password.RequireLowercase = false;
|
||||||
options.SignIn.RequireConfirmedEmail = true; // F<>r einfache Entwicklung/Tests
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// JWT-Authentifizierung
|
||||||
// 3. JWT-Authentifizierung konfigurieren
|
|
||||||
var jwtSettings = builder.Configuration.GetSection("JwtSettings");
|
var jwtSettings = builder.Configuration.GetSection("JwtSettings");
|
||||||
var secretKey = jwtSettings["Secret"] ?? throw new InvalidOperationException("JWT Secret not found in configuration.");
|
var secretKey = jwtSettings["Secret"] ?? throw new InvalidOperationException("JWT Secret not found in configuration.");
|
||||||
|
|
||||||
builder.Services.AddAuthentication(options =>
|
builder.Services.AddAuthentication(options =>
|
||||||
{
|
{
|
||||||
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
|
||||||
@@ -73,9 +72,8 @@ builder.Services.AddAuthentication(options =>
|
|||||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey))
|
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey))
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
builder.Services.AddAuthorization(); // Aktiviert die Autorisierung
|
builder.Services.AddAuthorization();
|
||||||
|
|
||||||
// 4. Unsere eigenen Interfaces und Klassen registrieren (Dependency Injection)
|
|
||||||
// Repositories
|
// Repositories
|
||||||
builder.Services.AddScoped<IProductRepository, ProductRepository>();
|
builder.Services.AddScoped<IProductRepository, ProductRepository>();
|
||||||
builder.Services.AddScoped<ISupplierRepository, SupplierRepository>();
|
builder.Services.AddScoped<ISupplierRepository, SupplierRepository>();
|
||||||
@@ -85,114 +83,94 @@ builder.Services.AddScoped<ICategoryRepository, CategoryRepository>();
|
|||||||
builder.Services.AddScoped<IOrderRepository, OrderRepository>();
|
builder.Services.AddScoped<IOrderRepository, OrderRepository>();
|
||||||
builder.Services.AddScoped<IShippingMethodRepository, ShippingMethodRepository>();
|
builder.Services.AddScoped<IShippingMethodRepository, ShippingMethodRepository>();
|
||||||
builder.Services.AddScoped<IAddressRepository, AddressRepository>();
|
builder.Services.AddScoped<IAddressRepository, AddressRepository>();
|
||||||
// AUTH Services
|
builder.Services.AddScoped<IDiscountRepository, DiscountRepository>();
|
||||||
builder.Services.AddScoped<IAuthService, AuthService>();
|
builder.Services.AddScoped<IReviewRepository, ReviewRepository>();
|
||||||
|
builder.Services.AddScoped<ISettingRepository, SettingRepository>();
|
||||||
|
|
||||||
// PUBLIC Services
|
// Services
|
||||||
|
builder.Services.AddScoped<IAuthService, AuthService>();
|
||||||
builder.Services.AddScoped<IProductService, ProductService>();
|
builder.Services.AddScoped<IProductService, ProductService>();
|
||||||
builder.Services.AddScoped<IPaymentMethodService, PaymentMethodService>();
|
builder.Services.AddScoped<IPaymentMethodService, PaymentMethodService>();
|
||||||
builder.Services.AddScoped<ICategoryService, CategoryService>();
|
builder.Services.AddScoped<ICategoryService, CategoryService>();
|
||||||
builder.Services.AddScoped<ICategoryService, CategoryService>();
|
|
||||||
|
|
||||||
// ADMIN Services
|
|
||||||
builder.Services.AddScoped<IAdminUserService, AdminUserService>();
|
builder.Services.AddScoped<IAdminUserService, AdminUserService>();
|
||||||
builder.Services.AddScoped<IAdminProductService, AdminProductService>();
|
builder.Services.AddScoped<IAdminProductService, AdminProductService>();
|
||||||
builder.Services.AddScoped<IAdminSupplierService, AdminSupplierService>();
|
builder.Services.AddScoped<IAdminSupplierService, AdminSupplierService>();
|
||||||
builder.Services.AddScoped<IAdminPaymentMethodService, AdminPaymentMethodService>();
|
builder.Services.AddScoped<IAdminPaymentMethodService, AdminPaymentMethodService>();
|
||||||
builder.Services.AddScoped<IAdminCategoryService, AdminCategoryService>(); // Hinzugef<65>gt f<>r Konsistenz
|
builder.Services.AddScoped<IAdminCategoryService, AdminCategoryService>();
|
||||||
builder.Services.AddScoped<IAdminOrderService, AdminOrderService>();
|
builder.Services.AddScoped<IAdminOrderService, AdminOrderService>();
|
||||||
builder.Services.AddScoped<IAdminShippingMethodService, AdminShippingMethodService>();
|
builder.Services.AddScoped<IAdminShippingMethodService, AdminShippingMethodService>();
|
||||||
|
builder.Services.AddScoped<IAdminDiscountService, AdminDiscountService>();
|
||||||
//builder.Services.AddScoped<IAdminDiscountService, AdminDiscountService>(); // Hinzugef<65>gt f<>r Konsistenz
|
builder.Services.AddScoped<IAdminSettingService, AdminSettingService>();
|
||||||
builder.Services.AddScoped<IAdminOrderService, AdminOrderService>(); // Hinzugef<65>gt f<>r Konsistenz
|
|
||||||
//builder.Services.AddScoped<IAdminSettingService, AdminSettingService>(); // Hinzugef<65>gt f<>r Konsistenz
|
|
||||||
|
|
||||||
// CUSTOMER Services (sp<73>ter Implementierungen hinzuf<75>gen)
|
|
||||||
builder.Services.AddScoped<ICustomerService, CustomerService>();
|
builder.Services.AddScoped<ICustomerService, CustomerService>();
|
||||||
builder.Services.AddScoped<IOrderService, OrderService>(); // Hinzugef<65>gt f<>r Konsistenz
|
builder.Services.AddScoped<IOrderService, OrderService>();
|
||||||
builder.Services.AddScoped<IAddressService, AddressService>();
|
builder.Services.AddScoped<IAddressService, AddressService>();
|
||||||
//builder.Services.AddScoped<ICheckoutService, CheckoutService>(); // Hinzugef<65>gt f<>r Konsistenz
|
builder.Services.AddScoped<ICheckoutService, CheckoutService>();
|
||||||
//builder.Services.AddScoped<IReviewService, ReviewService>(); // Hinzugef<65>gt f<>r Konsistenz
|
builder.Services.AddScoped<IReviewService, ReviewService>();
|
||||||
|
|
||||||
// --- NEU: Resend E-Mail-Dienst konfigurieren ---
|
// Externe Dienste (Resend)
|
||||||
builder.Services.AddOptions(); // Stellt sicher, dass Options konfiguriert werden k<>nnen
|
builder.Services.AddHttpClient<ResendClient>();
|
||||||
builder.Services.AddHttpClient<ResendClient>(); // F<>gt HttpClient f<>r Resend hinzu
|
|
||||||
builder.Services.Configure<ResendClientOptions>(options =>
|
builder.Services.Configure<ResendClientOptions>(options =>
|
||||||
{
|
{
|
||||||
// Der API-Token kommt aus den Konfigurationen (z.B. appsettings.json oder Umgebungsvariablen)
|
options.ApiToken = builder.Configuration["Resend:ApiToken"]!;
|
||||||
options.ApiToken = builder.Configuration["Resend:ApiToken"]!; // << ANPASSEN >>
|
|
||||||
});
|
});
|
||||||
builder.Services.AddTransient<IResend, ResendClient>();
|
builder.Services.AddTransient<IResend, ResendClient>();
|
||||||
|
|
||||||
|
// Controller und API-Infrastruktur
|
||||||
// 5. Controller und Swagger/OpenAPI hinzuf<75>gen
|
|
||||||
builder.Services.AddControllers()
|
builder.Services.AddControllers()
|
||||||
.AddJsonOptions(options =>
|
.AddJsonOptions(options =>
|
||||||
{
|
{
|
||||||
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
|
||||||
|
// Swagger / OpenAPI Konfiguration
|
||||||
builder.Services.AddSwaggerGen(c =>
|
builder.Services.AddSwaggerGen(c =>
|
||||||
{
|
{
|
||||||
// 1. JWT Security Definition hinzuf<75>gen
|
c.TagActionsBy(api =>
|
||||||
|
{
|
||||||
|
if (api.RelativePath.StartsWith("api/v1/admin")) return new[] { "Admin" };
|
||||||
|
if (api.RelativePath.StartsWith("api/v1/auth")) return new[] { "Auth" };
|
||||||
|
if (api.RelativePath.StartsWith("api/v1/customer")) return new[] { "Customer" };
|
||||||
|
if (api.RelativePath.StartsWith("api/v1/public")) return new[] { "Public" };
|
||||||
|
return new[] { "Default" };
|
||||||
|
});
|
||||||
|
|
||||||
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
|
||||||
{
|
{
|
||||||
Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
|
Description = "JWT Authorization header. Example: \"Authorization: Bearer {token}\"",
|
||||||
Name = "Authorization",
|
Name = "Authorization",
|
||||||
In = ParameterLocation.Header, // Der Token wird im Header gesendet
|
In = ParameterLocation.Header,
|
||||||
Type = SecuritySchemeType.Http, // Dies ist ein HTTP-Schema
|
Type = SecuritySchemeType.Http,
|
||||||
Scheme = "Bearer" // Das Schema ist "Bearer"
|
Scheme = "Bearer"
|
||||||
});
|
});
|
||||||
|
|
||||||
// 2. Security Requirement f<>r alle Operationen hinzuf<75>gen
|
|
||||||
c.AddSecurityRequirement(new OpenApiSecurityRequirement
|
|
||||||
{
|
|
||||||
{
|
|
||||||
new OpenApiSecurityScheme
|
|
||||||
{
|
|
||||||
Reference = new OpenApiReference
|
|
||||||
{
|
|
||||||
Type = ReferenceType.SecurityScheme,
|
|
||||||
Id = "Bearer" // Verweist auf die oben definierte "Bearer" Sicherheit
|
|
||||||
}
|
|
||||||
},
|
|
||||||
new string[] {} // Keine spezifischen "Scopes" f<>r JWT (leer lassen)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
c.OperationFilter<AuthorizeOperationFilter>();
|
c.OperationFilter<AuthorizeOperationFilter>();
|
||||||
|
|
||||||
c.SchemaFilter<AddExampleSchemaFilter>();
|
|
||||||
|
|
||||||
c.OperationFilter<LoginExampleOperationFilter>();
|
c.OperationFilter<LoginExampleOperationFilter>();
|
||||||
c.OperationFilter<PaymentMethodExampleOperationFilter>();
|
c.OperationFilter<PaymentMethodExampleOperationFilter>();
|
||||||
c.OperationFilter<SupplierExampleOperationFilter>();
|
c.OperationFilter<SupplierExampleOperationFilter>();
|
||||||
|
c.OperationFilter<ShippingMethodExampleOperationFilter>();
|
||||||
|
c.SchemaFilter<AddExampleSchemaFilter>();
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- ENDE: DIENSTE ZUM CONTAINER HINZUF<55>GEN ---
|
|
||||||
|
|
||||||
var app = builder.Build(); // <-- Hier wird die App gebaut
|
// --- 2. HTTP Request Pipeline Konfiguration ---
|
||||||
|
|
||||||
// OPTIONALE BL<42>CKE F<>R MIGRATION UND BENUTZERINITIALISIERUNG - DIESER CODE WIRD VOR APP.RUN() AUSGEF<45>HRT
|
var app = builder.Build();
|
||||||
// OPTIONALE BL<42>CKE F<>R MIGRATION UND BENUTZERINITIALISIERUNG - DIESER CODE WIRD VOR APP.RUN() AUSGEF<45>HRT
|
|
||||||
|
// F<>hre Datenbank-Migrationen und Initialisierungslogik beim Start aus
|
||||||
using (var scope = app.Services.CreateScope())
|
using (var scope = app.Services.CreateScope())
|
||||||
{
|
{
|
||||||
var services = scope.ServiceProvider;
|
var services = scope.ServiceProvider;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var context = services.GetRequiredService<ApplicationDbContext>();
|
var context = services.GetRequiredService<ApplicationDbContext>();
|
||||||
// Wendet ausstehende Datenbank-Migrationen an (sehr n<>tzlich f<>r Entwicklung/Tests)
|
|
||||||
context.Database.Migrate();
|
context.Database.Migrate();
|
||||||
|
|
||||||
// --- TEMPOR<4F>RER INITIALER ADMIN- UND KUNDEN-SETUP (NUR F<>R ERSTE ENTWICKLUNG!) ---
|
// TEMPOR<4F>RER INITIALER ADMIN- UND KUNDEN-SETUP
|
||||||
// Dieser Block erstellt Rollen und initiale Benutzer, falls sie noch nicht existieren.
|
// HINWEIS: Dieser Block sollte in der Produktion entfernt oder deaktiviert werden.
|
||||||
// BITTE ENTFERNEN ODER KOMMENTIEREN SIE DIESEN BLOCK AUS, NACHDEM SIE IHRE ERSTEN BENUTZER ERSTELLT HABEN!
|
|
||||||
var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();
|
var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();
|
||||||
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>(); // << KORREKT: UserManager f<>r ApplicationUser >>
|
var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
|
||||||
|
|
||||||
string[] roleNames = { "Admin", "Customer" };
|
string[] roleNames = { "Admin", "Customer" };
|
||||||
|
|
||||||
foreach (var roleName in roleNames)
|
foreach (var roleName in roleNames)
|
||||||
{
|
{
|
||||||
if (!await roleManager.RoleExistsAsync(roleName))
|
if (!await roleManager.RoleExistsAsync(roleName))
|
||||||
@@ -201,102 +179,66 @@ using (var scope = app.Services.CreateScope())
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erstelle einen initialen Admin-Benutzer und sein Customer-Profil
|
var adminUser = await userManager.FindByEmailAsync("admin@yourwebshop.com");
|
||||||
var adminUser = await userManager.FindByEmailAsync("admin@yourwebshop.com"); // << ANPASSEN >>
|
|
||||||
if (adminUser == null)
|
if (adminUser == null)
|
||||||
{
|
{
|
||||||
adminUser = new ApplicationUser // << KORREKT: ERSTELLT ApplicationUser >>
|
adminUser = new ApplicationUser { UserName = "admin@yourwebshop.com", Email = "admin@yourwebshop.com", EmailConfirmed = true, CreatedDate = DateTimeOffset.UtcNow, LastActive = DateTimeOffset.UtcNow };
|
||||||
{
|
var createAdmin = await userManager.CreateAsync(adminUser, "SecureAdminPass123!");
|
||||||
UserName = "admin@yourwebshop.com", // << ANPASSEN >>
|
|
||||||
Email = "admin@yourwebshop.com", // << ANPASSEN >>
|
|
||||||
EmailConfirmed = true,
|
|
||||||
CreatedDate = DateTimeOffset.UtcNow, // Custom Property auf ApplicationUser
|
|
||||||
LastActive = DateTimeOffset.UtcNow // Custom Property auf ApplicationUser
|
|
||||||
};
|
|
||||||
var createAdmin = await userManager.CreateAsync(adminUser, "SecureAdminPass123!"); // << ANPASSEN >>
|
|
||||||
if (createAdmin.Succeeded)
|
if (createAdmin.Succeeded)
|
||||||
{
|
{
|
||||||
await userManager.AddToRoleAsync(adminUser, "Admin");
|
await userManager.AddToRoleAsync(adminUser, "Admin");
|
||||||
Console.WriteLine("Admin user created.");
|
Console.WriteLine("Admin user created.");
|
||||||
}
|
}
|
||||||
else
|
else { Console.WriteLine($"Error creating admin user: {string.Join(", ", createAdmin.Errors.Select(e => e.Description))}"); }
|
||||||
{
|
|
||||||
Console.WriteLine($"Error creating admin user: {string.Join(", ", createAdmin.Errors.Select(e => e.Description))}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erstelle einen initialen Kunden-Benutzer und sein Customer-Profil (KOMBINIERT)
|
var customerUser = await userManager.FindByEmailAsync("customer@yourwebshop.com");
|
||||||
var customerUser = await userManager.FindByEmailAsync("customer@yourwebshop.com"); // << ANPASSEN >>
|
|
||||||
if (customerUser == null)
|
if (customerUser == null)
|
||||||
{
|
{
|
||||||
customerUser = new ApplicationUser // << KORREKT: ERSTELLT ApplicationUser >>
|
customerUser = new ApplicationUser { UserName = "customer@yourwebshop.com", Email = "customer@yourwebshop.com", EmailConfirmed = true, CreatedDate = DateTimeOffset.UtcNow, LastActive = DateTimeOffset.UtcNow };
|
||||||
{
|
var createCustomer = await userManager.CreateAsync(customerUser, "SecureCustomerPass123!");
|
||||||
UserName = "customer@yourwebshop.com", // << ANPASSEN >>
|
|
||||||
Email = "customer@yourwebshop.com", // << ANPASSEN >>
|
|
||||||
EmailConfirmed = true,
|
|
||||||
CreatedDate = DateTimeOffset.UtcNow, // Custom Property auf ApplicationUser
|
|
||||||
LastActive = DateTimeOffset.UtcNow // Custom Property auf ApplicationUser
|
|
||||||
};
|
|
||||||
var createCustomer = await userManager.CreateAsync(customerUser, "SecureCustomerPass123!"); // << ANPASSEN >>
|
|
||||||
if (createCustomer.Succeeded)
|
if (createCustomer.Succeeded)
|
||||||
{
|
{
|
||||||
await userManager.AddToRoleAsync(customerUser, "Customer");
|
await userManager.AddToRoleAsync(customerUser, "Customer");
|
||||||
Console.WriteLine("Customer user created.");
|
Console.WriteLine("Customer user created.");
|
||||||
|
|
||||||
// Kombinierter Teil: Customer-Profil erstellen, direkt nach IdentityUser-Erstellung
|
if (!await context.Customers.AnyAsync(c => c.AspNetUserId == customerUser.Id))
|
||||||
var customerProfile = await context.Customers.FirstOrDefaultAsync(c => c.AspNetUserId == customerUser.Id); // << KORREKT: SUCHT NACH AspNetUserId >>
|
|
||||||
if (customerProfile == null)
|
|
||||||
{
|
{
|
||||||
customerProfile = new Webshop.Domain.Entities.Customer
|
var customerProfile = new Customer { AspNetUserId = customerUser.Id, FirstName = "Test", LastName = "Kunde" };
|
||||||
{
|
|
||||||
Id = Guid.NewGuid(),
|
|
||||||
AspNetUserId = customerUser.Id,
|
|
||||||
FirstName = "Test",
|
|
||||||
LastName = "Kunde"
|
|
||||||
};
|
|
||||||
context.Customers.Add(customerProfile);
|
context.Customers.Add(customerProfile);
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
Console.WriteLine("Customer profile created for new customer user.");
|
Console.WriteLine("Customer profile created for new customer user.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else { Console.WriteLine($"Error creating customer user: {string.Join(", ", createCustomer.Errors.Select(e => e.Description))}"); }
|
||||||
{
|
|
||||||
Console.WriteLine($"Error creating customer user: {string.Join(", ", createCustomer.Errors.Select(e => e.Description))}");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// --- ENDE DES TEMPOR<4F>REN SETUP-BLOCKS ---
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
var logger = services.GetRequiredService<ILogger<Program>>();
|
var logger = services.GetRequiredService<ILogger<Program>>();
|
||||||
logger.LogError(ex, "An error occurred during database migration or user initialization.");
|
logger.LogError(ex, "An error occurred during database migration or user initialization.");
|
||||||
}
|
}
|
||||||
} // <-- Hier endet der using-Scope
|
}
|
||||||
|
|
||||||
// --- START: HTTP REQUEST PIPELINE KONFIGURIEREN ---
|
// Middleware f<>r Reverse-Proxies
|
||||||
|
|
||||||
// Middleware f<>r Forwarded Headers (wichtig bei Reverse-Proxies wie Nginx oder Load Balancern)
|
|
||||||
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
app.UseForwardedHeaders(new ForwardedHeadersOptions
|
||||||
{
|
{
|
||||||
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
|
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
|
||||||
});
|
});
|
||||||
|
|
||||||
// Swagger/SwaggerUI f<>r API-Dokumentation aktivieren
|
// Swagger/SwaggerUI f<>r API-Dokumentation aktivieren
|
||||||
// F<>r die Produktion w<>re es sicherer, dies an `app.Environment.IsDevelopment()` zu binden
|
if (app.Environment.IsDevelopment())
|
||||||
// if (app.Environment.IsDevelopment())
|
{
|
||||||
// {
|
app.UseSwagger();
|
||||||
app.UseSwagger();
|
app.UseSwaggerUI();
|
||||||
app.UseSwaggerUI();
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// app.UseHttpsRedirection(); // Auskommentiert f<>r Docker HTTP-Entwicklung (da der Proxy HTTPS <20>bernimmt)
|
// app.UseHttpsRedirection(); // Auskommentiert f<>r Docker HTTP-Entwicklung
|
||||||
|
|
||||||
// WICHTIG: Die Reihenfolge der Middleware ist entscheidend!
|
// WICHTIG: Die Reihenfolge ist entscheidend!
|
||||||
app.UseAuthentication(); // Zuerst pr<70>fen, wer der Benutzer ist
|
app.UseAuthentication();
|
||||||
app.UseAuthorization(); // Dann pr<70>fen, was der Benutzer darf
|
app.UseAuthorization();
|
||||||
|
|
||||||
app.MapControllers(); // Stellt sicher, dass Ihre Controller als Endpunkte gemappt werden
|
app.MapControllers();
|
||||||
|
|
||||||
// --- ENDE: HTTP REQUEST PIPELINE KONFIGURIEREN ---
|
app.Run();
|
||||||
|
|
||||||
app.Run(); // Hier startet die Anwendung und blockiert die weitere Ausf<73>hrung
|
|
||||||
@@ -6,6 +6,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Webshop.Application.DTOs;
|
using Webshop.Application.DTOs;
|
||||||
using Webshop.Application.DTOs.Auth;
|
using Webshop.Application.DTOs.Auth;
|
||||||
|
using Webshop.Application.DTOs.Categories; // Korrigierter Namespace
|
||||||
using Webshop.Application.DTOs.Categorys;
|
using Webshop.Application.DTOs.Categorys;
|
||||||
using Webshop.Application.DTOs.Customers;
|
using Webshop.Application.DTOs.Customers;
|
||||||
using Webshop.Application.DTOs.Discounts;
|
using Webshop.Application.DTOs.Discounts;
|
||||||
@@ -55,7 +56,7 @@ namespace Webshop.Api.SwaggerFilters
|
|||||||
{
|
{
|
||||||
["isAuthSuccessful"] = new OpenApiBoolean(true),
|
["isAuthSuccessful"] = new OpenApiBoolean(true),
|
||||||
["errorMessage"] = new OpenApiString(""),
|
["errorMessage"] = new OpenApiString(""),
|
||||||
["token"] = new OpenApiString("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"),
|
["token"] = new OpenApiString("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."),
|
||||||
["userId"] = new OpenApiString(Guid.NewGuid().ToString()),
|
["userId"] = new OpenApiString(Guid.NewGuid().ToString()),
|
||||||
["email"] = new OpenApiString("loggedin@example.com"),
|
["email"] = new OpenApiString("loggedin@example.com"),
|
||||||
["roles"] = new OpenApiArray { new OpenApiString("Customer") }
|
["roles"] = new OpenApiArray { new OpenApiString("Customer") }
|
||||||
@@ -81,10 +82,7 @@ namespace Webshop.Api.SwaggerFilters
|
|||||||
}
|
}
|
||||||
else if (type == typeof(ResendEmailConfirmationRequestDto))
|
else if (type == typeof(ResendEmailConfirmationRequestDto))
|
||||||
{
|
{
|
||||||
schema.Example = new OpenApiObject
|
schema.Example = new OpenApiObject { ["email"] = new OpenApiString("unconfirmed.user@example.com") };
|
||||||
{
|
|
||||||
["email"] = new OpenApiString("unconfirmed.user@example.com")
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
else if (type == typeof(ChangePasswordRequestDto))
|
else if (type == typeof(ChangePasswordRequestDto))
|
||||||
{
|
{
|
||||||
@@ -149,43 +147,10 @@ namespace Webshop.Api.SwaggerFilters
|
|||||||
["lastModifiedDate"] = new OpenApiNull(),
|
["lastModifiedDate"] = new OpenApiNull(),
|
||||||
["supplierId"] = new OpenApiNull(),
|
["supplierId"] = new OpenApiNull(),
|
||||||
["purchasePrice"] = new OpenApiDouble(80.00),
|
["purchasePrice"] = new OpenApiDouble(80.00),
|
||||||
["categoryIds"] = new OpenApiArray
|
["categoryIds"] = new OpenApiArray { new OpenApiString("EXISTING_CATEGORY_ID_HERE") }
|
||||||
{
|
|
||||||
new OpenApiString("EXISTING_CATEGORY_ID_1"),
|
|
||||||
new OpenApiString("EXISTING_CATEGORY_ID_2")
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (type == typeof(ProductVariantDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["id"] = new OpenApiString(Guid.Empty.ToString()),
|
|
||||||
["productId"] = new OpenApiString("EIN_PRODUKT_GUID_HIER"),
|
|
||||||
["name"] = new OpenApiString("Variante: Schwarz L"),
|
|
||||||
["value"] = new OpenApiString("Schwarz, L"),
|
|
||||||
["sku"] = new OpenApiString($"VARIANT-ABC-{uniqueId}"),
|
|
||||||
["priceAdjustment"] = new OpenApiDouble(5.00),
|
|
||||||
["stockQuantity"] = new OpenApiInteger(25),
|
|
||||||
["imageUrl"] = new OpenApiString("https://example.com/images/prod-variant-red.jpg"),
|
|
||||||
["isActive"] = new OpenApiBoolean(true)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// --- Kategorien ---
|
// --- Kategorien ---
|
||||||
else if (type == typeof(CategoryDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["id"] = new OpenApiString(Guid.NewGuid().ToString()),
|
|
||||||
["name"] = new OpenApiString($"Elektronik {uniqueId}"),
|
|
||||||
["slug"] = new OpenApiString($"elektronik-{uniqueId}"),
|
|
||||||
["description"] = new OpenApiString("Produkte rund um Elektronik."),
|
|
||||||
["parentCategoryId"] = new OpenApiNull(),
|
|
||||||
["imageUrl"] = new OpenApiString("https://example.com/images/category_electronics.jpg"),
|
|
||||||
["isActive"] = new OpenApiBoolean(true),
|
|
||||||
["displayOrder"] = new OpenApiInteger(1)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (type == typeof(CreateCategoryDto))
|
else if (type == typeof(CreateCategoryDto))
|
||||||
{
|
{
|
||||||
schema.Example = new OpenApiObject
|
schema.Example = new OpenApiObject
|
||||||
@@ -204,7 +169,7 @@ namespace Webshop.Api.SwaggerFilters
|
|||||||
{
|
{
|
||||||
schema.Example = new OpenApiObject
|
schema.Example = new OpenApiObject
|
||||||
{
|
{
|
||||||
["id"] = new OpenApiString(Guid.Empty.ToString()),
|
["id"] = new OpenApiString(Guid.NewGuid().ToString()),
|
||||||
["street"] = new OpenApiString("Musterstraße"),
|
["street"] = new OpenApiString("Musterstraße"),
|
||||||
["houseNumber"] = new OpenApiString("123a"),
|
["houseNumber"] = new OpenApiString("123a"),
|
||||||
["city"] = new OpenApiString("Musterstadt"),
|
["city"] = new OpenApiString("Musterstadt"),
|
||||||
@@ -214,20 +179,6 @@ namespace Webshop.Api.SwaggerFilters
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
// --- Kunden ---
|
// --- Kunden ---
|
||||||
else if (type == typeof(CustomerDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["id"] = new OpenApiString(Guid.NewGuid().ToString()),
|
|
||||||
["userId"] = new OpenApiString("EIN_IDENTITY_USER_ID_HIER"),
|
|
||||||
["firstName"] = new OpenApiString("Max"),
|
|
||||||
["lastName"] = new OpenApiString("Mustermann"),
|
|
||||||
["email"] = new OpenApiString($"max.mustermann.{uniqueId}@example.com"),
|
|
||||||
["phoneNumber"] = new OpenApiString("+491719876543"),
|
|
||||||
["defaultShippingAddressId"] = new OpenApiNull(),
|
|
||||||
["defaultBillingAddressId"] = new OpenApiNull()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (type == typeof(UpdateCustomerDto))
|
else if (type == typeof(UpdateCustomerDto))
|
||||||
{
|
{
|
||||||
schema.Example = new OpenApiObject
|
schema.Example = new OpenApiObject
|
||||||
@@ -240,32 +191,11 @@ namespace Webshop.Api.SwaggerFilters
|
|||||||
["defaultBillingAddressId"] = new OpenApiNull()
|
["defaultBillingAddressId"] = new OpenApiNull()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// --- Rabatte ---
|
|
||||||
else if (type == typeof(DiscountDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["id"] = new OpenApiString(Guid.Empty.ToString()),
|
|
||||||
["name"] = new OpenApiString($"Sommerrabatt {uniqueId}"),
|
|
||||||
["description"] = new OpenApiString("10% Rabatt auf alles"),
|
|
||||||
["type"] = new OpenApiString(DiscountType.Percentage.ToString()),
|
|
||||||
["value"] = new OpenApiDouble(10.00),
|
|
||||||
["couponCode"] = new OpenApiString($"SOMMER-{uniqueId}"),
|
|
||||||
["startDate"] = new OpenApiString(DateTimeOffset.UtcNow.AddDays(1).ToString("o")),
|
|
||||||
["endDate"] = new OpenApiString(DateTimeOffset.UtcNow.AddDays(30).ToString("o")),
|
|
||||||
["isActive"] = new OpenApiBoolean(true),
|
|
||||||
["maxUses"] = new OpenApiInteger(100),
|
|
||||||
["currentUses"] = new OpenApiInteger(0)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// --- Bestellungen ---
|
// --- Bestellungen ---
|
||||||
else if (type == typeof(CreateOrderDto))
|
else if (type == typeof(CreateOrderDto))
|
||||||
{
|
{
|
||||||
schema.Example = new OpenApiObject
|
schema.Example = new OpenApiObject
|
||||||
{
|
{
|
||||||
["customerId"] = new OpenApiString("CUSTOMER_ID_HERE"),
|
|
||||||
["guestEmail"] = new OpenApiString($"gast.besteller.{uniqueId}@example.com"),
|
|
||||||
["guestPhoneNumber"] = new OpenApiString("+4917611223344"),
|
|
||||||
["shippingAddressId"] = new OpenApiString("VALID_ADDRESS_ID_HERE"),
|
["shippingAddressId"] = new OpenApiString("VALID_ADDRESS_ID_HERE"),
|
||||||
["billingAddressId"] = new OpenApiString("VALID_ADDRESS_ID_HERE"),
|
["billingAddressId"] = new OpenApiString("VALID_ADDRESS_ID_HERE"),
|
||||||
["paymentMethodId"] = new OpenApiString("VALID_PAYMENT_METHOD_ID_HERE"),
|
["paymentMethodId"] = new OpenApiString("VALID_PAYMENT_METHOD_ID_HERE"),
|
||||||
@@ -280,110 +210,6 @@ namespace Webshop.Api.SwaggerFilters
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
else if (type == typeof(CreateOrderItemDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["productId"] = new OpenApiString("VALID_PRODUCT_ID_HERE"),
|
|
||||||
["productVariantId"] = new OpenApiNull(),
|
|
||||||
["quantity"] = new OpenApiInteger(1)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (type == typeof(OrderSummaryDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["id"] = new OpenApiString(Guid.NewGuid().ToString()),
|
|
||||||
["orderNumber"] = new OpenApiString($"WS-2025-{uniqueId}"),
|
|
||||||
["orderDate"] = new OpenApiString(DateTimeOffset.UtcNow.ToString("o")),
|
|
||||||
["status"] = new OpenApiString(OrderStatus.Processing.ToString()),
|
|
||||||
["totalAmount"] = new OpenApiDouble(123.45),
|
|
||||||
["paymentStatus"] = new OpenApiString(PaymentStatus.Paid.ToString()),
|
|
||||||
["paymentMethodName"] = new OpenApiString("Kreditkarte"),
|
|
||||||
["shippingMethodName"] = new OpenApiString("Standardversand")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (type == typeof(OrderDetailDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["id"] = new OpenApiString(Guid.NewGuid().ToString()),
|
|
||||||
["orderNumber"] = new OpenApiString($"WS-2025-{uniqueId}-Detail"),
|
|
||||||
["customerId"] = new OpenApiString(Guid.NewGuid().ToString()),
|
|
||||||
["orderDate"] = new OpenApiString(DateTimeOffset.UtcNow.ToString("o")),
|
|
||||||
["status"] = new OpenApiString(OrderStatus.Shipped.ToString()),
|
|
||||||
["totalAmount"] = new OpenApiDouble(245.67),
|
|
||||||
["shippingAddressId"] = new OpenApiString("EXISTING_ADDRESS_ID"),
|
|
||||||
["billingAddressId"] = new OpenApiString("EXISTING_ADDRESS_ID"),
|
|
||||||
["paymentMethodId"] = new OpenApiString("EXISTING_PAYMENT_METHOD_ID"),
|
|
||||||
["orderItems"] = new OpenApiArray {
|
|
||||||
new OpenApiObject { ["id"] = new OpenApiString(Guid.NewGuid().ToString()), ["productId"] = new OpenApiString("PROD_B_ID"), ["productName"] = new OpenApiString("Produkt B"), ["quantity"] = new OpenApiInteger(1), ["unitPrice"] = new OpenApiDouble(199.99), ["totalPrice"] = new OpenApiDouble(199.99) }
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// --- Bewertungen ---
|
|
||||||
else if (type == typeof(ReviewDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["id"] = new OpenApiString(Guid.NewGuid().ToString()),
|
|
||||||
["productId"] = new OpenApiString("EXISTING_PRODUCT_ID_HERE"),
|
|
||||||
["customerId"] = new OpenApiString("EXISTING_CUSTOMER_ID_HERE"),
|
|
||||||
["rating"] = new OpenApiInteger(5),
|
|
||||||
["title"] = new OpenApiString($"Super Produkt! ({uniqueId})"),
|
|
||||||
["comment"] = new OpenApiString("Ich bin sehr zufrieden mit diesem Produkt."),
|
|
||||||
["reviewDate"] = new OpenApiString(DateTimeOffset.UtcNow.ToString("o")),
|
|
||||||
["isApproved"] = new OpenApiBoolean(false)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else if (type == typeof(CreateReviewDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["productId"] = new OpenApiString("EXISTING_PRODUCT_ID_HERE"),
|
|
||||||
["rating"] = new OpenApiInteger(4),
|
|
||||||
["title"] = new OpenApiString($"Gute Qualität ({uniqueId})"),
|
|
||||||
["comment"] = new OpenApiString("Das Produkt ist gut, aber die Lieferung dauerte etwas.")
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// --- Einstellungen ---
|
|
||||||
else if (type == typeof(SettingDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["key"] = new OpenApiString($"GlobalTaxRate-{uniqueId}"),
|
|
||||||
["value"] = new OpenApiString("0.19"),
|
|
||||||
["description"] = new OpenApiString("Allgemeiner Mehrwertsteuersatz"),
|
|
||||||
["lastModifiedDate"] = new OpenApiString(DateTimeOffset.UtcNow.ToString("o"))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// --- Zahlungsmethoden ---
|
|
||||||
else if (type == typeof(PaymentMethodDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["id"] = new OpenApiString(Guid.Empty.ToString()),
|
|
||||||
["name"] = new OpenApiString($"Kreditkarte (Stripe) {uniqueId}"),
|
|
||||||
["description"] = new OpenApiString("Online-Zahlungsdienstleister."),
|
|
||||||
["isActive"] = new OpenApiBoolean(true),
|
|
||||||
["gatewayType"] = new OpenApiString(PaymentGatewayType.Stripe.ToString()),
|
|
||||||
["processingFee"] = new OpenApiDouble(0.035)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
// --- Versandmethoden ---
|
|
||||||
else if (type == typeof(ShippingMethodDto))
|
|
||||||
{
|
|
||||||
schema.Example = new OpenApiObject
|
|
||||||
{
|
|
||||||
["id"] = new OpenApiString(Guid.Empty.ToString()),
|
|
||||||
["name"] = new OpenApiString($"Expressversand UPS {uniqueId}"),
|
|
||||||
["description"] = new OpenApiString("Lieferung am nächsten Werktag."),
|
|
||||||
["cost"] = new OpenApiDouble(12.50),
|
|
||||||
["isActive"] = new OpenApiBoolean(true),
|
|
||||||
["minDeliveryDays"] = new OpenApiInteger(1),
|
|
||||||
["maxDeliveryDays"] = new OpenApiInteger(1)
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// src/Webshop.Api/SwaggerFilters/ShippingMethodExampleOperationFilter.cs
|
||||||
|
using Microsoft.OpenApi.Models;
|
||||||
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
using Microsoft.OpenApi.Any;
|
||||||
|
using System.Net.Mime;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Webshop.Api.SwaggerFilters
|
||||||
|
{
|
||||||
|
public class ShippingMethodExampleOperationFilter : IOperationFilter
|
||||||
|
{
|
||||||
|
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
||||||
|
{
|
||||||
|
if (context.MethodInfo.DeclaringType == typeof(Controllers.Admin.AdminShippingMethodsController) &&
|
||||||
|
context.MethodInfo.Name == "CreateShippingMethod")
|
||||||
|
{
|
||||||
|
if (operation.RequestBody == null ||
|
||||||
|
!operation.RequestBody.Content.TryGetValue(MediaTypeNames.Application.Json, out var mediaType))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mediaType.Examples == null)
|
||||||
|
{
|
||||||
|
mediaType.Examples = new Dictionary<string, OpenApiExample>();
|
||||||
|
}
|
||||||
|
mediaType.Examples.Clear();
|
||||||
|
|
||||||
|
mediaType.Examples["Standard"] = new OpenApiExample
|
||||||
|
{
|
||||||
|
Summary = "Beispiel: Standardversand",
|
||||||
|
Value = new OpenApiObject
|
||||||
|
{
|
||||||
|
["name"] = new OpenApiString("Standardversand (DHL)"),
|
||||||
|
["description"] = new OpenApiString("Lieferung in 2-3 Werktagen."),
|
||||||
|
["cost"] = new OpenApiDouble(4.99),
|
||||||
|
["isActive"] = new OpenApiBoolean(true),
|
||||||
|
["minDeliveryDays"] = new OpenApiInteger(2),
|
||||||
|
["maxDeliveryDays"] = new OpenApiInteger(3)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mediaType.Examples["Express"] = new OpenApiExample
|
||||||
|
{
|
||||||
|
Summary = "Beispiel: Expressversand",
|
||||||
|
Value = new OpenApiObject
|
||||||
|
{
|
||||||
|
["name"] = new OpenApiString("Expressversand (UPS)"),
|
||||||
|
["description"] = new OpenApiString("Lieferung am nächsten Werktag."),
|
||||||
|
["cost"] = new OpenApiDouble(12.99),
|
||||||
|
["isActive"] = new OpenApiBoolean(true),
|
||||||
|
["minDeliveryDays"] = new OpenApiInteger(1),
|
||||||
|
["maxDeliveryDays"] = new OpenApiInteger(1)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user