refactor: 消除 Admin 工程警告信息

This commit is contained in:
Argo-Cloud 2020-11-18 14:49:09 +08:00
parent cebb4e7beb
commit 986c6c7ab4
32 changed files with 109 additions and 107 deletions

View File

@ -38,7 +38,7 @@ namespace Bootstrap.Admin.Controllers
[HttpGet]
public async Task<ActionResult> Lock()
{
if (!User.Identity.IsAuthenticated) return Login();
if (!User.Identity!.IsAuthenticated) return Login();
var authenticationType = User.Identity.AuthenticationType;
await HttpContext.SignOutAsync();
@ -61,7 +61,7 @@ namespace Bootstrap.Admin.Controllers
/// <returns></returns>
[HttpPost]
[IgnoreAntiforgeryToken]
public Task<IActionResult> Lock([FromServices]ISMSProvider provider, string userName, string password, string authType)
public Task<IActionResult> Lock([FromServices] ISMSProvider provider, string userName, string password, string authType)
{
// 根据不同的登陆方式
Task<IActionResult> ret;
@ -77,14 +77,14 @@ namespace Bootstrap.Admin.Controllers
/// <param name="view"></param>
/// <returns></returns>
[HttpGet]
public ActionResult Login([FromQuery]string? appId = null, [FromQuery]string view = "")
public ActionResult Login([FromQuery] string? appId = null, [FromQuery] string view = "")
{
if (DictHelper.RetrieveSystemModel())
{
ViewBag.UserName = "Admin";
ViewBag.Password = "123789";
}
return User.Identity.IsAuthenticated ? (ActionResult)Redirect("~/Home/Index") : LoginView(view, new LoginModel(appId));
return User.Identity!.IsAuthenticated ? (ActionResult)Redirect("~/Home/Index") : LoginView(view, new LoginModel(appId));
}
private ViewResult LoginView(string view, LoginModel model)
@ -105,7 +105,7 @@ namespace Bootstrap.Admin.Controllers
/// <param name="code"></param>
/// <returns></returns>
[HttpPost()]
public async Task<IActionResult> Mobile([FromServices]ISMSProvider provider, string phone, string code)
public async Task<IActionResult> Mobile([FromServices] ISMSProvider provider, string phone, string code)
{
if (string.IsNullOrEmpty(phone) || string.IsNullOrEmpty(code)) return RedirectLogin();
@ -130,10 +130,8 @@ namespace Bootstrap.Admin.Controllers
if (UserHelper.Save(user) && !string.IsNullOrEmpty(user.Id))
{
// 根据配置文件设置默认角色
var roles = RoleHelper.Retrieves().Where(r => provider.Options.Roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id);
#nullable disable
var roles = RoleHelper.Retrieves().Where(r => provider.Options.Roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id!);
RoleHelper.SaveByUserId(user.Id, roles);
#nullable restore
}
}
}
@ -142,7 +140,7 @@ namespace Bootstrap.Admin.Controllers
private IActionResult RedirectLogin()
{
var query = Request.Query.Aggregate(new Dictionary<string, string>(), (d, v) =>
var query = Request.Query.Aggregate(new Dictionary<string, string?>(), (d, v) =>
{
d.Add(v.Key, v.Value.ToString());
return d;
@ -184,7 +182,7 @@ namespace Bootstrap.Admin.Controllers
/// <param name="appId"></param>
/// <returns>The logout.</returns>
[HttpGet]
public async Task<IActionResult> Logout([FromQuery]string appId)
public async Task<IActionResult> Logout([FromQuery] string appId)
{
await HttpContext.SignOutAsync();
return Redirect(QueryHelpers.AddQueryString(Request.PathBase + CookieAuthenticationDefaults.LoginPath, "AppId", appId ?? BootstrapAppContext.AppId));
@ -203,7 +201,7 @@ namespace Bootstrap.Admin.Controllers
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Gitee([FromServices]IConfiguration config)
public IActionResult Gitee([FromServices] IConfiguration config)
{
var enabled = config.GetValue($"{nameof(GiteeOptions)}:Enabled", false);
return Challenge(enabled ? GiteeDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
@ -214,7 +212,7 @@ namespace Bootstrap.Admin.Controllers
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult GitHub([FromServices]IConfiguration config)
public IActionResult GitHub([FromServices] IConfiguration config)
{
var enabled = config.GetValue($"{nameof(GitHubOptions)}:Enabled", false);
return Challenge(enabled ? GitHubDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
@ -225,7 +223,7 @@ namespace Bootstrap.Admin.Controllers
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Tencent([FromServices]IConfiguration config)
public IActionResult Tencent([FromServices] IConfiguration config)
{
var enabled = config.GetValue($"{nameof(TencentOptions)}:Enabled", false);
return Challenge(enabled ? TencentDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
@ -236,7 +234,7 @@ namespace Bootstrap.Admin.Controllers
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult Alipay([FromServices]IConfiguration config)
public IActionResult Alipay([FromServices] IConfiguration config)
{
var enabled = config.GetValue($"{nameof(AlipayOptions)}:Enabled", false);
return Challenge(enabled ? AlipayDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
@ -247,7 +245,7 @@ namespace Bootstrap.Admin.Controllers
/// </summary>
/// <returns></returns>
[HttpGet]
public IActionResult WeChat([FromServices]IConfiguration config)
public IActionResult WeChat([FromServices] IConfiguration config)
{
var enabled = config.GetValue($"{nameof(WeChatOptions)}:Enabled", false);
return Challenge(enabled ? WeChatDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);

View File

@ -32,7 +32,7 @@ namespace Bootstrap.Admin.Controllers.Api
[HttpGet]
public IEnumerable<string> RetrieveMenus()
{
return MenuHelper.RetrieveAllMenus(User.Identity.Name).OrderBy(m => m.Name).Select(m => m.Name);
return MenuHelper.RetrieveAllMenus(User.Identity!.Name).OrderBy(m => m.Name).Select(m => m.Name);
}
/// <summary>
@ -42,7 +42,7 @@ namespace Bootstrap.Admin.Controllers.Api
[HttpGet]
public IEnumerable<string> RetrieveParentMenus()
{
return MenuHelper.RetrieveMenus(User.Identity.Name).Where(m => m.Menus.Count() > 0).OrderBy(m => m.Name).Select(m => m.Name);
return MenuHelper.RetrieveMenus(User.Identity!.Name).Where(m => m.Menus.Count() > 0).OrderBy(m => m.Name).Select(m => m.Name);
}
/// <summary>
@ -52,7 +52,7 @@ namespace Bootstrap.Admin.Controllers.Api
[HttpGet("{id}")]
public bool ValidateMenuBySubMenu(string id)
{
return !MenuHelper.RetrieveAllMenus(User.Identity.Name).Where(m => m.ParentId == id).Any();
return !MenuHelper.RetrieveAllMenus(User.Identity!.Name).Where(m => m.ParentId == id).Any();
}
/// <summary>
@ -62,7 +62,7 @@ namespace Bootstrap.Admin.Controllers.Api
[HttpGet("{id}")]
public bool ValidateParentMenuById(string id)
{
return MenuHelper.RetrieveAllMenus(User.Identity.Name).FirstOrDefault(m => m.Id == id)?.IsResource == 0;
return MenuHelper.RetrieveAllMenus(User.Identity!.Name).FirstOrDefault(m => m.Id == id)?.IsResource == 0;
}
}
}

View File

@ -38,11 +38,11 @@ namespace Bootstrap.Admin.Controllers.Api
{
value.UserAgent = Request.Headers["User-Agent"];
var agent = new UserAgent(value.UserAgent);
value.Ip = HttpContext.Connection.RemoteIpAddress.ToIPv4String();
value.Ip = HttpContext.Connection.RemoteIpAddress?.ToIPv4String() ?? "";
value.Browser = $"{agent.Browser?.Name} {agent.Browser?.Version}";
value.OS = $"{agent.OS?.Name} {agent.OS?.Version}";
value.City = ipLocator.Locate(value.Ip);
value.UserName = User.Identity.Name ?? string.Empty;
value.UserName = User.Identity?.Name ?? string.Empty;
return LogHelper.Save(value);
}
}

View File

@ -25,7 +25,7 @@ namespace Bootstrap.Admin.Controllers.Api
[HttpGet]
public QueryData<object> Get([FromQuery]QueryMenuOption value)
{
return value.RetrieveData(User.Identity.Name);
return value.RetrieveData(User.Identity!.Name);
}
/// <summary>
@ -66,7 +66,7 @@ namespace Bootstrap.Admin.Controllers.Api
ret = MenuHelper.RetrieveMenusByRoleId(id);
break;
case "user":
ret = MenuHelper.RetrieveMenus(User.Identity.Name);
ret = MenuHelper.RetrieveMenus(User.Identity!.Name);
break;
}
return ret;

View File

@ -28,16 +28,16 @@ namespace Bootstrap.Admin.Controllers.Api
switch (id)
{
case "inbox":
ret = MessageHelper.Inbox(User.Identity.Name).ToList();
ret = MessageHelper.Inbox(User.Identity!.Name).ToList();
break;
case "sendmail":
ret = MessageHelper.SendMail(User.Identity.Name).ToList();
ret = MessageHelper.SendMail(User.Identity!.Name).ToList();
break;
case "mark":
ret = MessageHelper.Mark(User.Identity.Name).ToList();
ret = MessageHelper.Mark(User.Identity!.Name).ToList();
break;
case "trash":
ret = MessageHelper.Trash(User.Identity.Name).ToList();
ret = MessageHelper.Trash(User.Identity!.Name).ToList();
break;
}
return ret;
@ -52,12 +52,12 @@ namespace Bootstrap.Admin.Controllers.Api
{
var mcm = new MessageCountModel
{
InboxCount = MessageHelper.Inbox(User.Identity.Name).Count(),
SendmailCount = MessageHelper.SendMail(User.Identity.Name).Count(),
MarkCount = MessageHelper.Mark(User.Identity.Name).Count(),
TrashCount = MessageHelper.Trash(User.Identity.Name).Count()
InboxCount = MessageHelper.Inbox(User.Identity!.Name).Count(),
SendmailCount = MessageHelper.SendMail(User.Identity!.Name).Count(),
MarkCount = MessageHelper.Mark(User.Identity!.Name).Count(),
TrashCount = MessageHelper.Trash(User.Identity!.Name).Count()
};
return mcm;
}
}
}
}

View File

@ -38,7 +38,7 @@ namespace Bootstrap.Admin.Controllers
public bool Put([FromBody]User value)
{
var ret = false;
var userName = User.Identity.Name;
var userName = User.Identity!.Name;
if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(value.Id))
{
if (value.UserStatus == UserStates.ApproveUser)

View File

@ -43,11 +43,11 @@ namespace Bootstrap.Admin.Controllers.Api
var tasksCount = task.Count();
//Message
var message = MessageHelper.Retrieves(User.Identity.Name);
var message = MessageHelper.Retrieves(User.Identity!.Name);
var messagesCount = message.Count();
message = message.Take(6);
message.AsParallel().ForAll(m => m.FromIcon = Url.Content(m.FromIcon));
message.AsParallel().ForAll(m => m.FromIcon = Url.Content(m.FromIcon) ?? string.Empty);
//Apps
var apps = ExceptionsHelper.Retrieves().Where(n => n.Category != "DB");

View File

@ -23,7 +23,7 @@ namespace Bootstrap.Admin.Controllers.Api
/// </summary>
/// <returns></returns>
[HttpGet()]
public IEnumerable<OnlineUser> Get([FromServices]IOnlineUsers onlineUSers)
public IEnumerable<OnlineUser> Get([FromServices] IOnlineUsers onlineUSers)
{
return onlineUSers.OnlineUsers.OrderByDescending(u => u.LastAccessTime);
}
@ -35,7 +35,7 @@ namespace Bootstrap.Admin.Controllers.Api
/// <param name="onlineUSers"></param>
/// <returns></returns>
[HttpGet("{id}")]
public IEnumerable<KeyValuePair<DateTime, string>> Get(string id, [FromServices]IOnlineUsers onlineUSers)
public IEnumerable<KeyValuePair<DateTime, string>> Get(string id, [FromServices] IOnlineUsers onlineUSers)
{
var user = onlineUSers.OnlineUsers.FirstOrDefault(u => u.ConnectionId == id);
return user?.RequestUrls ?? new KeyValuePair<DateTime, string>[0];
@ -49,7 +49,7 @@ namespace Bootstrap.Admin.Controllers.Api
[AllowAnonymous]
public bool Put()
{
var ip = Request.HttpContext.Connection.RemoteIpAddress.ToIPv4String();
var ip = Request.HttpContext.Connection.RemoteIpAddress?.ToIPv4String() ?? "";
if (_loginUsers.TryGetValue(ip, out var user))
{
user.Reset();

View File

@ -27,10 +27,10 @@ namespace Bootstrap.Admin.Controllers.Api
/// <returns></returns>
[HttpPost("{id}")]
[ButtonAuthorize(Url = "~/Admin/Profiles", Auth = "saveIcon")]
public JsonResult Post(string id, [FromServices]IWebHostEnvironment env, [FromForm]DeleteFileCollection files)
public JsonResult Post(string id, [FromServices] IWebHostEnvironment env, [FromForm] DeleteFileCollection files)
{
if (!id.Equals("Delete", StringComparison.OrdinalIgnoreCase)) return new JsonResult(new object());
var userName = User.Identity.Name;
var userName = User.Identity!.Name;
var fileName = files.Key;
fileName = Path.Combine(env.WebRootPath, $"images{Path.DirectorySeparatorChar}uploader{Path.DirectorySeparatorChar}{fileName}");
@ -40,7 +40,7 @@ namespace Bootstrap.Admin.Controllers.Api
var filePath = Path.Combine(env.WebRootPath, webSiteUrl.Replace("~", string.Empty).Replace('/', Path.DirectorySeparatorChar).TrimStart(Path.DirectorySeparatorChar) + fileName);
var fileSize = new FileInfo(filePath).Length;
var iconName = $"{fileName}?v={DateTime.Now.Ticks}";
var previewUrl = Url.Content($"{webSiteUrl}{iconName}");
var previewUrl = Url.Content($"{webSiteUrl}{iconName}") ?? string.Empty;
if (!string.IsNullOrEmpty(userName)) UserHelper.SaveUserIconByName(userName, iconName);
return new JsonResult(new
@ -72,11 +72,11 @@ namespace Bootstrap.Admin.Controllers.Api
/// <returns></returns>
[HttpPost]
[ButtonAuthorize(Url = "~/Admin/Profiles", Auth = "saveIcon")]
public async Task<JsonResult> Post([FromServices]IWebHostEnvironment env, IFormCollection files)
public async Task<JsonResult> Post([FromServices] IWebHostEnvironment env, IFormCollection files)
{
var previewUrl = string.Empty;
string? previewUrl = null;
long fileSize = 0;
var userName = User.Identity.Name;
var userName = User.Identity!.Name;
var fileName = string.Empty;
if (files.Files.Count > 0)
{
@ -95,7 +95,7 @@ namespace Bootstrap.Admin.Controllers.Api
}
return new JsonResult(new
{
initialPreview = new string[] { previewUrl },
initialPreview = new string[] { previewUrl ?? string.Empty },
initialPreviewConfig = new object[] {
new { caption = "新头像", size = fileSize, showZoom = true, key = fileName }
},
@ -109,10 +109,10 @@ namespace Bootstrap.Admin.Controllers.Api
/// <returns></returns>
[HttpPut]
[ButtonAuthorize(Url = "~/Admin/Profiles", Auth = "saveDisplayName,savePassword,saveApp,saveTheme")]
public bool Put([FromBody]User value)
public bool Put([FromBody] User value)
{
var ret = false;
if (value.UserName.Equals(User.Identity.Name, StringComparison.OrdinalIgnoreCase))
if (value.UserName.Equals(User.Identity!.Name, StringComparison.OrdinalIgnoreCase))
{
ret = value.UserStatus switch
{

View File

@ -24,7 +24,7 @@ namespace Bootstrap.Admin.Controllers.Api
[HttpGet]
public IEnumerable<object> Get()
{
return TaskServicesManager.ToList().Select(s => new { s.Name, Status = s.Status.ToString(), s.LastRuntime, s.CreatedTime, s.NextRuntime, LastRunResult = s.Triggers.First().LastResult.ToString(), TriggerExpression = s.Triggers.FirstOrDefault().ToString() }).OrderBy(s => s.Name);
return TaskServicesManager.ToList().Select(s => new { s.Name, Status = s.Status.ToString(), s.LastRuntime, s.CreatedTime, s.NextRuntime, LastRunResult = s.Triggers.First().LastResult.ToString(), TriggerExpression = s.Triggers.First().ToString() }).OrderBy(s => s.Name);
}
/// <summary>

View File

@ -61,7 +61,7 @@ namespace Bootstrap.Admin.Controllers.Api
bool ret;
if (string.IsNullOrEmpty(value.Id))
{
value.Description = string.Format("管理员{0}创建用户", User.Identity.Name);
value.Description = string.Format("管理员{0}创建用户", User.Identity!.Name);
value.ApprovedBy = User.Identity.Name;
value.ApprovedTime = DateTime.Now;
ret = UserHelper.Save(value);

View File

@ -19,7 +19,7 @@ namespace Bootstrap.Admin.Controllers
/// <returns></returns>
public IActionResult Index([FromServices]IConfiguration configuration)
{
var model = new HeaderBarModel(User.Identity.Name);
var model = new HeaderBarModel(User.Identity!.Name);
var homeUrl = DictHelper.RetrieveHomeUrl(User.Identity.Name, model.AppId);
var useBlazor = DictHelper.RetrieveEnableBlazor();
return homeUrl.Equals("~/Home/Index", System.StringComparison.OrdinalIgnoreCase) ? (useBlazor ? Redirect("~/Pages") : (IActionResult)View(model)) : Redirect(homeUrl);

View File

@ -58,7 +58,7 @@ namespace Bootstrap.Admin.HealthChecks
};
// 检查 当前用户 账户权限
var loginUser = _httpContextAccessor.HttpContext?.User.Identity.Name;
var loginUser = _httpContextAccessor.HttpContext?.User.Identity?.Name;
var userName = loginUser ?? "Admin";
var dictsCount = 0;
var menusCount = 0;
@ -88,11 +88,11 @@ namespace Bootstrap.Admin.HealthChecks
{
error = ex;
}
var data = new Dictionary<string, object?>()
var data = new Dictionary<string, object>()
{
{ "ConnectionString", db.ConnectionString },
{ "Reference", DbContextManager.Create<Dict>()?.GetType().Assembly.FullName ?? db.Widget },
{ "DbType", db?.ProviderName },
{ "ConnectionString", db.ConnectionString ?? string.Empty },
{ "Reference", DbContextManager.Create<Dict>()?.GetType().Assembly.FullName ?? db.Widget ?? string.Empty },
{ "DbType", db?.ProviderName ?? string.Empty },
{ "Dicts", dictsCount },
{ "LoginName", userName },
{ "DisplayName", displayName },

View File

@ -24,7 +24,7 @@ namespace Bootstrap.Admin.HealthChecks
public GiteeHttpHealthCheck(GiteeHttpClient client, IHttpContextAccessor accessor)
{
_client = client;
_client.HttpClient.BaseAddress = new Uri($"{accessor.HttpContext.Request.Scheme}://{accessor.HttpContext.Request.Host}{accessor.HttpContext.Request.PathBase}");
_client.HttpClient.BaseAddress = new Uri($"{accessor.HttpContext!.Request.Scheme}://{accessor.HttpContext?.Request.Host}{accessor.HttpContext?.Request.PathBase}");
}
/// <summary>

View File

@ -16,7 +16,7 @@ namespace Bootstrap.Admin.Models
/// 构造函数
/// </summary>
/// <param name="controller"></param>
public NavigatorBarModel(ControllerBase controller) : this(controller.User.Identity.Name, $"~{controller.Request.Path}")
public NavigatorBarModel(ControllerBase controller) : this(controller.User.Identity!.Name, $"~{controller.Request.Path}")
{
}

View File

@ -45,14 +45,14 @@ namespace Bootstrap.Admin.Models
// 数据库存储的个人图片有后缀 default.jpg?v=1234567
fileName = fileName.Split('?').FirstOrDefault();
if (File.Exists(fileName))
if (!string.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
Size = new FileInfo(fileName).Length;
FileName = Path.GetFileName(fileName);
}
}
if (controller.User.Identity.AuthenticationType != CookieAuthenticationDefaults.AuthenticationScheme) External = true;
if (controller.User.Identity!.AuthenticationType != CookieAuthenticationDefaults.AuthenticationScheme) External = true;
// 设置 当前用户默认应用名称
AppName = Applications.FirstOrDefault(app => app.Key == AppId).Value;

View File

@ -3,6 +3,7 @@ using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
@ -53,13 +54,13 @@ namespace Bootstrap.Admin.Pages.Components
{
if (!validationResult.MemberNames.Any())
{
messages.Add(new FieldIdentifier(editContext.Model, fieldName: string.Empty), validationResult.ErrorMessage);
messages.Add(new FieldIdentifier(editContext.Model, fieldName: string.Empty), validationResult.ErrorMessage!);
continue;
}
foreach (var memberName in validationResult.MemberNames)
{
messages.Add(editContext.Field(memberName), validationResult.ErrorMessage);
messages.Add(editContext.Field(memberName), validationResult.ErrorMessage!);
}
}
editContext.NotifyValidationStateChanged();
@ -81,14 +82,13 @@ namespace Bootstrap.Admin.Pages.Components
editForm.ValidateProperty(propertyValue, validationContext, results);
messages.Clear(fieldIdentifier);
messages.Add(fieldIdentifier, results.Select(result => result.ErrorMessage));
messages.Add(fieldIdentifier, results.Select(result => result.ErrorMessage!));
editContext.NotifyValidationStateChanged();
}
}
#nullable disable
internal static bool TryGetValidatableProperty(in FieldIdentifier fieldIdentifier, out PropertyInfo propertyInfo)
internal static bool TryGetValidatableProperty(in FieldIdentifier fieldIdentifier, [MaybeNullWhen(false)] out PropertyInfo propertyInfo)
{
var cacheKey = (ModelType: fieldIdentifier.Model.GetType(), fieldIdentifier.FieldName);
if (!_propertyInfoCache.TryGetValue(cacheKey, out propertyInfo))
@ -96,11 +96,10 @@ namespace Bootstrap.Admin.Pages.Components
// Validator.TryValidateProperty 只能对 Public 属性生效
propertyInfo = cacheKey.ModelType.GetProperty(cacheKey.FieldName);
_propertyInfoCache[cacheKey] = propertyInfo;
if (propertyInfo != null) _propertyInfoCache[cacheKey] = propertyInfo;
}
return propertyInfo != null;
}
#nullable restore
}
}

View File

@ -105,7 +105,7 @@ namespace Bootstrap.Admin.Pages.Components
}
var state = await AuthenticationStateProvider.GetAuthenticationStateAsync();
if (!state.User.Identity.IsAuthenticated)
if (!state.User.Identity!.IsAuthenticated)
{
NavigationManager?.NavigateTo("/Account/Login?returnUrl=" + WebUtility.UrlEncode(new Uri(NavigationManager.Uri).PathAndQuery));
}

View File

@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace Bootstrap.Admin.Pages.Components
{
@ -39,7 +40,7 @@ namespace Bootstrap.Admin.Pages.Components
{
var val = propertyValue?.ToString() ?? "";
if (val != Value)
results.Add(new ValidationResult(ErrorMessage, new string[] { context.MemberName }));
results.Add(new ValidationResult(ErrorMessage, string.IsNullOrEmpty(context.MemberName) ? Enumerable.Empty<string>() : new string[] { context.MemberName }));
}
}
}

View File

@ -106,7 +106,7 @@ namespace Bootstrap.Admin.Pages.Components
/// <param name="results"></param>
public void ValidateProperty(object? propertyValue, ValidationContext context, List<ValidationResult> results)
{
if (_validatorCache.TryGetValue((this, context.ObjectType, context.MemberName), out var validator))
if (_validatorCache.TryGetValue((this, context.ObjectType, context.MemberName ?? string.Empty), out var validator))
{
validator.ValidateProperty(propertyValue, context, results);
validator.ToggleMessage(results, true);

View File

@ -2,6 +2,7 @@
using Microsoft.AspNetCore.Components.Forms;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq.Expressions;
namespace Bootstrap.Admin.Pages.Components
@ -32,7 +33,9 @@ namespace Bootstrap.Admin.Pages.Components
/// <summary>
/// 获得/设置 ValueExpression 表达式
/// </summary>
[Parameter] public Expression<Func<TItem>>? ValueExpression { get; set; }
[Parameter]
[NotNull]
public Expression<Func<TItem>>? ValueExpression { get; set; }
/// <summary>
/// 获得/设置 是否排序 默认 false

View File

@ -1,6 +1,7 @@
using System.Collections.Generic;
using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Components;
using System.Linq;
namespace Bootstrap.Admin.Pages.Components
{
@ -34,7 +35,7 @@ namespace Bootstrap.Admin.Pages.Components
var val = propertyValue?.ToString() ?? "";
if (!AllowEmptyString && val == string.Empty)
{
results.Add(new ValidationResult(ErrorMessage, new string[] { context.MemberName }));
results.Add(new ValidationResult(ErrorMessage, string.IsNullOrEmpty(context.MemberName) ? Enumerable.Empty<string>() : new string[] { context.MemberName }));
}
}
}

View File

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Microsoft.AspNetCore.Components;
namespace Bootstrap.Admin.Pages.Components
@ -33,7 +34,7 @@ namespace Bootstrap.Admin.Pages.Components
public override void Validate(object? propertyValue, ValidationContext context, List<ValidationResult> results)
{
var val = propertyValue?.ToString() ?? "";
if (val.Length > Length) results.Add(new ValidationResult(ErrorMessage, new string[] { context.MemberName }));
if (val.Length > Length) results.Add(new ValidationResult(ErrorMessage, string.IsNullOrEmpty(context.MemberName) ? Enumerable.Empty<string>() : new string[] { context.MemberName }));
}
}
}

View File

@ -120,11 +120,14 @@ namespace Bootstrap.Admin.Pages.Components
tabId = await JSRuntime.RemoveTabAsync(tab.Id);
Tabs.Remove(tab);
tab = Tabs.FirstOrDefault(t => t.Id == tabId);
tab.SetActive(true);
if (tab != null)
{
tab.SetActive(true);
page = Pages.FirstOrDefault(p => p.Id == tabId);
if (page != null) page.Active = true;
StateHasChanged();
page = Pages.FirstOrDefault(p => p.Id == tabId);
if (page != null) page.Active = true;
StateHasChanged();
}
}
}
}

View File

@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Components.Forms;
using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
namespace Bootstrap.Admin.Pages.Components
@ -18,6 +19,7 @@ namespace Bootstrap.Admin.Pages.Components
/// 获得 IJSRuntime 实例
/// </summary>
[Inject]
[NotNull]
protected IJSRuntime? JSRuntime { get; set; }
/// <summary>
@ -278,12 +280,12 @@ namespace Bootstrap.Admin.Pages.Components
}
/// <summary>
/// OnAfterRenderAsync 方法
/// OnAfterRender 方法
/// </summary>
protected override async System.Threading.Tasks.Task OnAfterRenderAsync(bool firstRender)
protected override void OnAfterRender(bool firstRender)
{
// 调用客户端脚本
await JSRuntime.InitTableAsync(RetrieveId(), firstRender);
JSRuntime.InitTableAsync(RetrieveId(), firstRender);
}
/// <summary>

View File

@ -4,6 +4,7 @@ using Microsoft.JSInterop;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
@ -67,11 +68,6 @@ namespace Bootstrap.Admin.Pages.Components
/// </summary>
protected string ValidCss { get; set; } = "";
/// <summary>
/// 获得/设置 显示名称 默认为 -
/// </summary>
protected string DisplayName { get; set; } = "-";
/// <summary>
/// OnInitialized 方法
/// </summary>
@ -123,7 +119,7 @@ namespace Bootstrap.Admin.Pages.Components
var messages = results.Where(item => item.MemberNames.Any(m => m == FieldIdentifier.FieldName));
if (messages.Any())
{
ErrorMessage = messages.First().ErrorMessage;
ErrorMessage = messages.First().ErrorMessage ?? string.Empty;
ValidCss = "is-invalid";
// 控件自身数据验证时显示 tooltip
@ -147,9 +143,9 @@ namespace Bootstrap.Admin.Pages.Components
/// <param name="result"></param>
/// <param name="validationErrorMessage"></param>
/// <returns></returns>
protected override bool TryParseValueFromString(string value, out TItem result, out string? validationErrorMessage)
protected override bool TryParseValueFromString(string? value, [MaybeNullWhen(false)] out TItem result, [NotNullWhen(false)] out string? validationErrorMessage)
{
if (typeof(TItem) == typeof(string))
if (!string.IsNullOrEmpty(value) && typeof(TItem) == typeof(string))
{
result = (TItem)(object)value;
validationErrorMessage = null;
@ -160,22 +156,20 @@ namespace Bootstrap.Admin.Pages.Components
var success = BindConverter.TryConvertTo<TItem>(value, CultureInfo.CurrentCulture, out var parsedValue);
if (success)
{
result = parsedValue;
result = parsedValue!;
validationErrorMessage = null;
return true;
}
else
{
#nullable disable
result = default;
#nullable restore
validationErrorMessage = $"The {FieldIdentifier.FieldName} field is not valid.";
return false;
}
}
else if (typeof(TItem).IsValueType)
{
result = (TItem)Convert.ChangeType(value, typeof(TItem));
result = (TItem)Convert.ChangeType(value, typeof(TItem))!;
validationErrorMessage = null;
return true;
}

View File

@ -1,4 +1,4 @@
using Bootstrap.DataAccess;
using Bootstrap.DataAccess;
using Longbow.Cache;
using Longbow.Web;
using Microsoft.Extensions.DependencyInjection;
@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Http
{
UserAgent = agent,
ConnectionId = key,
Ip = context.Connection.RemoteIpAddress.ToIPv4String(),
Ip = context.Connection.RemoteIpAddress?.ToIPv4String() ?? string.Empty,
Browser = userAgent == null ? "Unknown" : $"{userAgent.Browser?.Name} {userAgent.Browser?.Version}",
OS = userAgent == null ? "Unknown" : $"{userAgent.OS?.Name} {userAgent.OS?.Version}",
FirstAccessTime = DateTime.Now,

View File

@ -45,14 +45,14 @@ namespace Microsoft.JSInterop
/// 启用动画
/// </summary>
/// <param name="jSRuntime"></param>
public static void InitDocument(this IJSRuntime? jSRuntime) => jSRuntime.InvokeVoidAsync("$.initDocument");
public static void InitDocument(this IJSRuntime? jSRuntime) => jSRuntime?.InvokeVoidAsync("$.initDocument");
/// <summary>
/// 弹出 Modal 组件
/// </summary>
/// <param name="jSRuntime"></param>
/// <param name="modalId"></param>
public static void ToggleModal(this IJSRuntime? jSRuntime, string modalId) => jSRuntime.InvokeVoidAsync("$.toggleModal", modalId);
public static void ToggleModal(this IJSRuntime? jSRuntime, string modalId) => jSRuntime?.InvokeVoidAsync("$.toggleModal", modalId);
/// <summary>
/// 弹出 Toast 组件
@ -61,7 +61,7 @@ namespace Microsoft.JSInterop
/// <param name="title"></param>
/// <param name="message"></param>
/// <param name="cate"></param>
public static void ShowToast(this IJSRuntime? jSRuntime, string title, string message, ToastCategory cate) => jSRuntime.InvokeVoidAsync("$.showToast", title, message, cate.ToString());
public static void ShowToast(this IJSRuntime? jSRuntime, string title, string message, ToastCategory cate) => jSRuntime?.InvokeVoidAsync("$.showToast", title, message, cate.ToString());
/// <summary>
/// 弹出 Tooltip 组件
@ -69,14 +69,14 @@ namespace Microsoft.JSInterop
/// <param name="jSRuntime"></param>
/// <param name="id"></param>
/// <param name="method"></param>
public static void Tooltip(this IJSRuntime? jSRuntime, string id, string method) => jSRuntime.InvokeVoidAsync("$.tooltip", $"#{id}", method);
public static void Tooltip(this IJSRuntime? jSRuntime, string id, string method) => jSRuntime?.InvokeVoidAsync("$.tooltip", $"#{id}", method);
/// <summary>
/// 显示或者隐藏 网站 Blazor 挂件图标
/// </summary>
/// <param name="jSRuntime"></param>
/// <param name="show"></param>
public static void ToggleBlazor(this IJSRuntime? jSRuntime, bool show) => jSRuntime.InvokeVoidAsync("$.toggleBlazor", show);
public static void ToggleBlazor(this IJSRuntime? jSRuntime, bool show) => jSRuntime?.InvokeVoidAsync("$.toggleBlazor", show);
/// <summary>
/// 显示或者隐藏 网站 Blazor 挂件图标
@ -85,7 +85,7 @@ namespace Microsoft.JSInterop
/// <param name="showSidebar"></param>
/// <param name="showCardTitle"></param>
/// <param name="fixedTableHeader"></param>
public static void SetWebSettings(this IJSRuntime? jSRuntime, bool showSidebar, bool showCardTitle, bool fixedTableHeader) => jSRuntime.InvokeVoidAsync("$.setWebSettings", showSidebar, showCardTitle, fixedTableHeader);
public static void SetWebSettings(this IJSRuntime? jSRuntime, bool showSidebar, bool showCardTitle, bool fixedTableHeader) => jSRuntime?.InvokeVoidAsync("$.setWebSettings", showSidebar, showCardTitle, fixedTableHeader);
/// <summary>
/// 初始化 Table 组件
@ -93,6 +93,6 @@ namespace Microsoft.JSInterop
/// <param name="jSRuntime"></param>
/// <param name="id"></param>
/// <param name="firstRender"></param>
public static ValueTask InitTableAsync(this IJSRuntime? jSRuntime, string id, bool firstRender) => jSRuntime.InvokeVoidAsync("$.initTable", id, firstRender);
public static void InitTableAsync(this IJSRuntime? jSRuntime, string id, bool firstRender) => jSRuntime?.InvokeVoidAsync("$.initTable", id, firstRender);
}
}

View File

@ -3,7 +3,7 @@
<div class="@($"form-group {ColumnClass}")">
<label class="control-label" for="@Id">@DisplayName</label>
<input Id="@Id" data-original-title="@ErrorMessage" class="@($"form-control {CssClass} {ValidCss}")" placeholder="@PlaceHolder" maxlength=@MaxLength type="@InputType" value="@BindConverter.FormatValue(CurrentValue)" @oninput="EventCallback.Factory.CreateBinder<string>(this, __value => CurrentValueAsString = __value, CurrentValueAsString)" />
<input Id="@Id" data-original-title="@ErrorMessage" class="@($"form-control {CssClass} {ValidCss}")" placeholder="@PlaceHolder" maxlength=@MaxLength type="@InputType" value="@BindConverter.FormatValue(CurrentValue)" @oninput="EventCallback.Factory.CreateBinder<string>(this, __value => CurrentValueAsString = __value, CurrentValueAsString ?? string.Empty)" />
<CascadingValue Value="this" IsFixed="true">
@ChildContent
</CascadingValue>

View File

@ -99,7 +99,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
if (AuthenticationStateProvider != null)
{
var state = await AuthenticationStateProvider.GetAuthenticationStateAsync();
UserName = state?.User.Identity.Name;
UserName = state?.User.Identity!.Name;
}
}

View File

@ -1,4 +1,4 @@
using Bootstrap.Admin.Pages.Components;
using Bootstrap.Admin.Pages.Components;
using Bootstrap.DataAccess;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Authorization;
@ -42,7 +42,7 @@ namespace Bootstrap.Admin.Pages.Views.Admin.Components
if (AuthenticationStateProvider != null)
{
var state = await AuthenticationStateProvider.GetAuthenticationStateAsync();
UserName = state?.User.Identity.Name;
UserName = state?.User.Identity!.Name;
}
}

View File

@ -20,6 +20,6 @@
{
var menus = DataAccess.MenuHelper.RetrieveAllMenus(Layout.UserName);
var menu = menus.FirstOrDefault(menu => "/Pages/Admin/Index".Contains(menu.Url.ToBlazorMenuUrl(), StringComparison.OrdinalIgnoreCase));
JSRuntime.ActiveMenu(menu.Id);
JSRuntime.ActiveMenu(menu!.Id);
}
}