Shady nagy/remove newton soft (#436)

* replace NewtonSoft with System.Text.Json

* not use auth for brande and types and use GetFromJsonAsync

* fix

* fix

* Auth HttpGet more simple.

* Put, Delete and Post  more simple.

* Fixed Edit for remove image and keep image and change other fields.
Added description required in Blazor Admin.

* Removed using not used

* Refactor AuthService and introduce HttpService. add validation for price.

* return null in HttpService if not success.

* Limt Price to 1000 mximum

* DI for Blazor Services

* one blazor service.

* fix
This commit is contained in:
Shady Nagy
2020-07-29 16:28:55 +02:00
committed by GitHub
parent 24cf9be6ae
commit b640926a19
24 changed files with 164 additions and 190 deletions

View File

@@ -14,7 +14,6 @@
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0" PrivateAssets="all" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0" PrivateAssets="all" /> <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="3.1.5" /> <PackageReference Include="Microsoft.Extensions.Identity.Core" Version="3.1.5" />
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
<PackageReference Include="System.Net.Http.Json" Version="3.2.0" /> <PackageReference Include="System.Net.Http.Json" Version="3.2.0" />
</ItemGroup> </ItemGroup>

View File

@@ -1,6 +1,4 @@
using System.Threading.Tasks; using Microsoft.AspNetCore.Components;
using BlazorAdmin.Services;
using Microsoft.AspNetCore.Components;
namespace BlazorAdmin.Helpers namespace BlazorAdmin.Helpers
{ {

View File

@@ -1,9 +1,4 @@
using System; namespace BlazorAdmin.JavaScript
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorAdmin.JavaScript
{ {
public static class JSInteropConstants public static class JSInteropConstants
{ {

View File

@@ -1,6 +1,9 @@
@page "/admin" @page "/admin"
@attribute [Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS)] @attribute [Authorize(Roles = BlazorShared.Authorization.Constants.Roles.ADMINISTRATORS)]
@inject AuthService Auth @inject AuthService Auth
@inject BlazorAdmin.Services.CatalogItemServices.ListPaged CatalogItemListPaged
@inject BlazorAdmin.Services.CatalogTypeServices.List TypeList
@inject BlazorAdmin.Services.CatalogBrandServices.List BrandList
@inherits BlazorAdmin.Helpers.BlazorComponent @inherits BlazorAdmin.Helpers.BlazorComponent
@namespace BlazorAdmin.Pages.CatalogItemPage @namespace BlazorAdmin.Pages.CatalogItemPage

View File

@@ -22,9 +22,9 @@ namespace BlazorAdmin.Pages.CatalogItemPage
{ {
if (firstRender) if (firstRender)
{ {
catalogItems = await new BlazorAdmin.Services.CatalogItemServices.ListPaged(Auth).HandleAsync(50); catalogItems = await CatalogItemListPaged.HandleAsync(50);
catalogTypes = await new BlazorAdmin.Services.CatalogTypeServices.List(Auth).HandleAsync(); catalogTypes = await TypeList.HandleAsync();
catalogBrands = await new BlazorAdmin.Services.CatalogBrandServices.List(Auth).HandleAsync(); catalogBrands = await BrandList.HandleAsync();
CallRequestRefresh(); CallRequestRefresh();
} }
@@ -37,9 +37,9 @@ namespace BlazorAdmin.Pages.CatalogItemPage
await DetailsComponent.Open(id); await DetailsComponent.Open(id);
} }
private void CreateClick() private async Task CreateClick()
{ {
CreateComponent.Open(); await CreateComponent.Open();
} }
private async Task EditClick(int id) private async Task EditClick(int id)

View File

@@ -25,6 +25,8 @@ namespace BlazorAdmin
builder.Services.AddSingleton<AuthenticationStateProvider, CustomAuthStateProvider>(); builder.Services.AddSingleton<AuthenticationStateProvider, CustomAuthStateProvider>();
builder.Services.AddSingleton(sp => (CustomAuthStateProvider)sp.GetRequiredService<AuthenticationStateProvider>()); builder.Services.AddSingleton(sp => (CustomAuthStateProvider)sp.GetRequiredService<AuthenticationStateProvider>());
builder.Services.AddBlazorServices();
await builder.Build().RunAsync(); await builder.Build().RunAsync();
} }
} }

View File

@@ -1,12 +1,10 @@
using System.Net.Http; using System.Net.Http;
using System.Net.Http.Headers; using System.Net.Http.Headers;
using System.Net.Http.Json; using System.Net.Http.Json;
using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using BlazorAdmin.JavaScript; using BlazorAdmin.JavaScript;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Microsoft.JSInterop; using Microsoft.JSInterop;
using Newtonsoft.Json;
using BlazorShared.Authorization; using BlazorShared.Authorization;
namespace BlazorAdmin.Services namespace BlazorAdmin.Services
@@ -16,12 +14,10 @@ namespace BlazorAdmin.Services
private readonly HttpClient _httpClient; private readonly HttpClient _httpClient;
private readonly ILocalStorageService _localStorage; private readonly ILocalStorageService _localStorage;
private readonly IJSRuntime _jSRuntime; private readonly IJSRuntime _jSRuntime;
private static bool InDocker { get; set; }
public string ApiUrl => Constants.GetApiUrl(InDocker); public string ApiUrl => Constants.GetApiUrl(InDocker);
public string WebUrl => Constants.GetWebUrl(InDocker); public string WebUrl => Constants.GetWebUrl(InDocker);
private static bool InDocker { get; set; }
public bool IsLoggedIn { get; set; } public bool IsLoggedIn { get; set; }
public string UserName { get; set; } public string UserName { get; set; }
@@ -32,28 +28,9 @@ namespace BlazorAdmin.Services
_jSRuntime = jSRuntime; _jSRuntime = jSRuntime;
} }
public async Task<HttpResponseMessage> HttpGet(string uri) public HttpClient GetHttpClient()
{ {
return await _httpClient.GetAsync($"{ApiUrl}{uri}"); return _httpClient;
}
public async Task<HttpResponseMessage> HttpDelete(string uri, int id)
{
return await _httpClient.DeleteAsync($"{ApiUrl}{uri}/{id}");
}
public async Task<HttpResponseMessage> HttpPost(string uri, object dataToSend)
{
var content = ToJson(dataToSend);
return await _httpClient.PostAsync($"{ApiUrl}{uri}", content);
}
public async Task<HttpResponseMessage> HttpPut(string uri, object dataToSend)
{
var content = ToJson(dataToSend);
return await _httpClient.PutAsync($"{ApiUrl}{uri}", content);
} }
public async Task Logout() public async Task Logout()
@@ -108,11 +85,6 @@ namespace BlazorAdmin.Services
return (await _localStorage.GetItemAsync<string>("inDocker")).ToLower() == "true"; return (await _localStorage.GetItemAsync<string>("inDocker")).ToLower() == "true";
} }
private StringContent ToJson(object obj)
{
return new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json");
}
private async Task LogoutIdentityManager() private async Task LogoutIdentityManager()
{ {
await _httpClient.PostAsync("Identity/Account/Logout", null); await _httpClient.PostAsync("Identity/Account/Logout", null);

View File

@@ -1,45 +1,25 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Newtonsoft.Json;
namespace BlazorAdmin.Services.CatalogBrandServices namespace BlazorAdmin.Services.CatalogBrandServices
{ {
public class List public class List
{ {
private readonly AuthService _authService; private readonly AuthService _authService;
private readonly HttpClient _httpClient;
public List(AuthService authService) public List(AuthService authService, HttpClient httpClient)
{ {
_authService = authService; _authService = authService;
_httpClient = httpClient;
} }
public async Task<List<CatalogBrand>> HandleAsync() public async Task<List<CatalogBrand>> HandleAsync()
{ {
var brands = new List<CatalogBrand>(); return (await _httpClient.GetFromJsonAsync<CatalogBrandResult>($"{_authService.ApiUrl}catalog-brands"))?.CatalogBrands;
if (!_authService.IsLoggedIn)
{
return brands;
}
try
{
var result = await _authService.HttpGet("catalog-brands");
if (result.StatusCode != HttpStatusCode.OK)
{
return brands;
}
brands = JsonConvert.DeserializeObject<CatalogBrandResult>(await result.Content.ReadAsStringAsync()).CatalogBrands;
}
catch (AccessTokenNotAvailableException)
{
return brands;
}
return brands;
} }
public static string GetBrandName(IEnumerable<CatalogBrand> brands, int brandId) public static string GetBrandName(IEnumerable<CatalogBrand> brands, int brandId)

View File

@@ -17,11 +17,12 @@ namespace BlazorAdmin.Services.CatalogItemServices
[Required(ErrorMessage = "The Name field is required")] [Required(ErrorMessage = "The Name field is required")]
public string Name { get; set; } public string Name { get; set; }
[Required(ErrorMessage = "The Description field is required")]
public string Description { get; set; } public string Description { get; set; }
// decimal(18,2) // decimal(18,2)
[RegularExpression(@"^\d+(\.\d{0,2})*$", ErrorMessage = "The field Price must be a positive number with maximum two decimals.")] [RegularExpression(@"^\d+(\.\d{0,2})*$", ErrorMessage = "The field Price must be a positive number with maximum two decimals.")]
[Range(0, 9999999999999999.99)] [Range(0.01, 1000)]
[DataType(DataType.Currency)] [DataType(DataType.Currency)]
public decimal Price { get; set; } public decimal Price { get; set; }

View File

@@ -11,11 +11,12 @@ namespace BlazorAdmin.Services.CatalogItemServices
[Required(ErrorMessage = "The Name field is required")] [Required(ErrorMessage = "The Name field is required")]
public string Name { get; set; } = string.Empty; public string Name { get; set; } = string.Empty;
[Required(ErrorMessage = "The Description field is required")]
public string Description { get; set; } = string.Empty; public string Description { get; set; } = string.Empty;
// decimal(18,2) // decimal(18,2)
[RegularExpression(@"^\d+(\.\d{0,2})*$", ErrorMessage = "The field Price must be a positive number with maximum two decimals.")] [RegularExpression(@"^\d+(\.\d{0,2})*$", ErrorMessage = "The field Price must be a positive number with maximum two decimals.")]
[Range(0, 9999999999999999.99)] [Range(0.01, 1000)]
[DataType(DataType.Currency)] [DataType(DataType.Currency)]
public decimal Price { get; set; } = 0; public decimal Price { get; set; } = 0;

View File

@@ -1,9 +1,4 @@
using System; namespace BlazorAdmin.Services.CatalogItemServices
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorAdmin.Services.CatalogItemServices
{ {
public class CreateCatalogItemResult public class CreateCatalogItemResult
{ {

View File

@@ -1,31 +1,19 @@
using System.Net; using System.Threading.Tasks;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace BlazorAdmin.Services.CatalogItemServices namespace BlazorAdmin.Services.CatalogItemServices
{ {
public class Create public class Create
{ {
private readonly AuthService _authService; private readonly HttpService _httpService;
public Create(AuthService authService) public Create(AuthService authService)
{ {
_authService = authService; _httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl);
} }
public async Task<CatalogItem> HandleAsync(CreateCatalogItemRequest catalogItem) public async Task<CatalogItem> HandleAsync(CreateCatalogItemRequest catalogItem)
{ {
var catalogItemResult = new CatalogItem(); return (await _httpService.HttpPost<CreateCatalogItemResult>("catalog-items", catalogItem)).CatalogItem;
var result = await _authService.HttpPost("catalog-items", catalogItem);
if (result.StatusCode != HttpStatusCode.OK)
{
return catalogItemResult;
}
catalogItemResult = JsonConvert.DeserializeObject<CreateCatalogItemResult>(await result.Content.ReadAsStringAsync()).CatalogItem;
return catalogItemResult;
} }
} }
} }

View File

@@ -1,31 +1,19 @@
using System.Net; using System.Threading.Tasks;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace BlazorAdmin.Services.CatalogItemServices namespace BlazorAdmin.Services.CatalogItemServices
{ {
public class Delete public class Delete
{ {
private readonly AuthService _authService; private readonly HttpService _httpService;
public Delete(AuthService authService) public Delete(AuthService authService)
{ {
_authService = authService; _httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl);
} }
public async Task<string> HandleAsync(int catalogItemId) public async Task<string> HandleAsync(int catalogItemId)
{ {
var catalogItemResult = string.Empty; return (await _httpService.HttpDelete<DeleteCatalogItemResult>("catalog-items", catalogItemId)).Status;
var result = await _authService.HttpDelete("catalog-items", catalogItemId);
if (result.StatusCode != HttpStatusCode.OK)
{
return catalogItemResult;
}
catalogItemResult = JsonConvert.DeserializeObject<DeleteCatalogItemResult>(await result.Content.ReadAsStringAsync()).Status;
return catalogItemResult;
} }
} }
} }

View File

@@ -1,31 +1,19 @@
using System.Net; using System.Threading.Tasks;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace BlazorAdmin.Services.CatalogItemServices namespace BlazorAdmin.Services.CatalogItemServices
{ {
public class Edit public class Edit
{ {
private readonly AuthService _authService; private readonly HttpService _httpService;
public Edit(AuthService authService) public Edit(AuthService authService)
{ {
_authService = authService; _httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl);
} }
public async Task<CatalogItem> HandleAsync(CatalogItem catalogItem) public async Task<CatalogItem> HandleAsync(CatalogItem catalogItem)
{ {
var catalogItemResult = new CatalogItem(); return (await _httpService.HttpPut<EditCatalogItemResult>("catalog-items", catalogItem)).CatalogItem;
var result = await _authService.HttpPut("catalog-items", catalogItem);
if (result.StatusCode != HttpStatusCode.OK)
{
return catalogItemResult;
}
catalogItemResult = JsonConvert.DeserializeObject<EditCatalogItemResult>(await result.Content.ReadAsStringAsync()).CatalogItem;
return catalogItemResult;
} }
} }
} }

View File

@@ -1,31 +1,19 @@
using System.Net; using System.Threading.Tasks;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace BlazorAdmin.Services.CatalogItemServices namespace BlazorAdmin.Services.CatalogItemServices
{ {
public class GetById public class GetById
{ {
private readonly AuthService _authService; private readonly HttpService _httpService;
public GetById(AuthService authService) public GetById(AuthService authService)
{ {
_authService = authService; _httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl);
} }
public async Task<CatalogItem> HandleAsync(int catalogItemId) public async Task<CatalogItem> HandleAsync(int catalogItemId)
{ {
var catalogItemResult = new CatalogItem(); return (await _httpService.HttpGet<EditCatalogItemResult>($"catalog-items/{catalogItemId}")).CatalogItem;
var result = await _authService.HttpGet($"catalog-items/{catalogItemId}");
if (result.StatusCode != HttpStatusCode.OK)
{
return catalogItemResult;
}
catalogItemResult = JsonConvert.DeserializeObject<EditCatalogItemResult>(await result.Content.ReadAsStringAsync()).CatalogItem;
return catalogItemResult;
} }
} }
} }

View File

@@ -1,32 +1,20 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json;
namespace BlazorAdmin.Services.CatalogItemServices namespace BlazorAdmin.Services.CatalogItemServices
{ {
public class ListPaged public class ListPaged
{ {
private readonly AuthService _authService; private readonly HttpService _httpService;
public ListPaged(AuthService authService) public ListPaged(AuthService authService)
{ {
_authService = authService; _httpService = new HttpService(authService.GetHttpClient(), authService.ApiUrl);
} }
public async Task<List<CatalogItem>> HandleAsync(int pageSize) public async Task<List<CatalogItem>> HandleAsync(int pageSize)
{ {
var catalogItems = new List<CatalogItem>(); return (await _httpService.HttpGet<PagedCatalogItemResult>($"catalog-items?PageSize={pageSize}")).CatalogItems;
var result = await _authService.HttpGet($"catalog-items?PageSize={pageSize}");
if (result.StatusCode != HttpStatusCode.OK)
{
return catalogItems;
}
catalogItems = JsonConvert.DeserializeObject<PagedCatalogItemResult>(await result.Content.ReadAsStringAsync()).CatalogItems;
return catalogItems;
} }
} }

View File

@@ -1,46 +1,25 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Net; using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Components.WebAssembly.Authentication;
using Newtonsoft.Json;
namespace BlazorAdmin.Services.CatalogTypeServices namespace BlazorAdmin.Services.CatalogTypeServices
{ {
public class List public class List
{ {
private readonly AuthService _authService; private readonly AuthService _authService;
private readonly HttpClient _httpClient;
public List(AuthService authService) public List(AuthService authService, HttpClient httpClient)
{ {
_authService = authService; _authService = authService;
_httpClient = httpClient;
} }
public async Task<List<CatalogType>> HandleAsync() public async Task<List<CatalogType>> HandleAsync()
{ {
var types = new List<CatalogType>(); return (await _httpClient.GetFromJsonAsync<CatalogTypeResult>($"{_authService.ApiUrl}catalog-types"))?.CatalogTypes;
if (!_authService.IsLoggedIn)
{
return types;
}
try
{
var result = await _authService.HttpGet("catalog-types");
if (result.StatusCode != HttpStatusCode.OK)
{
return types;
}
types = JsonConvert.DeserializeObject<CatalogTypeResult>(await result.Content.ReadAsStringAsync()).CatalogTypes;
}
catch (AccessTokenNotAvailableException)
{
return types;
}
return types;
} }
public static string GetTypeName(IEnumerable<CatalogType> types, int typeId) public static string GetTypeName(IEnumerable<CatalogType> types, int typeId)

View File

@@ -0,0 +1,85 @@
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace BlazorAdmin.Services
{
public class HttpService
{
private readonly HttpClient _httpClient;
private readonly string _apiUrl;
public HttpService(HttpClient httpClient, string apiUrl)
{
_httpClient = httpClient;
_apiUrl = apiUrl;
}
public async Task<T> HttpGet<T>(string uri)
where T : class
{
var result = await _httpClient.GetAsync($"{_apiUrl}{uri}");
if (!result.IsSuccessStatusCode)
{
return null;
}
return await FromHttpResponseMessage<T>(result);
}
public async Task<T> HttpDelete<T>(string uri, int id)
where T : class
{
var result = await _httpClient.DeleteAsync($"{_apiUrl}{uri}/{id}");
if (!result.IsSuccessStatusCode)
{
return null;
}
return await FromHttpResponseMessage<T>(result);
}
public async Task<T> HttpPost<T>(string uri, object dataToSend)
where T : class
{
var content = ToJson(dataToSend);
var result = await _httpClient.PostAsync($"{_apiUrl}{uri}", content);
if (!result.IsSuccessStatusCode)
{
return null;
}
return await FromHttpResponseMessage<T>(result);
}
public async Task<T> HttpPut<T>(string uri, object dataToSend)
where T : class
{
var content = ToJson(dataToSend);
var result = await _httpClient.PutAsync($"{_apiUrl}{uri}", content);
if (!result.IsSuccessStatusCode)
{
return null;
}
return await FromHttpResponseMessage<T>(result);
}
private StringContent ToJson(object obj)
{
return new StringContent(JsonSerializer.Serialize(obj), Encoding.UTF8, "application/json");
}
private async Task<T> FromHttpResponseMessage<T>(HttpResponseMessage result)
{
return JsonSerializer.Deserialize<T>(await result.Content.ReadAsStringAsync(), new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
}
}
}

View File

@@ -0,0 +1,22 @@
using BlazorAdmin.Services.CatalogItemServices;
using Microsoft.Extensions.DependencyInjection;
namespace BlazorAdmin
{
public static class ServicesConfiguration
{
public static IServiceCollection AddBlazorServices(this IServiceCollection service)
{
service.AddScoped<Create>();
service.AddScoped<ListPaged>();
service.AddScoped<Delete>();
service.AddScoped<Edit>();
service.AddScoped<GetById>();
service.AddScoped<BlazorAdmin.Services.CatalogBrandServices.List>();
service.AddScoped<BlazorAdmin.Services.CatalogTypeServices.List>();
return service;
}
}
}

View File

@@ -12,7 +12,6 @@
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.5" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.5" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.5" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.5" PrivateAssets="All" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.5" PrivateAssets="All" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.7.0" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.7.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -2,10 +2,10 @@
using System.IO; using System.IO;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Text.Json;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.eShopWeb.ApplicationCore.Interfaces; using Microsoft.eShopWeb.ApplicationCore.Interfaces;
using Microsoft.eShopWeb.Infrastructure.Data; using Microsoft.eShopWeb.Infrastructure.Data;
using Newtonsoft.Json;
namespace Microsoft.eShopWeb.Infrastructure.Services namespace Microsoft.eShopWeb.Infrastructure.Services
{ {
@@ -49,7 +49,7 @@ namespace Microsoft.eShopWeb.Infrastructure.Services
DataBase64 = Convert.ToBase64String(fileData), DataBase64 = Convert.ToBase64String(fileData),
FileName = fileName FileName = fileName
}; };
var content = new StringContent(JsonConvert.SerializeObject(request), Encoding.UTF8, "application/json"); var content = new StringContent(JsonSerializer.Serialize(request), Encoding.UTF8, "application/json");
using var message = await _httpClient.PostAsync(_url, content); using var message = await _httpClient.PostAsync(_url, content);
if (!message.IsSuccessStatusCode) if (!message.IsSuccessStatusCode)

View File

@@ -15,6 +15,7 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints
[Required] [Required]
public string Name { get; set; } public string Name { get; set; }
public string PictureBase64 { get; set; } public string PictureBase64 { get; set; }
public string PictureUri { get; set; }
public string PictureName { get; set; } public string PictureName { get; set; }
[Range(0.01, 10000)] [Range(0.01, 10000)]
public decimal Price { get; set; } public decimal Price { get; set; }

View File

@@ -42,7 +42,7 @@ namespace Microsoft.eShopWeb.PublicApi.CatalogItemEndpoints
existingItem.UpdateBrand(request.CatalogBrandId); existingItem.UpdateBrand(request.CatalogBrandId);
existingItem.UpdateType(request.CatalogTypeId); existingItem.UpdateType(request.CatalogTypeId);
if (string.IsNullOrEmpty(request.PictureBase64)) if (string.IsNullOrEmpty(request.PictureBase64) && string.IsNullOrEmpty(request.PictureUri))
{ {
existingItem.UpdatePictureUri(string.Empty); existingItem.UpdatePictureUri(string.Empty);
} }

View File

@@ -19,6 +19,7 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http; using System.Net.Http;
using System.Net.Mime; using System.Net.Mime;
using BlazorAdmin;
using BlazorAdmin.Services; using BlazorAdmin.Services;
using Blazored.LocalStorage; using Blazored.LocalStorage;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
@@ -149,6 +150,7 @@ namespace Microsoft.eShopWeb.Web
services.AddBlazoredLocalStorage(); services.AddBlazoredLocalStorage();
services.AddServerSideBlazor(); services.AddServerSideBlazor();
services.AddScoped<AuthService>(); services.AddScoped<AuthService>();
services.AddBlazorServices();
_services = services; // used to debug registered services _services = services; // used to debug registered services
} }