实现产品管理微服务
This commit is contained in:
parent
77b9f64039
commit
f742b2ea0e
@ -0,0 +1,21 @@
|
||||
using AutoMapper;
|
||||
using HelloShop.ProductService.Entities.Products;
|
||||
using HelloShop.ProductService.Models.Products;
|
||||
|
||||
namespace HelloShop.ProductService.AutoMapper;
|
||||
|
||||
public class ProductsMapConfiguration : Profile
|
||||
{
|
||||
public ProductsMapConfiguration()
|
||||
{
|
||||
CreateMap<ProductCreateRequest, Product>();
|
||||
CreateMap<ProductUpdateRequest, Product>();
|
||||
CreateMap<Product, ProductListItem>().AfterMap((src, dest) => dest.BrandName = src.Brand.Name);
|
||||
CreateMap<Product, ProductDetailsResponse>();
|
||||
|
||||
CreateMap<BrandCreateRequest, Brand>();
|
||||
CreateMap<BrandUpdateRequest, Brand>();
|
||||
CreateMap<Brand, BrandDetailsResponse>();
|
||||
CreateMap<Brand, BrandListItem>();
|
||||
}
|
||||
}
|
6
src/HelloShop.ProductService/Constants/DbConstants.cs
Normal file
6
src/HelloShop.ProductService/Constants/DbConstants.cs
Normal file
@ -0,0 +1,6 @@
|
||||
namespace HelloShop.ProductService.Constants;
|
||||
|
||||
public static class DbConstants
|
||||
{
|
||||
public const string ConnectionStringName = "ProductDatabase";
|
||||
}
|
115
src/HelloShop.ProductService/Controllers/BrandsController.cs
Normal file
115
src/HelloShop.ProductService/Controllers/BrandsController.cs
Normal file
@ -0,0 +1,115 @@
|
||||
using AutoMapper;
|
||||
using HelloShop.ProductService.Entities.Products;
|
||||
using HelloShop.ProductService.EntityFrameworks;
|
||||
using HelloShop.ProductService.Models.Products;
|
||||
using HelloShop.ServiceDefaults.Models.Paging;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using HelloShop.ServiceDefaults.Extensions;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using HelloShop.ProductService.PermissionProviders;
|
||||
|
||||
namespace HelloShop.ProductService;
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class BrandsController(ProductServiceDbContext dbContext, IMapper mapper) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Authorize(CatalogPermissions.Brands.Default)]
|
||||
public async Task<ActionResult<PagedResponse<BrandListItem>>> GetBrands([FromQuery] KeywordSearchRequest model)
|
||||
{
|
||||
IQueryable<Brand> query = dbContext.Set<Brand>().AsNoTracking();
|
||||
|
||||
query = query.WhereIf(model.Keyword is not null, x => model.Keyword != null && x.Name.Contains(model.Keyword));
|
||||
|
||||
var pagedBrands = query.SortAndPageBy(model);
|
||||
|
||||
return new PagedResponse<BrandListItem>(mapper.Map<List<BrandListItem>>(await pagedBrands.ToListAsync()), await query.CountAsync());
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(CatalogPermissions.Brands.Details)]
|
||||
public async Task<ActionResult<BrandDetailsResponse>> GetBrand(int id)
|
||||
{
|
||||
Brand? entity = await dbContext.Set<Brand>().FindAsync(id);
|
||||
|
||||
if (entity is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
return mapper.Map<BrandDetailsResponse>(entity);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Authorize(CatalogPermissions.Brands.Create)]
|
||||
public async Task<ActionResult<BrandDetailsResponse>> PostBrand(BrandCreateRequest model)
|
||||
{
|
||||
Brand entity = mapper.Map<Brand>(model);
|
||||
|
||||
await dbContext.AddAsync(entity);
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
BrandDetailsResponse result = mapper.Map<BrandDetailsResponse>(entity);
|
||||
|
||||
return CreatedAtAction(nameof(GetBrand), new { id = entity.Id }, result);
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(CatalogPermissions.Brands.Update)]
|
||||
public async Task<IActionResult> PutBrand(int id, BrandUpdateRequest model)
|
||||
{
|
||||
if (id != model.Id)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
Brand entity = mapper.Map<Brand>(model);
|
||||
|
||||
dbContext.Entry(entity).State = EntityState.Modified;
|
||||
|
||||
try
|
||||
{
|
||||
await dbContext.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!dbContext.Set<Brand>().Any(e => e.Id == id))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(CatalogPermissions.Brands.Delete)]
|
||||
public async Task<IActionResult> DeleteBrand(int id)
|
||||
{
|
||||
Brand? entity = await dbContext.Set<Brand>().FindAsync(id);
|
||||
|
||||
if (entity is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
dbContext.Remove(entity);
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Authorize(CatalogPermissions.Brands.Delete)]
|
||||
public async Task<IActionResult> DeleteBrands([FromQuery] IEnumerable<int> ids)
|
||||
{
|
||||
await dbContext.Set<Brand>().Where(e => ids.Contains(e.Id)).ExecuteDeleteAsync();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
118
src/HelloShop.ProductService/Controllers/ProductsController.cs
Normal file
118
src/HelloShop.ProductService/Controllers/ProductsController.cs
Normal file
@ -0,0 +1,118 @@
|
||||
using HelloShop.ProductService.Entities.Products;
|
||||
using HelloShop.ProductService.EntityFrameworks;
|
||||
using HelloShop.ProductService.Models.Products;
|
||||
using HelloShop.ServiceDefaults.Models.Paging;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using HelloShop.ServiceDefaults.Extensions;
|
||||
using AutoMapper;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using HelloShop.ProductService.PermissionProviders;
|
||||
|
||||
namespace HelloShop.ProductService;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class ProductsController(ProductServiceDbContext dbContext, IMapper mapper) : ControllerBase
|
||||
{
|
||||
[HttpGet]
|
||||
[Authorize(CatalogPermissions.Products.Default)]
|
||||
public async Task<ActionResult<PagedResponse<ProductListItem>>> GetProducts([FromQuery] KeywordSearchRequest model)
|
||||
{
|
||||
IQueryable<Product> query = dbContext.Set<Product>().Include(x => x.Brand).AsNoTracking();
|
||||
|
||||
query = query.WhereIf(model.Keyword is not null, x => model.Keyword != null && x.Name.Contains(model.Keyword));
|
||||
|
||||
var pagedProducts = query.SortAndPageBy(model);
|
||||
|
||||
return new PagedResponse<ProductListItem>(mapper.Map<List<ProductListItem>>(await pagedProducts.ToListAsync()), await query.CountAsync());
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
[Authorize(CatalogPermissions.Products.Details)]
|
||||
public async Task<ActionResult<ProductDetailsResponse>> GetProduct(int id)
|
||||
{
|
||||
Product? entity = await dbContext.Set<Product>().FindAsync(id);
|
||||
|
||||
if (entity is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
await dbContext.Entry(entity).Reference(e => e.Brand).LoadAsync();
|
||||
|
||||
return mapper.Map<ProductDetailsResponse>(entity);
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[Authorize(CatalogPermissions.Products.Create)]
|
||||
public async Task<ActionResult<ProductDetailsResponse>> PostProduct(ProductCreateRequest model)
|
||||
{
|
||||
Product entity = mapper.Map<Product>(model);
|
||||
|
||||
await dbContext.AddAsync(entity);
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
|
||||
ProductDetailsResponse result = mapper.Map<ProductDetailsResponse>(entity);
|
||||
|
||||
return CreatedAtAction(nameof(GetProduct), new { id = entity.Id }, result);
|
||||
}
|
||||
|
||||
[HttpPut("{id}")]
|
||||
[Authorize(CatalogPermissions.Products.Update)]
|
||||
public async Task<IActionResult> PutProduct(int id, ProductUpdateRequest model)
|
||||
{
|
||||
if (id != model.Id)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
Product entity = mapper.Map<Product>(model);
|
||||
|
||||
dbContext.Entry(entity).State = EntityState.Modified;
|
||||
|
||||
try
|
||||
{
|
||||
await dbContext.SaveChangesAsync();
|
||||
}
|
||||
catch (DbUpdateConcurrencyException)
|
||||
{
|
||||
if (!dbContext.Set<Product>().Any(e => e.Id == id))
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete("{id}")]
|
||||
[Authorize(CatalogPermissions.Products.Delete)]
|
||||
public async Task<IActionResult> DeleteProduct(int id)
|
||||
{
|
||||
Product? entity = await dbContext.Set<Product>().FindAsync(id);
|
||||
|
||||
if (entity is null)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
dbContext.Remove(entity);
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
[Authorize(CatalogPermissions.Products.Delete)]
|
||||
public async Task<IActionResult> DeleteProducts([FromQuery] IEnumerable<int> ids)
|
||||
{
|
||||
await dbContext.Set<Product>().Where(e => ids.Contains(e.Id)).ExecuteDeleteAsync();
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace HelloShop.ProductService.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class WeatherForecastController : ControllerBase
|
||||
{
|
||||
private static readonly string[] Summaries = new[]
|
||||
{
|
||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
||||
};
|
||||
|
||||
private readonly ILogger<WeatherForecastController> _logger;
|
||||
|
||||
public WeatherForecastController(ILogger<WeatherForecastController> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetWeatherForecast")]
|
||||
public IEnumerable<WeatherForecast> Get()
|
||||
{
|
||||
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
||||
{
|
||||
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
|
||||
TemperatureC = Random.Shared.Next(-20, 55),
|
||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
using HelloShop.ProductService.Entities.Products;
|
||||
using HelloShop.ProductService.EntityFrameworks;
|
||||
using HelloShop.ServiceDefaults.Infrastructure;
|
||||
|
||||
namespace HelloShop.ProductService.DataSeeding
|
||||
{
|
||||
public class ProductDataSeedingProvider(ProductServiceDbContext dbContext) : IDataSeedingProvider
|
||||
{
|
||||
public async Task SeedingAsync(IServiceProvider ServiceProvider)
|
||||
{
|
||||
if (!dbContext.Set<Product>().Any())
|
||||
{
|
||||
Dictionary<string, List<Product>> products = new()
|
||||
{
|
||||
{ "Google", new List<Product>{
|
||||
new() { Name = "Android", Price = 156.99m },
|
||||
new() { Name = "Gmail", Price = 135.82m },
|
||||
new() { Name = "Google Drive", Price = 99.99m },
|
||||
new() { Name = "Google Maps", Price = 199.99m },
|
||||
new() { Name = "Google Photos", Price = 299.99m },
|
||||
new() { Name = "Google Play", Price = 399.99m },
|
||||
new() { Name = "Google Search", Price = 499.99m },
|
||||
new() { Name = "Google Translate", Price = 599.99m },
|
||||
new() { Name = "Google Chrome", Price = 699.99m },
|
||||
new() { Name = "Google Earth", Price = 799.99m },
|
||||
}},
|
||||
{ "Microsoft", new List<Product>{
|
||||
new() { Name = "Windows", Price = 156.99m },
|
||||
new() { Name = "Office", Price = 135.82m },
|
||||
new() { Name = "Azure", Price = 99.99m },
|
||||
new() { Name = "Xbox", Price = 199.99m },
|
||||
new() { Name = "Skype", Price = 299.99m },
|
||||
new() { Name = "LinkedIn", Price = 399.99m },
|
||||
new() { Name = "GitHub", Price = 499.99m },
|
||||
new() { Name = "Visual Studio", Price = 599.99m },
|
||||
new() { Name = "Bing", Price = 699.99m },
|
||||
new() { Name = "OneDrive", Price = 799.99m },
|
||||
}},
|
||||
{ "Apple", new List<Product>{
|
||||
new() { Name = "iPhone", Price = 156.99m },
|
||||
new() { Name = "iPad", Price = 135.82m },
|
||||
new() { Name = "Mac", Price = 99.99m },
|
||||
new() { Name = "Apple Watch", Price = 199.99m },
|
||||
new() { Name = "Apple TV", Price = 299.99m },
|
||||
new() { Name = "AirPods", Price = 399.99m },
|
||||
new() { Name = "HomePod", Price = 499.99m },
|
||||
new() { Name = "iPod", Price = 599.99m },
|
||||
new() { Name = "Apple Music", Price = 699.99m },
|
||||
new() { Name = "Apple Pay", Price = 799.99m },
|
||||
}},
|
||||
{ "Amazon", new List<Product>{
|
||||
new() { Name = "Amazon Prime", Price = 156.99m },
|
||||
new() { Name = "Kindle", Price = 135.82m },
|
||||
new() { Name = "Fire TV", Price = 99.99m },
|
||||
new() { Name = "Echo", Price = 199.99m },
|
||||
new() { Name = "Ring", Price = 299.99m },
|
||||
new() { Name = "Twitch", Price = 399.99m },
|
||||
new() { Name = "Audible", Price = 499.99m },
|
||||
new() { Name = "Goodreads", Price = 599.99m },
|
||||
new() { Name = "IMDb", Price = 699.99m },
|
||||
new() { Name = "Whole Foods", Price = 799.99m },
|
||||
}},
|
||||
{ "Samsung", new List<Product>
|
||||
{
|
||||
new() { Name = "Galaxy", Price = 156.99m },
|
||||
new() { Name = "SmartThings", Price = 135.82m },
|
||||
new() { Name = "Samsung Pay", Price = 99.99m },
|
||||
new() { Name = "Samsung Health", Price = 199.99m },
|
||||
new() { Name = "Samsung DeX", Price = 299.99m },
|
||||
new() { Name = "Samsung Knox", Price = 399.99m },
|
||||
new() { Name = "Samsung Internet", Price = 499.99m },
|
||||
new() { Name = "Samsung Cloud", Price = 599.99m },
|
||||
new() { Name = "Samsung TV", Price = 699.99m },
|
||||
new() { Name = "Samsung Galaxy Store", Price = 799.99m },
|
||||
}}
|
||||
};
|
||||
|
||||
foreach (var (brandName, productList) in products)
|
||||
{
|
||||
var brand = new Brand { Name = brandName };
|
||||
|
||||
await dbContext.AddAsync(brand);
|
||||
|
||||
foreach (var product in productList)
|
||||
{
|
||||
product.Brand = brand;
|
||||
await dbContext.AddAsync(product);
|
||||
}
|
||||
}
|
||||
|
||||
await dbContext.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
src/HelloShop.ProductService/Entities/Products/Brand.cs
Normal file
9
src/HelloShop.ProductService/Entities/Products/Brand.cs
Normal file
@ -0,0 +1,9 @@
|
||||
namespace HelloShop.ProductService.Entities.Products
|
||||
{
|
||||
public class Brand
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public required string Name { get; set; }
|
||||
}
|
||||
}
|
21
src/HelloShop.ProductService/Entities/Products/Product.cs
Normal file
21
src/HelloShop.ProductService/Entities/Products/Product.cs
Normal file
@ -0,0 +1,21 @@
|
||||
namespace HelloShop.ProductService.Entities.Products
|
||||
{
|
||||
public class Product
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public required string Name { get; set; }
|
||||
|
||||
public string? Description { get; set; }
|
||||
|
||||
public decimal Price { get; set; }
|
||||
|
||||
public int BrandId { get; set; }
|
||||
|
||||
public Brand Brand { get; set; } = default!;
|
||||
|
||||
public string? ImageUrl { get; set; }
|
||||
|
||||
public DateTimeOffset CreationTime { get; init; } = TimeProvider.System.GetUtcNow();
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using HelloShop.ProductService.Entities.Products;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace HelloShop.ProductService.EntityFrameworks.EntityConfigurations.Products;
|
||||
|
||||
public class BrandEntityTypeConfiguration : IEntityTypeConfiguration<Brand>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Brand> builder)
|
||||
{
|
||||
builder.ToTable("Brands");
|
||||
builder.Property(x => x.Name).HasMaxLength(32);
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
using HelloShop.ProductService.Entities.Products;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
|
||||
namespace HelloShop.ProductService.EntityFrameworks.EntityConfigurations.Products;
|
||||
|
||||
public class ProductEntityTypeConfiguration : IEntityTypeConfiguration<Product>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<Product> builder)
|
||||
{
|
||||
builder.ToTable("Products");
|
||||
|
||||
builder.Property(x => x.Name).HasMaxLength(32);
|
||||
|
||||
builder.Property(x => x.ImageUrl).HasMaxLength(256);
|
||||
|
||||
builder.HasOne(x => x.Brand).WithMany();
|
||||
}
|
||||
}
|
95
src/HelloShop.ProductService/EntityFrameworks/Migrations/20240419145737_InitialCreate.Designer.cs
generated
Normal file
95
src/HelloShop.ProductService/EntityFrameworks/Migrations/20240419145737_InitialCreate.Designer.cs
generated
Normal file
@ -0,0 +1,95 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using HelloShop.ProductService.EntityFrameworks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace HelloShop.ProductService.EntityFrameworks.Migrations
|
||||
{
|
||||
[DbContext(typeof(ProductServiceDbContext))]
|
||||
[Migration("20240419145737_InitialCreate")]
|
||||
partial class InitialCreate
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("HelloShop.ProductService.Entities.Products.Brand", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("character varying(32)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Brands", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HelloShop.ProductService.Entities.Products.Product", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BrandId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTimeOffset>("CreationTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ImageUrl")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("character varying(32)");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BrandId");
|
||||
|
||||
b.ToTable("Products", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HelloShop.ProductService.Entities.Products.Product", b =>
|
||||
{
|
||||
b.HasOne("HelloShop.ProductService.Entities.Products.Brand", "Brand")
|
||||
.WithMany()
|
||||
.HasForeignKey("BrandId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Brand");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace HelloShop.ProductService.EntityFrameworks.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialCreate : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Brands",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Name = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Brands", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Products",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Name = table.Column<string>(type: "character varying(32)", maxLength: 32, nullable: false),
|
||||
Description = table.Column<string>(type: "text", nullable: true),
|
||||
Price = table.Column<decimal>(type: "numeric", nullable: false),
|
||||
BrandId = table.Column<int>(type: "integer", nullable: false),
|
||||
ImageUrl = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
CreationTime = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Products", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_Products_Brands_BrandId",
|
||||
column: x => x.BrandId,
|
||||
principalTable: "Brands",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_Products_BrandId",
|
||||
table: "Products",
|
||||
column: "BrandId");
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "Products");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Brands");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using HelloShop.ProductService.EntityFrameworks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace HelloShop.ProductService.EntityFrameworks.Migrations
|
||||
{
|
||||
[DbContext(typeof(ProductServiceDbContext))]
|
||||
partial class ProductServiceDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.4")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("HelloShop.ProductService.Entities.Products.Brand", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("character varying(32)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Brands", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HelloShop.ProductService.Entities.Products.Product", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<int>("BrandId")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<DateTimeOffset>("CreationTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ImageUrl")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(32)
|
||||
.HasColumnType("character varying(32)");
|
||||
|
||||
b.Property<decimal>("Price")
|
||||
.HasColumnType("numeric");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("BrandId");
|
||||
|
||||
b.ToTable("Products", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("HelloShop.ProductService.Entities.Products.Product", b =>
|
||||
{
|
||||
b.HasOne("HelloShop.ProductService.Entities.Products.Brand", "Brand")
|
||||
.WithMany()
|
||||
.HasForeignKey("BrandId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Brand");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Reflection;
|
||||
|
||||
namespace HelloShop.ProductService.EntityFrameworks;
|
||||
|
||||
public class ProductServiceDbContext(DbContextOptions<ProductServiceDbContext> options) : DbContext(options)
|
||||
{
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
|
||||
builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
|
||||
}
|
||||
}
|
@ -5,9 +5,20 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.4">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.2" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\HelloShop.ServiceDefaults\HelloShop.ServiceDefaults.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Resources\" />
|
||||
<Folder Include="Resources\Models\" />
|
||||
<Folder Include="Resources\Models\Products\" />
|
||||
<Folder Include="Resources\PermissionProviders\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -0,0 +1,6 @@
|
||||
namespace HelloShop.ProductService.Models.Products;
|
||||
|
||||
public class BrandCreateRequest
|
||||
{
|
||||
public required string Name { get; init; }
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace HelloShop.ProductService.Models.Products;
|
||||
|
||||
public class BrandDetailsResponse
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public required string Name { get; set; }
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace HelloShop.ProductService.Models.Products;
|
||||
|
||||
public class BrandListItem
|
||||
{
|
||||
public int Id { get; set; }
|
||||
|
||||
public required string Name { get; set; }
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
namespace HelloShop.ProductService.Models.Products;
|
||||
|
||||
public class BrandUpdateRequest
|
||||
{
|
||||
public int Id { get; init; }
|
||||
|
||||
public required string Name { get; init; }
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
namespace HelloShop.ProductService.Models.Products
|
||||
{
|
||||
public class ProductCreateRequest
|
||||
{
|
||||
public required string Name { get; init; }
|
||||
|
||||
public string? Description { get; init; }
|
||||
|
||||
public decimal Price { get; init; }
|
||||
|
||||
public int BrandId { get; init; }
|
||||
|
||||
public string? ImageUrl { get; init; }
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
namespace HelloShop.ProductService.Models.Products;
|
||||
public class ProductDetailsResponse
|
||||
{
|
||||
public int Id { get; init; }
|
||||
|
||||
public required string Name { get; init; }
|
||||
|
||||
public string? Description { get; init; }
|
||||
|
||||
public decimal Price { get; init; }
|
||||
|
||||
public required BrandDetailsResponse Brand { get; init; }
|
||||
|
||||
public string? ImageUrl { get; init; }
|
||||
|
||||
public DateTimeOffset CreationTime { get; init; }
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
namespace HelloShop.ProductService.Models.Products;
|
||||
|
||||
public class ProductListItem
|
||||
{
|
||||
public int Id { get; init; }
|
||||
|
||||
public required string Name { get; init; }
|
||||
|
||||
public decimal Price { get; init; }
|
||||
|
||||
public required string BrandName { get; set; }
|
||||
|
||||
public DateTimeOffset CreationTime { get; init; }
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
namespace HelloShop.ProductService.Models.Products
|
||||
{
|
||||
public class ProductUpdateRequest
|
||||
{
|
||||
public int Id { get; init; }
|
||||
|
||||
public required string Name { get; init; }
|
||||
|
||||
public string? Description { get; init; }
|
||||
|
||||
public decimal Price { get; init; }
|
||||
|
||||
public int BrandId { get; init; }
|
||||
|
||||
public string? ImageUrl { get; init; }
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
using HelloShop.ServiceDefaults.Permissions;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using System.Security;
|
||||
|
||||
namespace HelloShop.ProductService.PermissionProviders;
|
||||
|
||||
public class CatalogPermissionDefinitionProvider(IStringLocalizer<CatalogPermissionDefinitionProvider> localizer) : IPermissionDefinitionProvider
|
||||
{
|
||||
public void Define(PermissionDefinitionContext context)
|
||||
{
|
||||
var identityGroup = context.AddGroup(CatalogPermissions.GroupName, localizer["CatalogManagement"]);
|
||||
|
||||
var productsPermission = identityGroup.AddPermission(CatalogPermissions.Products.Default, localizer["ProductManagement"]);
|
||||
productsPermission.AddChild(CatalogPermissions.Products.Create, localizer["Create"]);
|
||||
productsPermission.AddChild(CatalogPermissions.Products.Details, localizer["Details"]);
|
||||
productsPermission.AddChild(CatalogPermissions.Products.Update, localizer["Edit"]);
|
||||
productsPermission.AddChild(CatalogPermissions.Products.Delete, localizer["Delete"]);
|
||||
|
||||
var brandsPermission = identityGroup.AddPermission(CatalogPermissions.Brands.Default, localizer["BrandManagement"]);
|
||||
brandsPermission.AddChild(CatalogPermissions.Brands.Create, localizer["Create"]);
|
||||
brandsPermission.AddChild(CatalogPermissions.Brands.Details, localizer["Details"]);
|
||||
brandsPermission.AddChild(CatalogPermissions.Brands.Update, localizer["Edit"]);
|
||||
brandsPermission.AddChild(CatalogPermissions.Brands.Delete, localizer["Delete"]);
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
namespace HelloShop.ProductService.PermissionProviders;
|
||||
|
||||
public static class CatalogPermissions
|
||||
{
|
||||
public const string GroupName = "Catalog";
|
||||
|
||||
public static class Products
|
||||
{
|
||||
public const string Default = GroupName + ".Products";
|
||||
public const string Details = Default + ".Details";
|
||||
public const string Create = Default + ".Create";
|
||||
public const string Update = Default + ".Update";
|
||||
public const string Delete = Default + ".Delete";
|
||||
}
|
||||
|
||||
public static class Brands
|
||||
{
|
||||
public const string Default = GroupName + ".Brands";
|
||||
public const string Details = Default + ".Details";
|
||||
public const string Create = Default + ".Create";
|
||||
public const string Update = Default + ".Update";
|
||||
public const string Delete = Default + ".Delete";
|
||||
}
|
||||
}
|
@ -1,3 +1,8 @@
|
||||
using HelloShop.ProductService.Constants;
|
||||
using HelloShop.ProductService.EntityFrameworks;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using HelloShop.ServiceDefaults.Extensions;
|
||||
|
||||
var builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.AddServiceDefaults();
|
||||
@ -5,25 +10,39 @@ builder.AddServiceDefaults();
|
||||
// Add services to the container.
|
||||
|
||||
builder.Services.AddControllers();
|
||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
||||
builder.Services.AddEndpointsApiExplorer();
|
||||
builder.Services.AddSwaggerGen();
|
||||
|
||||
// Add extensions services to the container.
|
||||
builder.Services.AddDbContext<ProductServiceDbContext>(options =>
|
||||
{
|
||||
options.UseNpgsql(builder.Configuration.GetConnectionString(DbConstants.ConnectionStringName));
|
||||
});
|
||||
builder.Services.AddHttpClient().AddHttpContextAccessor().AddDistributedMemoryCache();
|
||||
builder.Services.AddDataSeedingProviders();
|
||||
builder.Services.AddCustomLocalization();
|
||||
builder.Services.AddOpenApi();
|
||||
builder.Services.AddModelMapper().AddModelValidator();
|
||||
builder.Services.AddLocalization().AddPermissionDefinitions();
|
||||
builder.Services.AddAuthorization().AddRemotePermissionChecker(options =>
|
||||
{
|
||||
options.ApiEndpoint = "https://localhost:5001";
|
||||
}).AddCustomAuthorization();
|
||||
// End addd extensions services to the container.
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
app.MapDefaultEndpoints();
|
||||
|
||||
// Configure the HTTP request pipeline.
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI();
|
||||
}
|
||||
|
||||
app.UseHttpsRedirection();
|
||||
|
||||
app.UseAuthorization();
|
||||
|
||||
app.MapControllers();
|
||||
|
||||
// Configure extensions request pipeline.
|
||||
app.UseDataSeedingProviders();
|
||||
app.UseCustomLocalization();
|
||||
app.UseOpenApi();
|
||||
app.MapGroup("api/Permissions").MapPermissionDefinitions("Permissions");
|
||||
// End configure extensions request pipeline.
|
||||
|
||||
app.Run();
|
||||
|
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>名称</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Id" xml:space="preserve">
|
||||
<value>Identifier</value>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,126 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="Id" xml:space="preserve">
|
||||
<value>编号</value>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>名称</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="BrandId" xml:space="preserve">
|
||||
<value>Brand</value>
|
||||
</data>
|
||||
<data name="Description" xml:space="preserve">
|
||||
<value>Description</value>
|
||||
</data>
|
||||
<data name="ImageUrl" xml:space="preserve">
|
||||
<value>Image</value>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
<data name="Price" xml:space="preserve">
|
||||
<value>Price</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="BrandId" xml:space="preserve">
|
||||
<value>品牌</value>
|
||||
</data>
|
||||
<data name="Description" xml:space="preserve">
|
||||
<value>描述</value>
|
||||
</data>
|
||||
<data name="ImageUrl" xml:space="preserve">
|
||||
<value>图片</value>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>名称</value>
|
||||
</data>
|
||||
<data name="Price" xml:space="preserve">
|
||||
<value>价格</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="BrandId" xml:space="preserve">
|
||||
<value>Brand</value>
|
||||
</data>
|
||||
<data name="Description" xml:space="preserve">
|
||||
<value>Description</value>
|
||||
</data>
|
||||
<data name="Id" xml:space="preserve">
|
||||
<value>Identifier</value>
|
||||
</data>
|
||||
<data name="ImageUrl" xml:space="preserve">
|
||||
<value>Image</value>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>Name</value>
|
||||
</data>
|
||||
<data name="Price" xml:space="preserve">
|
||||
<value>Price</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,138 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="BrandId" xml:space="preserve">
|
||||
<value>品牌</value>
|
||||
</data>
|
||||
<data name="Description" xml:space="preserve">
|
||||
<value>描述</value>
|
||||
</data>
|
||||
<data name="Id" xml:space="preserve">
|
||||
<value>编号</value>
|
||||
</data>
|
||||
<data name="ImageUrl" xml:space="preserve">
|
||||
<value>图片</value>
|
||||
</data>
|
||||
<data name="Name" xml:space="preserve">
|
||||
<value>名称</value>
|
||||
</data>
|
||||
<data name="Price" xml:space="preserve">
|
||||
<value>价格</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="BrandManagement" xml:space="preserve">
|
||||
<value>Brand Management</value>
|
||||
</data>
|
||||
<data name="CatalogManagement" xml:space="preserve">
|
||||
<value>Catalog Management</value>
|
||||
</data>
|
||||
<data name="Create" xml:space="preserve">
|
||||
<value>Create</value>
|
||||
</data>
|
||||
<data name="Delete" xml:space="preserve">
|
||||
<value>Delete</value>
|
||||
</data>
|
||||
<data name="Details" xml:space="preserve">
|
||||
<value>Details</value>
|
||||
</data>
|
||||
<data name="Edit" xml:space="preserve">
|
||||
<value>Edit</value>
|
||||
</data>
|
||||
<data name="ProductManagement" xml:space="preserve">
|
||||
<value>Product Management</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="BrandManagement" xml:space="preserve">
|
||||
<value>品牌管理</value>
|
||||
</data>
|
||||
<data name="CatalogManagement" xml:space="preserve">
|
||||
<value>商品管理</value>
|
||||
</data>
|
||||
<data name="Create" xml:space="preserve">
|
||||
<value>创建</value>
|
||||
</data>
|
||||
<data name="Delete" xml:space="preserve">
|
||||
<value>删除</value>
|
||||
</data>
|
||||
<data name="Details" xml:space="preserve">
|
||||
<value>详细</value>
|
||||
</data>
|
||||
<data name="Edit" xml:space="preserve">
|
||||
<value>编辑</value>
|
||||
</data>
|
||||
<data name="ProductManagement" xml:space="preserve">
|
||||
<value>产品管理</value>
|
||||
</data>
|
||||
</root>
|
@ -0,0 +1,13 @@
|
||||
using FluentValidation;
|
||||
using HelloShop.ProductService.Models.Products;
|
||||
|
||||
namespace HelloShop.ProductService.Validations.Products
|
||||
{
|
||||
public class BrandCreateRequestValidator : AbstractValidator<BrandCreateRequest>
|
||||
{
|
||||
public BrandCreateRequestValidator()
|
||||
{
|
||||
RuleFor(x => x.Name).NotNull().NotEmpty().Length(8, 32);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
using FluentValidation;
|
||||
using HelloShop.ProductService.Models.Products;
|
||||
|
||||
namespace HelloShop.ProductService.Validations.Products
|
||||
{
|
||||
public class BrandUpdateRequestValidator : AbstractValidator<BrandUpdateRequest>
|
||||
{
|
||||
public BrandUpdateRequestValidator()
|
||||
{
|
||||
RuleFor(x => x.Id).GreaterThan(0);
|
||||
RuleFor(x => x.Name).NotNull().NotEmpty().Length(8, 32);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
using FluentValidation;
|
||||
using HelloShop.ProductService.Models.Products;
|
||||
|
||||
namespace HelloWorld.ProductService.Validations.Products
|
||||
{
|
||||
public class ProductCreateRequestValidator : AbstractValidator<ProductCreateRequest>
|
||||
{
|
||||
public ProductCreateRequestValidator()
|
||||
{
|
||||
RuleFor(x => x.Name).NotNull().NotEmpty().Length(8, 32);
|
||||
RuleFor(x => x.Description).Length(8, 256);
|
||||
RuleFor(x => x.Price).GreaterThan(0);
|
||||
RuleFor(x => x.BrandId).GreaterThan(0);
|
||||
RuleFor(x => x.ImageUrl).Length(8, 256);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
// Copyright (c) HelloShop Corporation. All rights reserved.
|
||||
// See the license file in the project root for more information.
|
||||
|
||||
using FluentValidation;
|
||||
using HelloShop.ProductService.Models.Products;
|
||||
|
||||
namespace HelloWorld.ProductService.Validations.Products
|
||||
{
|
||||
public class ProductUpdateRequestValidator : AbstractValidator<ProductUpdateRequest>
|
||||
{
|
||||
public ProductUpdateRequestValidator()
|
||||
{
|
||||
RuleFor(x => x.Name).NotNull().NotEmpty().Length(8, 32);
|
||||
RuleFor(x => x.Description).Length(8, 256);
|
||||
RuleFor(x => x.Price).GreaterThan(0);
|
||||
RuleFor(x => x.BrandId).GreaterThan(0);
|
||||
RuleFor(x => x.ImageUrl).Length(8, 256);
|
||||
}
|
||||
}
|
||||
}
|
@ -5,5 +5,8 @@
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*"
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionStrings": {
|
||||
"ProductDatabase": "Host=localhost;Port=5432;Database=ProductService;Username=postgres;Password=postgres"
|
||||
}
|
||||
}
|
||||
|
@ -17,9 +17,9 @@ public static class PermissionExtensions
|
||||
|
||||
var permissionDefinitionProviders = assembly.ExportedTypes.Where(t => t.IsAssignableTo(typeof(IPermissionDefinitionProvider)));
|
||||
|
||||
permissionDefinitionProviders.ToList().ForEach(t => services.AddSingleton(typeof(IPermissionDefinitionProvider), t));
|
||||
permissionDefinitionProviders.ToList().ForEach(t => services.AddTransient(typeof(IPermissionDefinitionProvider), t));
|
||||
|
||||
services.AddSingleton<IPermissionDefinitionManager, PermissionDefinitionManager>();
|
||||
services.AddTransient<IPermissionDefinitionManager, PermissionDefinitionManager>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user