diff --git a/.editorconfig b/.editorconfig index 03ef2d8bf..03ae84d98 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,37 +1,85 @@ -; EditorConfig to support per-solution formatting. -; Use the EditorConfig VS add-in to make this work. -; http://editorconfig.org/ -; -; Here are some resources for what's supported for .NET/C# -; https://kent-boogaart.com/blog/editorconfig-reference-for-c-developers -; https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017 -; -; Be **careful** editing this because some of the rules don't support adding a severity level -; For instance if you change to `dotnet_sort_system_directives_first = true:warning` (adding `:warning`) -; then the rule will be silently ignored. - -; This is the default for the codeline. +# EditorConfig: https://editorconfig.org root = true [*] indent_style = space +indent_size = 4 +end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -[*.cs] -indent_size = 4 -dotnet_sort_system_directives_first = true +[*.md] +trim_trailing_whitespace = false -[*.{xml,config,*proj,nuspec,props,resx,targets,yml,tasks,cshtml,html}] +[*.{json,yml,yaml}] indent_size = 2 -[*.json] +[*.{csproj,props,targets,nuspec,xml,config,resx,tasks,cshtml,html}] indent_size = 2 -[*.{ps1,psm1}] +[*.{ps1,psm1,sh}] indent_size = 4 -[*.sh] -indent_size = 4 -end_of_line = lf \ No newline at end of file +[*.cs] +# Namespace +dotnet_style_namespace_match_folder = true + +# Using directives +dotnet_sort_system_directives_first = true +dotnet_separate_import_directive_groups = false + +# this. qualification +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion + +# Language keywords vs BCL types +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# var preferences +csharp_style_var_for_built_in_types = false:suggestion +csharp_style_var_when_type_is_apparent = true:suggestion +csharp_style_var_elsewhere = false:suggestion + +# Expression-level preferences +csharp_style_expression_bodied_methods = when_on_single_line:suggestion +csharp_style_expression_bodied_constructors = false:suggestion +csharp_style_expression_bodied_properties = true:suggestion +csharp_style_expression_bodied_accessors = true:suggestion + +# Pattern matching +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion + +# Null checking +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion + +# Formatting +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_space_after_cast = false +csharp_space_after_keywords_in_control_flow_statements = true + +# Naming conventions +dotnet_naming_rule.private_fields_should_be_camel_case.severity = suggestion +dotnet_naming_rule.private_fields_should_be_camel_case.symbols = private_fields +dotnet_naming_rule.private_fields_should_be_camel_case.style = camel_case_prefix + +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private + +dotnet_naming_style.camel_case_prefix.capitalization = camel_case +dotnet_naming_style.camel_case_prefix.required_prefix = _ + +# Severity overrides - don't break build for style +dotnet_analyzer_diagnostic.category-Style.severity = suggestion diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 348aab62c..eaa0d1f76 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -14,7 +14,14 @@ jobs: dotnet-version: '8.0.x' - run: dotnet restore WalkingTec.Mvvm.sln - run: dotnet build WalkingTec.Mvvm.sln --no-restore -c Release - - run: dotnet test WalkingTec.Mvvm.sln --no-build -c Release --verbosity normal + - name: Test + run: dotnet test WalkingTec.Mvvm.sln --no-build -c Release --verbosity normal --logger "trx;LogFileName=test-results.trx" + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results + path: "**/test-results.trx" security-scan: runs-on: ubuntu-latest needs: build-and-test diff --git a/WTM-8.1.13-SPEC.md b/WTM-8.1.13-SPEC.md new file mode 100644 index 000000000..23b81c22f --- /dev/null +++ b/WTM-8.1.13-SPEC.md @@ -0,0 +1,542 @@ +# WTM 8.1.13 Security Patches - Claude CLI Execution Spec + +## Overview + +This document is the **single source of truth** for implementing P0/P1 security and quality fixes on the WTM fork (`cct08311github/WTM`, `dotnet8` branch). Designed for Claude CLI automated execution. + +**Repository:** https://github.com/cct08311github/WTM +**Branch:** `dotnet8` (base), create `feature/8.1.13-security` for work +**Current version:** WTM 8.1.12, targeting net8.0 + +--- + +## Execution Order (7 tasks, each = 1 git commit) + +| Task | ID | Priority | Type | Risk | +|------|----|----------|------|------| +| 1 | P1-1 | HIGH | Dependency removal | Low | +| 2 | P1-2 | HIGH | Dependency replacement | Medium | +| 3 | P0-1a | CRITICAL | New file | Low | +| 4 | P0-1b | CRITICAL | Code modification (multiple files) | Medium | +| 5 | P0-2 | CRITICAL | New files + code modification | Medium | +| 6 | P1-3 | HIGH | Code modification | Medium | +| 7 | CI | INFRA | New file | Low | + +Before starting: `git checkout dotnet8 && git checkout -b feature/8.1.13-security` + +--- +## GitHub Issues to Create (5 total, create ALL before starting code changes) + +### Issue #1 +``` +Title: [P1-1] Remove legacy .NET Core 2.1.x dependencies +Labels: security, dependencies, P1 +``` +Body: Three NuGet packages reference .NET Core 2.1.x (EOL Aug 2021): Microsoft.AspNetCore.Http 2.1.34 (Core.csproj), Microsoft.AspNetCore.Mvc.ViewFeatures 2.1.3 (TagHelpers.LayUI.csproj), Microsoft.AspNetCore.Razor.Runtime 2.1.2 (TagHelpers.LayUI.csproj), System.IO.FileSystem 4.3.0 (unnecessary polyfill). All types included in .NET 8 shared framework. Replace with FrameworkReference. Risk: Low | Effort: 0.5 day + +### Issue #2 +``` +Title: [P1-2] Replace abandoned DotNetCore.NPOI with official NPOI 2.7.6 +Labels: security, dependencies, P1 +``` +Body: DotNetCore.NPOI 1.2.3 is abandoned fork with no security patches. Official NPOI actively maintained at 2.7.x. API compatible, same namespaces. Risk: Medium | Effort: 1-2 days + +### Issue #3 +``` +Title: [P0-1][CRITICAL] Replace MD5 password hashing with PBKDF2 +Labels: security, critical, P0 +``` +Body: Login uses bare Utils.GetMD5String(password) - unsalted MD5. Vulnerable to rainbow table attacks. Fails CISSP/SOC2 compliance. Fix: Add PasswordHashHelper with PBKDF2, transparent verify-and-upgrade migration. DB migration: ALTER TABLE FrameworkUser ALTER COLUMN Password NVARCHAR(256). Risk: Medium | Effort: 2-3 days + +### Issue #4 +``` +Title: [P0-2][CRITICAL] Implement JWT refresh token with rotation +Labels: security, critical, P0 +``` +Body: TokenService.cs returns RefreshToken = "". No refresh mechanism. Fix: Add RefreshTokenEntity, implement rotation with reuse detection, expand ITokenService, add API endpoints. DB migration: CREATE TABLE FrameworkRefreshTokens. Risk: Low (additive) | Effort: 2-3 days + +### Issue #5 +``` +Title: [P1-3] Fix sync-over-async patterns (ThreadPool starvation) +Labels: performance, P1 +``` +Body: ~20+ .Result/.Wait() on async methods. Highest risk: DoLogin() on every auth request. Key locations: WTMContext.cs DoLogin (6x), _WorkflowApiController.cs (5x), ApproveActivity.cs (5x). Fix: Add DoLoginAsync, keep sync wrapper [Obsolete]. Risk: Medium | Effort: 2-3 days + +--- +## Task 1: Remove Legacy .NET Core 2.1.x Dependencies [P1-1] + +### File: `src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj` + +DELETE this line: +```xml + +``` + +ADD this ItemGroup (after existing PackageReference ItemGroup): +```xml + + + +``` + +### File: `src/WalkingTec.Mvvm.TagHelpers.LayUI/WalkingTec.Mvvm.TagHelpers.LayUI.csproj` + +DELETE these 3 lines: +```xml + + + +``` + +REPLACE the now-empty ItemGroup with: +```xml + + + +``` + +### Verify: `dotnet build WalkingTec.Mvvm.sln -c Release` + +### Commit message: +``` +fix(deps): remove legacy .NET Core 2.1.x dependencies [P1-1] + +- Remove Microsoft.AspNetCore.Http 2.1.34 from Core.csproj +- Remove Mvc.ViewFeatures 2.1.3, Razor.Runtime 2.1.2, System.IO.FileSystem 4.3.0 from TagHelpers.LayUI.csproj +- Add FrameworkReference to Microsoft.AspNetCore.App (both projects) +Closes #1 +``` + +--- + +## Task 2: Replace DotNetCore.NPOI [P1-2] + +### File: `src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj` + +REPLACE: +```xml + +``` +WITH: +```xml + +``` + +Also check: `grep -rn "using DotNetCore" src/ --include="*.cs"` - if any found, change to `using NPOI`. + +### Verify: `dotnet build WalkingTec.Mvvm.sln -c Release` + +### Commit message: +``` +fix(deps): replace abandoned DotNetCore.NPOI with official NPOI 2.7.6 [P1-2] +Closes #2 +``` + +--- +## Task 3: Add PasswordHashHelper [P0-1a] + +### NEW FILE: `src/WalkingTec.Mvvm.Core/PasswordHashHelper.cs` + +```csharp +using System; +using System.Security.Cryptography; +using System.Text; +using System.Text.RegularExpressions; +using Microsoft.AspNetCore.Identity; + +namespace WalkingTec.Mvvm.Core +{ + public static class PasswordHashHelper + { + private static readonly PasswordHasher _hasher = new(); + private static readonly Regex _md5Pattern = + new(@"^[0-9A-F]{32}$", RegexOptions.Compiled); + + public static string HashPassword(string password) + { + if (string.IsNullOrEmpty(password)) return string.Empty; + return _hasher.HashPassword(string.Empty, password); + } + + public static PasswordVerifyResult VerifyPassword( + string storedHash, string password) + { + if (string.IsNullOrEmpty(storedHash) || + string.IsNullOrEmpty(password)) + return PasswordVerifyResult.Failed; + + if (IsLegacyMD5Hash(storedHash)) + { + var md5 = ComputeMD5(password); + return string.Equals(storedHash, md5, StringComparison.Ordinal) + ? PasswordVerifyResult.SuccessRehashNeeded + : PasswordVerifyResult.Failed; + } + + var result = _hasher.VerifyHashedPassword( + string.Empty, storedHash, password); + return result switch + { + PasswordVerificationResult.Success + => PasswordVerifyResult.Success, + PasswordVerificationResult.SuccessRehashNeeded + => PasswordVerifyResult.SuccessRehashNeeded, + _ => PasswordVerifyResult.Failed + }; + } + + public static bool IsLegacyMD5Hash(string hash) + { + if (string.IsNullOrEmpty(hash) || hash.Length != 32) return false; + return _md5Pattern.IsMatch(hash); + } + + internal static string ComputeMD5(string input) + { + if (string.IsNullOrEmpty(input)) return string.Empty; + byte[] buffer = Encoding.UTF8.GetBytes(input); + byte[] hash = MD5.HashData(buffer); + var sb = new StringBuilder(32); + foreach (byte b in hash) sb.Append(b.ToString("X2")); + return sb.ToString(); + } + } + + public enum PasswordVerifyResult + { + Failed = 0, + Success = 1, + SuccessRehashNeeded = 2 + } +} +``` + +### Verify: `dotnet build src/WalkingTec.Mvvm.Core/ -c Release` + +### Commit message: +``` +feat(security): add PasswordHashHelper with PBKDF2 and MD5 migration [P0-1a] +Part of #3 +``` + +--- +## Task 4: Apply Password Hashing to Existing Code [P0-1b] + +### 4a. File: `src/WalkingTec.Mvvm.Core/Utils.cs` (line ~757) + +Add [Obsolete] to GetMD5String: +```csharp +// FIND: + public static string GetMD5String(string str) +// REPLACE WITH: + [Obsolete("Use PasswordHashHelper.HashPassword(). MD5 is broken for passwords.")] + public static string GetMD5String(string str) +``` + +Fix GetMD5Stream memory bomb (line ~775): +```csharp +// FIND entire method: + public static string GetMD5Stream(Stream stream) + { + byte[] buffer = new byte[stream.Length]; + stream.Read(buffer, 0, buffer.Length); + return MD5String(buffer); + } +// REPLACE WITH: + public static string GetMD5Stream(Stream stream) + { + using var md5 = MD5.Create(); + byte[] hash = md5.ComputeHash(stream); + var sb = new StringBuilder(32); + foreach (byte b in hash) + sb.Append(b.ToString("X2")); + return sb.ToString(); + } +``` + +### 4b. File: `src/WalkingTec.Mvvm.Core/WTMContext.cs` (line ~444-449) + +FIND (in else branch where IsAuthenticated is false): +```csharp + else + { + exist = BaseUserQuery.IgnoreQueryFilters().Any(x => x.ITCode == username && x.Password == Utils.GetMD5String(password) && x.TenantCode == tenant && x.IsValid==true); + } +``` + +REPLACE WITH: +```csharp + else + { + var userEntity = BaseUserQuery.IgnoreQueryFilters() + .Where(x => x.ITCode == username + && x.TenantCode == tenant + && x.IsValid == true) + .Select(x => new { x.ID, x.Password }) + .FirstOrDefault(); + + if (userEntity != null) + { + var verifyResult = PasswordHashHelper.VerifyPassword( + userEntity.Password, password); + + if (verifyResult == PasswordVerifyResult.Failed) + { + exist = false; + } + else + { + exist = true; + if (verifyResult == PasswordVerifyResult.SuccessRehashNeeded) + { + try + { + var newHash = PasswordHashHelper.HashPassword(password); + var dbUser = DC.Set() + .IgnoreQueryFilters() + .FirstOrDefault(x => x.ID == userEntity.ID); + if (dbUser != null) + { + dbUser.Password = newHash; + DC.SaveChanges(); + } + } + catch { } + } + } + } + else + { + exist = false; + } + } +``` + +### 4c. Demo ViewModel Changes + +Run: `grep -rn "Utils.GetMD5String" demo/ --include="*.cs"` to find ALL occurrences. + +Standard replacement (apply to ALL demo projects - BlazorDemo, Demo, ReactDemo, Vue3Demo, VueDemo): + +| File pattern | Before | After | +|---|---|---| +| AccountController.cs | `Utils.GetMD5String(regInfo.Password)` | `PasswordHashHelper.HashPassword(regInfo.Password)` | +| DataContext.cs | `Utils.GetMD5String("000000")` | `PasswordHashHelper.HashPassword("000000")` | +| FrameworkTenantVM.cs | `Utils.GetMD5String("000000")` | `PasswordHashHelper.HashPassword("000000")` | +| FrameworkUserImportVM.cs | `Utils.GetMD5String(item.Password)` | `PasswordHashHelper.HashPassword(item.Password)` | +| FrameworkUserVM.cs (2x) | `Utils.GetMD5String(Entity.Password)` | `PasswordHashHelper.HashPassword(Entity.Password)` | + +Special: ChangePasswordVM.cs line ~32: +```csharp +// FIND: + if (DC.Set().Where(x => x.ITCode == LoginUserInfo.ITCode && x.Password == Utils.GetMD5String(OldPassword)).SingleOrDefault() == null) +// REPLACE WITH: + var currentUser = DC.Set().Where(x => x.ITCode == LoginUserInfo.ITCode).SingleOrDefault(); + if (currentUser == null || PasswordHashHelper.VerifyPassword(currentUser.Password, OldPassword) == PasswordVerifyResult.Failed) +``` + +ChangePasswordVM.cs line ~47: +```csharp +// FIND: + user.Password = Utils.GetMD5String(NewPassword); +// REPLACE WITH: + user.Password = PasswordHashHelper.HashPassword(NewPassword); +``` + +### Verify: `dotnet build WalkingTec.Mvvm.sln -c Release && dotnet test WalkingTec.Mvvm.sln -c Release` + +### Commit message: +``` +feat(security): apply PBKDF2 password hashing across codebase [P0-1b] +Closes #3 +``` + +--- +## Task 5: JWT Refresh Token [P0-2] + +### 5a. NEW FILE: `src/WalkingTec.Mvvm.Core/Models/RefreshTokenEntity.cs` + +```csharp +using System; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; + +namespace WalkingTec.Mvvm.Core +{ + [Table("FrameworkRefreshTokens")] + public class RefreshTokenEntity + { + [Key] + public Guid ID { get; set; } = Guid.NewGuid(); + [Required, StringLength(256)] + public string Token { get; set; } + [Required, StringLength(50)] + public string ITCode { get; set; } + [StringLength(50)] + public string TenantCode { get; set; } + public DateTime ExpiresUtc { get; set; } + public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; + [StringLength(50)] + public string CreatedByIp { get; set; } + public DateTime? RevokedUtc { get; set; } + [StringLength(50)] + public string RevokedByIp { get; set; } + [StringLength(256)] + public string ReplacedByToken { get; set; } + [StringLength(100)] + public string RevokeReason { get; set; } + [NotMapped] + public bool IsExpired => DateTime.UtcNow >= ExpiresUtc; + [NotMapped] + public bool IsRevoked => RevokedUtc != null; + [NotMapped] + public bool IsActive => !IsRevoked && !IsExpired; + } +} +``` + +### 5b. REPLACE FILE: `src/WalkingTec.Mvvm.Core/Auth/ITokenService.cs` + +Note: The file might be at a different path. Search: `find src -name "ITokenService.cs" -not -path "*/obj/*"` + +```csharp +using System.Threading.Tasks; +using WalkingTec.Mvvm.Core.Support.Json; + +namespace WalkingTec.Mvvm.Core +{ + public interface ITokenService + { + Task IssueTokenAsync(LoginUserInfo loginUserInfo, string ipAddress = null); + Task RefreshTokenAsync(string refreshToken, string ipAddress = null); + Task RevokeTokenAsync(string refreshToken, string ipAddress = null, string reason = null); + } +} +``` + +### 5c. REPLACE FILE: `src/WalkingTec.Mvvm.Mvc/Auth/JwtAuth/TokenService.cs` + +Full replacement file content is provided in the release package at `new-files/TokenService.cs`. The key changes are: +- Constructor adds `IServiceProvider sp` parameter +- `IssueTokenAsync` now creates and persists a RefreshTokenEntity +- New `RefreshTokenAsync` with rotation and reuse detection +- New `RevokeTokenAsync` for logout +- `RefreshToken` field now returns actual cryptographic token instead of "" + +### 5d. Add DbSet to DataContext + +Find DataContext files: `grep -rn "DbSet" demo/ src/ --include="*.cs"` + +In each DataContext class, add: +```csharp + public DbSet FrameworkRefreshTokens { get; set; } +``` + +### 5e. Add API endpoints to AccountController + +In each demo's AccountController (find: `grep -rn "loginjwt" demo/ --include="*.cs" -l`), add RefreshToken and RevokeToken endpoints. See release package for full code. + +### Verify: `dotnet build WalkingTec.Mvvm.sln -c Release` + +### Commit message: +``` +feat(security): implement JWT refresh token with rotation [P0-2] +Closes #4 +``` + +--- + +## Task 6: Async DoLogin [P1-3] + +Add `DoLoginAsync` to WTMContext.cs. It's identical to DoLogin but all `.Result` become `await` and all `.Wait()` become `await`. + +Keep existing `DoLogin` as deprecated wrapper: +```csharp + [Obsolete("Use DoLoginAsync to avoid ThreadPool starvation.")] + public LoginUserInfo DoLogin(string username, string password, string tenant) + => DoLoginAsync(username, password, tenant).GetAwaiter().GetResult(); +``` + +Update all callers: `grep -rn "\.DoLogin(" demo/ src/ --include="*.cs"` - change to `await Wtm.DoLoginAsync(...)`. + +### Commit message: +``` +perf: convert DoLogin to async [P1-3] +Closes #5 +``` + +--- + +## Task 7: CI Pipeline + +### NEW FILE: `.github/workflows/ci-build.yml` + +```yaml +name: WTM Build and Test +on: + push: + branches: [ dotnet8, "feature/**" ] + pull_request: + branches: [ dotnet8 ] +env: + DOTNET_VERSION: '8.0.x' + SOLUTION_FILE: 'WalkingTec.Mvvm.sln' +jobs: + build-and-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - run: dotnet restore WalkingTec.Mvvm.sln + - run: dotnet build WalkingTec.Mvvm.sln --no-restore -c Release + - run: dotnet test WalkingTec.Mvvm.sln --no-build -c Release --verbosity normal + security-scan: + runs-on: ubuntu-latest + needs: build-and-test + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.0.x + - run: dotnet list WalkingTec.Mvvm.sln package --vulnerable --include-transitive +``` + +### Commit: `ci: add GitHub Actions workflow` + +--- + +## DB Migration (run BEFORE deploying code) + +```sql +ALTER TABLE [FrameworkUser] ALTER COLUMN [Password] NVARCHAR(256) NOT NULL; + +CREATE TABLE [FrameworkRefreshTokens] ( + [ID] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT NEWID(), + [Token] NVARCHAR(256) NOT NULL, + [ITCode] NVARCHAR(50) NOT NULL, + [TenantCode] NVARCHAR(50) NULL, + [ExpiresUtc] DATETIME2 NOT NULL, + [CreatedUtc] DATETIME2 NOT NULL DEFAULT GETUTCDATE(), + [CreatedByIp] NVARCHAR(50) NULL, + [RevokedUtc] DATETIME2 NULL, + [RevokedByIp] NVARCHAR(50) NULL, + [ReplacedByToken] NVARCHAR(256) NULL, + [RevokeReason] NVARCHAR(100) NULL +); +CREATE INDEX IX_RefreshToken_Token ON [FrameworkRefreshTokens]([Token]); +CREATE INDEX IX_RefreshToken_ITCode ON [FrameworkRefreshTokens]([ITCode]); +``` + +## Final: Push, PR, Merge + +```bash +git push origin feature/8.1.13-security +gh pr create --base dotnet8 --title "v8.1.13: P0/P1 Security Patches" --body "Closes #1 #2 #3 #4 #5" +# Wait for CI green +gh pr merge --squash +git checkout dotnet8 && git pull +git tag -a v8.1.13 -m "Security: PBKDF2 passwords, JWT refresh, legacy deps, async login" +git push origin v8.1.13 +``` diff --git a/WTM-8.1.14-SPEC.md b/WTM-8.1.14-SPEC.md new file mode 100644 index 000000000..0472d56e0 --- /dev/null +++ b/WTM-8.1.14-SPEC.md @@ -0,0 +1,745 @@ +# WTM 8.1.14 Technical Debt & Stabilization - Claude CLI Execution Spec + +## Overview + +This document is the **single source of truth** for v8.1.14 technical debt cleanup on the WTM fork (`cct08311github/WTM`, `dotnet8` branch). Designed for Claude CLI automated execution. + +**Repository:** https://github.com/cct08311github/WTM +**Branch:** `dotnet8` (base after v8.1.13 merged), create `feature/8.1.14-stabilize` for work +**Prerequisite:** v8.1.13 must be merged into `dotnet8` first +**Current version:** WTM 8.1.13, targeting net8.0 + +--- + +## Execution Order (6 tasks, each = 1 git commit) + +| Task | ID | Priority | Type | Risk | +|------|----|----------|------|------| +| 1 | ASYNC-1 | HIGH | Code modification (multiple files) | Medium | +| 2 | DEPS-1 | HIGH | Dependency updates | Medium | +| 3 | QUALITY-1 | MEDIUM | New file (.editorconfig) | Low | +| 4 | QUALITY-2 | MEDIUM | csproj modifications | Low-Medium | +| 5 | TEST-1 | MEDIUM | New project + test files | Low | +| 6 | CI-UPDATE | LOW | CI config update | Low | + +Before starting: +```bash +git checkout dotnet8 && git pull origin dotnet8 +git checkout -b feature/8.1.14-stabilize +dotnet build WalkingTec.Mvvm.sln -c Release # confirm baseline +``` + +--- +## GitHub Issues to Create (4 total, create ALL before starting code changes) + +### Issue #6 +``` +Title: [P1-3 cont.] Complete sync-over-async fixes across codebase +Labels: performance, P1 +``` +Body: +v8.1.13 fixed DoLogin. Remaining ~15 `.Result/.Wait()` calls cause ThreadPool starvation risk under load. + +Locations: +- `_WorkflowApiController.cs`: 5x `Request.RedirectCall(...).Result` +- `ApproveActivity.cs`: 5x `CallAPI(...).Result` +- `FrameworkServiceExtension.cs`: `DataInit(...).Wait()` +- `SessionExtension.cs`: `CommitAsync().Wait()` +- Any others found via `grep -rn "\.Result[^s]" src/ --include="*.cs"` and `grep -rn "\.Wait()" src/ --include="*.cs"` + +Fix: Convert to async/await. Keep sync wrappers marked [Obsolete] where public API. +Risk: Medium | Effort: 2-3 days + +### Issue #7 +``` +Title: [DEPS] Full dependency audit and update +Labels: dependencies, security +``` +Body: +Run `dotnet list WalkingTec.Mvvm.sln package --outdated` and upgrade all packages to latest stable within same major version. Do NOT cross major version boundaries without explicit approval. + +Special attention: +- EF Core: upgrade to latest 8.0.x patch +- System.Text.Json: check version alignment +- Any package with known CVEs (check `dotnet list package --vulnerable`) + +Risk: Medium | Effort: 1 day + +### Issue #8 +``` +Title: [QUALITY] Add .editorconfig and enable Nullable Reference Types +Labels: quality, code-health +``` +Body: +1. Add `.editorconfig` with consistent C# coding standards +2. Enable `enable` starting with Core project +3. Fix resulting warnings (nullable annotations) + +Risk: Low-Medium | Effort: 2-3 days + +### Issue #9 +``` +Title: [TEST] Establish unit test project and baseline coverage +Labels: testing, quality +``` +Body: +Create xUnit test project targeting critical security code: +- PasswordHashHelper (hash, verify, MD5 migration) +- TokenService (issue, refresh, revoke, reuse detection) +- RefreshTokenEntity (computed properties) + +Goal: baseline test coverage on security-critical paths. +Risk: Low | Effort: 2 days + +--- +## Task 1: Complete Sync-over-Async Fixes [ASYNC-1] + +### Step 1: Full scan of remaining violations + +Run these commands to find ALL remaining sync-over-async: +```bash +# Find .Result calls (excluding comments, string literals, test files) +grep -rn "\.Result[^s\"]" src/ --include="*.cs" | grep -v "//.*\.Result" | grep -v "/obj/" + +# Find .Wait() calls +grep -rn "\.Wait()" src/ --include="*.cs" | grep -v "//.*\.Wait" | grep -v "/obj/" + +# Find .GetAwaiter().GetResult() calls (these are OK in [Obsolete] wrappers only) +grep -rn "GetAwaiter().GetResult()" src/ --include="*.cs" | grep -v "/obj/" +``` + +### Step 2: Fix `_WorkflowApiController` + +File: Search with `find src/ -name "*Workflow*" -not -path "*/obj/*"` +(Note: This might be a .txt template file that generates controllers) + +For each occurrence of `.Result`: +```csharp +// FIND pattern: +var result = someAsyncCall(...).Result; +// REPLACE WITH: +var result = await someAsyncCall(...); +``` + +Ensure the containing method signature is changed to `async Task` if not already. + +### Step 3: Fix `ApproveActivity.cs` + +File: Search with `find src/ -name "ApproveActivity.cs" -not -path "*/obj/*"` + +Same pattern: replace all `.Result` with `await`, change method signatures to async. + +### Step 4: Fix `FrameworkServiceExtension.cs` + +File: Search with `find src/ -name "FrameworkServiceExtension.cs" -not -path "*/obj/*"` + +```csharp +// FIND pattern: +DataInit(...).Wait(); +// REPLACE WITH: +await DataInit(...); +``` + +If `DataInit` is called from a synchronous context (like `Configure`), use this pattern instead: +```csharp +// If in IApplicationBuilder pipeline (sync context), keep as-is but add comment: +// TODO: Convert to IHostedService for proper async startup in future version +DataInit(...).GetAwaiter().GetResult(); +``` + +### Step 5: Fix `SessionExtension.cs` + +File: Search with `find src/ -name "SessionExtension.cs" -not -path "*/obj/*"` + +```csharp +// FIND pattern: +CommitAsync().Wait(); +// REPLACE WITH (if method can be made async): +await CommitAsync(); +// OR (if sync context is unavoidable): +// Add [Obsolete] and provide async alternative +``` + +### Step 6: Fix any remaining violations found in Step 1 + +Apply the same patterns. For each file: +1. If the caller can be made async -> use await +2. If the caller is in a sync-only context (startup, interface constraint) -> use `.GetAwaiter().GetResult()` with a `// TODO` comment +3. Never use `.Result` or `.Wait()` - these can deadlock + +### Verification +```bash +dotnet build WalkingTec.Mvvm.sln -c Release + +# Verify no remaining .Result/.Wait() (except [Obsolete] wrappers and startup code): +grep -rn "\.Result[^s\"]" src/ --include="*.cs" | grep -v "/obj/" | grep -v "Obsolete" | grep -v "TODO" +grep -rn "\.Wait()" src/ --include="*.cs" | grep -v "/obj/" | grep -v "Obsolete" | grep -v "TODO" +``` + +### Commit message: +``` +perf: complete sync-over-async fixes across codebase [ASYNC-1] + +- WorkflowApiController: convert RedirectCall().Result to await +- ApproveActivity: convert CallAPI().Result to await +- FrameworkServiceExtension: fix DataInit().Wait() +- SessionExtension: fix CommitAsync().Wait() +- Mark unavoidable sync wrappers with TODO for future refactor + +Closes #6 +``` + +--- +## Task 2: Full Dependency Audit and Update [DEPS-1] + +### Step 1: Audit current state + +```bash +# List all outdated packages +dotnet list WalkingTec.Mvvm.sln package --outdated + +# Check for known vulnerabilities +dotnet list WalkingTec.Mvvm.sln package --vulnerable --include-transitive +``` + +### Step 2: Upgrade rules + +**DO upgrade:** +- All packages within same major version to latest patch/minor +- EF Core 8.x -> latest 8.0.x +- Microsoft.Extensions.* -> latest 8.x +- Any package with CVE advisories + +**DO NOT upgrade without asking the project owner:** +- Any package crossing a major version boundary (e.g., 7.x -> 8.x, 2.x -> 3.x) +- Newtonsoft.Json (deep integration, needs separate migration plan) + +**DO NOT upgrade at all:** +- Packages that would require .NET 9 (skip per project owner decision) + +### Step 3: Apply upgrades + +For each `.csproj` file with outdated packages, update the version number. + +After EACH package group upgrade, run: +```bash +dotnet build WalkingTec.Mvvm.sln -c Release +``` + +If build fails after a specific upgrade, revert that one and note it as a known issue. + +### Step 4: Verify no new vulnerabilities +```bash +dotnet list WalkingTec.Mvvm.sln package --vulnerable --include-transitive +``` + +### Commit message: +``` +fix(deps): full dependency audit and update to latest stable [DEPS-1] + +- Upgraded [list each package: name X.Y.Z -> X.Y.Z] +- No major version boundary crossings +- Verified zero known CVEs in direct dependencies + +Closes #7 +``` + +--- +## Task 3: Add .editorconfig [QUALITY-1] + +### NEW FILE: `.editorconfig` (in repo root) + +```ini +# EditorConfig: https://editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[*.{json,yml,yaml}] +indent_size = 2 + +[*.{csproj,props,targets}] +indent_size = 2 + +[*.cs] +# Namespace +dotnet_style_namespace_match_folder = true + +# Using directives +dotnet_sort_system_directives_first = true +dotnet_separate_import_directive_groups = false + +# this. qualification +dotnet_style_qualification_for_field = false:suggestion +dotnet_style_qualification_for_property = false:suggestion +dotnet_style_qualification_for_method = false:suggestion +dotnet_style_qualification_for_event = false:suggestion + +# Language keywords vs BCL types +dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion +dotnet_style_predefined_type_for_member_access = true:suggestion + +# var preferences +csharp_style_var_for_built_in_types = false:suggestion +csharp_style_var_when_type_is_apparent = true:suggestion +csharp_style_var_elsewhere = false:suggestion + +# Expression-level preferences +csharp_style_expression_bodied_methods = when_on_single_line:suggestion +csharp_style_expression_bodied_constructors = false:suggestion +csharp_style_expression_bodied_properties = true:suggestion +csharp_style_expression_bodied_accessors = true:suggestion + +# Pattern matching +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion + +# Null checking +csharp_style_throw_expression = true:suggestion +csharp_style_conditional_delegate_call = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_null_propagation = true:suggestion + +# Formatting +csharp_new_line_before_open_brace = all +csharp_new_line_before_else = true +csharp_new_line_before_catch = true +csharp_new_line_before_finally = true +csharp_indent_case_contents = true +csharp_indent_switch_labels = true +csharp_space_after_cast = false +csharp_space_after_keywords_in_control_flow_statements = true + +# Naming conventions +dotnet_naming_rule.private_fields_should_be_camel_case.severity = suggestion +dotnet_naming_rule.private_fields_should_be_camel_case.symbols = private_fields +dotnet_naming_rule.private_fields_should_be_camel_case.style = camel_case_prefix + +dotnet_naming_symbols.private_fields.applicable_kinds = field +dotnet_naming_symbols.private_fields.applicable_accessibilities = private + +dotnet_naming_style.camel_case_prefix.capitalization = camel_case +dotnet_naming_style.camel_case_prefix.required_prefix = _ + +# Severity overrides - don't break build for style +dotnet_analyzer_diagnostic.category-Style.severity = suggestion +``` + +### Verification +```bash +dotnet build WalkingTec.Mvvm.sln -c Release +# Should produce no new errors (style rules are suggestion level only) +``` + +### Commit message: +``` +chore: add .editorconfig with C# coding standards [QUALITY-1] + +- Consistent indentation, charset, line endings +- C# style rules as suggestions (non-breaking) +- Naming conventions for private fields (_camelCase) + +Part of #8 +``` + +--- +## Task 4: Enable Nullable Reference Types [QUALITY-2] + +### Strategy: Incremental enablement + +Enable Nullable in this order (least to most dependents): +1. `WalkingTec.Mvvm.Core` - the foundation +2. Only Core for v8.1.14. Other projects in future versions. + +### Step 1: Enable in Core.csproj + +File: `src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj` + +ADD inside ``: +```xml + enable +``` + +### Step 2: Build and assess + +```bash +dotnet build src/WalkingTec.Mvvm.Core/ -c Release 2>&1 | grep -c "warning CS86" +``` + +This will show the count of nullable warnings. + +### Step 3: Fix warnings - priority tiers + +**Tier 1 - Fix immediately (security-critical files from v8.1.13):** +- `PasswordHashHelper.cs` - add proper null annotations +- `RefreshTokenEntity.cs` - mark nullable properties with `?` +- `ITokenService.cs` - annotate return types + +**Tier 2 - Fix if < 50 warnings:** +- Model classes: add `?` to optional properties, `required` to mandatory ones +- Extension methods: add null guards + +**Tier 3 - Suppress if > 50 warnings remaining:** +For files that would take excessive effort, add at the top of the file: +```csharp +#nullable disable +``` +This preserves the opt-in model without blocking the build. + +### Step 4: Ensure zero warnings in new code + +After fixing/suppressing, the build must be clean: +```bash +dotnet build WalkingTec.Mvvm.sln -c Release +# Full solution must still build. Nullable warnings are OK in non-Core projects. +# Core project should have zero nullable warnings. +``` + +### Important: Do NOT enable Nullable in other projects yet +Projects that depend on Core will get warnings from consuming nullable-annotated APIs. That is fine - they will be addressed in future versions. + +### Commit message: +``` +chore: enable Nullable Reference Types in Core project [QUALITY-2] + +- Enable enable in WalkingTec.Mvvm.Core.csproj +- Add null annotations to security-critical files +- Suppress nullable in legacy files pending future cleanup +- Other projects remain nullable-oblivious for now + +Closes #8 +``` + +--- +## Task 5: Establish Unit Test Project [TEST-1] + +### Step 1: Create test project + +```bash +cd src/ +dotnet new xunit -n WalkingTec.Mvvm.Core.Tests -f net8.0 +cd WalkingTec.Mvvm.Core.Tests/ +dotnet add reference ../WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj +dotnet add package Moq --version 4.* +dotnet add package FluentAssertions --version 6.* +dotnet add package Microsoft.EntityFrameworkCore.InMemory --version 8.* +``` + +### Step 2: Add test project to solution + +```bash +cd ../../ # back to repo root +dotnet sln WalkingTec.Mvvm.sln add src/WalkingTec.Mvvm.Core.Tests/WalkingTec.Mvvm.Core.Tests.csproj +``` + +### Step 3: Add InternalsVisibleTo in Core.csproj + +File: `src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj` + +ADD this ItemGroup: +```xml + + + +``` + +### Step 4: Create test files + +#### NEW FILE: `src/WalkingTec.Mvvm.Core.Tests/PasswordHashHelperTests.cs` + +```csharp +using FluentAssertions; +using WalkingTec.Mvvm.Core; +using Xunit; + +namespace WalkingTec.Mvvm.Core.Tests +{ + public class PasswordHashHelperTests + { + [Fact] + public void HashPassword_ReturnsNonEmptyString() + { + var hash = PasswordHashHelper.HashPassword("test123"); + hash.Should().NotBeNullOrEmpty(); + hash.Should().NotBe("test123"); + } + + [Fact] + public void HashPassword_EmptyInput_ReturnsEmpty() + { + PasswordHashHelper.HashPassword("").Should().BeEmpty(); + PasswordHashHelper.HashPassword(null).Should().BeEmpty(); + } + + [Fact] + public void HashPassword_DifferentCalls_ProduceDifferentHashes() + { + var hash1 = PasswordHashHelper.HashPassword("test123"); + var hash2 = PasswordHashHelper.HashPassword("test123"); + hash1.Should().NotBe(hash2, "PBKDF2 uses random salt"); + } + + [Fact] + public void VerifyPassword_CorrectPassword_ReturnsSuccess() + { + var hash = PasswordHashHelper.HashPassword("myPassword"); + var result = PasswordHashHelper.VerifyPassword(hash, "myPassword"); + result.Should().Be(PasswordVerifyResult.Success); + } + + [Fact] + public void VerifyPassword_WrongPassword_ReturnsFailed() + { + var hash = PasswordHashHelper.HashPassword("myPassword"); + var result = PasswordHashHelper.VerifyPassword(hash, "wrongPassword"); + result.Should().Be(PasswordVerifyResult.Failed); + } + + [Fact] + public void VerifyPassword_NullInputs_ReturnsFailed() + { + PasswordHashHelper.VerifyPassword(null, "pw") + .Should().Be(PasswordVerifyResult.Failed); + PasswordHashHelper.VerifyPassword("hash", null) + .Should().Be(PasswordVerifyResult.Failed); + PasswordHashHelper.VerifyPassword(null, null) + .Should().Be(PasswordVerifyResult.Failed); + } + + [Fact] + public void VerifyPassword_LegacyMD5_ReturnsSuccessRehashNeeded() + { + var md5Hash = PasswordHashHelper.ComputeMD5("000000"); + var result = PasswordHashHelper.VerifyPassword(md5Hash, "000000"); + result.Should().Be(PasswordVerifyResult.SuccessRehashNeeded); + } + + [Fact] + public void VerifyPassword_LegacyMD5_WrongPassword_ReturnsFailed() + { + var md5Hash = PasswordHashHelper.ComputeMD5("000000"); + var result = PasswordHashHelper.VerifyPassword(md5Hash, "111111"); + result.Should().Be(PasswordVerifyResult.Failed); + } + + [Fact] + public void IsLegacyMD5Hash_ValidMD5_ReturnsTrue() + { + PasswordHashHelper.IsLegacyMD5Hash("670B14728AD9902AECBA32E22FA4F6BD") + .Should().BeTrue(); + } + + [Fact] + public void IsLegacyMD5Hash_PBKDF2Hash_ReturnsFalse() + { + var pbkdf2 = PasswordHashHelper.HashPassword("test"); + PasswordHashHelper.IsLegacyMD5Hash(pbkdf2).Should().BeFalse(); + } + + [Fact] + public void IsLegacyMD5Hash_NullOrEmpty_ReturnsFalse() + { + PasswordHashHelper.IsLegacyMD5Hash(null).Should().BeFalse(); + PasswordHashHelper.IsLegacyMD5Hash("").Should().BeFalse(); + } + + [Fact] + public void IsLegacyMD5Hash_WrongLength_ReturnsFalse() + { + PasswordHashHelper.IsLegacyMD5Hash("ABC123").Should().BeFalse(); + } + + [Fact] + public void MigrationFlow_MD5ToNewHash_Verify_Success() + { + // Simulate: user had MD5 password, logs in, system upgrades + var legacyMD5 = PasswordHashHelper.ComputeMD5("secretPassword"); + + // Step 1: Verify against legacy hash + var verifyResult = PasswordHashHelper.VerifyPassword( + legacyMD5, "secretPassword"); + verifyResult.Should().Be(PasswordVerifyResult.SuccessRehashNeeded); + + // Step 2: Generate new PBKDF2 hash + var newHash = PasswordHashHelper.HashPassword("secretPassword"); + + // Step 3: Verify against new hash + var verifyNew = PasswordHashHelper.VerifyPassword( + newHash, "secretPassword"); + verifyNew.Should().Be(PasswordVerifyResult.Success); + } + } +} +``` + +#### NEW FILE: `src/WalkingTec.Mvvm.Core.Tests/RefreshTokenEntityTests.cs` + +```csharp +using System; +using FluentAssertions; +using WalkingTec.Mvvm.Core; +using Xunit; + +namespace WalkingTec.Mvvm.Core.Tests +{ + public class RefreshTokenEntityTests + { + [Fact] + public void NewToken_IsActive() + { + var token = new RefreshTokenEntity + { + Token = "test-token", + ITCode = "admin", + ExpiresUtc = DateTime.UtcNow.AddDays(7) + }; + token.IsActive.Should().BeTrue(); + token.IsExpired.Should().BeFalse(); + token.IsRevoked.Should().BeFalse(); + } + + [Fact] + public void ExpiredToken_IsNotActive() + { + var token = new RefreshTokenEntity + { + Token = "test-token", + ITCode = "admin", + ExpiresUtc = DateTime.UtcNow.AddMinutes(-1) + }; + token.IsActive.Should().BeFalse(); + token.IsExpired.Should().BeTrue(); + } + + [Fact] + public void RevokedToken_IsNotActive() + { + var token = new RefreshTokenEntity + { + Token = "test-token", + ITCode = "admin", + ExpiresUtc = DateTime.UtcNow.AddDays(7), + RevokedUtc = DateTime.UtcNow + }; + token.IsActive.Should().BeFalse(); + token.IsRevoked.Should().BeTrue(); + } + + [Fact] + public void NewToken_HasGeneratedID() + { + var token = new RefreshTokenEntity(); + token.ID.Should().NotBe(Guid.Empty); + } + + [Fact] + public void NewToken_HasCreatedUtcSet() + { + var before = DateTime.UtcNow.AddSeconds(-1); + var token = new RefreshTokenEntity(); + var after = DateTime.UtcNow.AddSeconds(1); + token.CreatedUtc.Should().BeAfter(before).And.BeBefore(after); + } + } +} +``` + +### Verification +```bash +dotnet build WalkingTec.Mvvm.sln -c Release +dotnet test src/WalkingTec.Mvvm.Core.Tests/ -c Release --verbosity normal +``` + +All tests must pass. Expected: 17+ tests, 0 failures. + +### Commit message: +``` +test: add unit test project with PasswordHashHelper and RefreshToken tests [TEST-1] + +- New xUnit project: WalkingTec.Mvvm.Core.Tests +- 12 tests for PasswordHashHelper (hash, verify, MD5 migration flow) +- 5 tests for RefreshTokenEntity (active/expired/revoked states) +- Dependencies: FluentAssertions, Moq, EF Core InMemory +- Added InternalsVisibleTo for testing internal methods + +Closes #9 +``` + +--- +## Task 6: Update CI Pipeline [CI-UPDATE] + +### File: `.github/workflows/ci-build.yml` + +UPDATE the test step to include test result artifact upload. + +FIND: +```yaml + - run: dotnet test WalkingTec.Mvvm.sln --no-build -c Release --verbosity normal +``` +REPLACE WITH: +```yaml + - name: Test + run: dotnet test WalkingTec.Mvvm.sln --no-build -c Release --verbosity normal --logger "trx;LogFileName=test-results.trx" + + - name: Upload test results + uses: actions/upload-artifact@v4 + if: always() + with: + name: test-results + path: "**/test-results.trx" +``` + +### Commit message: +``` +ci: update workflow with test result artifacts [CI-UPDATE] +``` + +--- + +## Final Steps After All Tasks Complete + +```bash +# Push feature branch +git push origin feature/8.1.14-stabilize + +# Create PR +gh pr create \ + --base dotnet8 \ + --title "v8.1.14: Technical Debt Cleanup & Stabilization" \ + --body "## Changes +- Complete sync-over-async fixes (remaining .Result/.Wait() removed) +- Full dependency audit and update +- .editorconfig with C# coding standards +- Nullable Reference Types enabled in Core project +- Unit test project with baseline tests on security-critical code + +Closes #6 #7 #8 #9" + +# After CI passes and owner confirms, merge +gh pr merge --squash + +# Tag release +git checkout dotnet8 && git pull +git tag -a v8.1.14 -m "Stabilization: async fixes, dep updates, nullable, unit tests" +git push origin v8.1.14 +``` + +--- + +## Notes for Claude CLI Execution + +1. **Task 1 (async)** is the most complex - search carefully. Some `.Result` calls are in template `.txt` files that generate controllers. Fix those too. +2. **Task 2 (deps)** - run the audit commands first, then TELL the project owner what you plan to upgrade before doing it. Do NOT upgrade across major versions. Do NOT upgrade to anything requiring .NET 9. +3. **Task 4 (nullable)** - if warnings exceed 100 in Core project, use `#nullable disable` at the top of the worst files and note them for future cleanup. Do NOT let nullable warnings break the build. +4. **Task 5 (tests)** - the `ComputeMD5` method is `internal`, so the test project needs `InternalsVisibleTo`. This is handled in Step 3. +5. Do NOT merge PR automatically - wait for project owner confirmation. +6. If any task fails to build, STOP and report. Do not attempt speculative fixes. diff --git a/WalkingTec.Mvvm.sln b/WalkingTec.Mvvm.sln index 9d4ca04b7..de29b2732 100644 --- a/WalkingTec.Mvvm.sln +++ b/WalkingTec.Mvvm.sln @@ -59,6 +59,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WalkingTec.Mvvm.BlazorDemo. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WalkingTec.Mvvm.Vue3Demo", "demo\WalkingTec.Mvvm.Vue3Demo\WalkingTec.Mvvm.Vue3Demo.csproj", "{411690A4-0021-4509-BF24-900437B5DC6E}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WalkingTec.Mvvm.Core.Tests", "src\WalkingTec.Mvvm.Core.Tests\WalkingTec.Mvvm.Core.Tests.csproj", "{7338D82E-C258-4739-AE85-3B8B0D27AAED}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -133,6 +135,10 @@ Global {411690A4-0021-4509-BF24-900437B5DC6E}.Debug|Any CPU.Build.0 = Debug|Any CPU {411690A4-0021-4509-BF24-900437B5DC6E}.Release|Any CPU.ActiveCfg = Release|Any CPU {411690A4-0021-4509-BF24-900437B5DC6E}.Release|Any CPU.Build.0 = Release|Any CPU + {7338D82E-C258-4739-AE85-3B8B0D27AAED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7338D82E-C258-4739-AE85-3B8B0D27AAED}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7338D82E-C258-4739-AE85-3B8B0D27AAED}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7338D82E-C258-4739-AE85-3B8B0D27AAED}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -156,6 +162,7 @@ Global {94352C3E-899A-44A2-A052-578DC6A7159F} = {840C6DED-B5D5-4763-A6A7-6F615B72EC10} {D4104589-85BE-446A-A123-1E0FD1538A7B} = {840C6DED-B5D5-4763-A6A7-6F615B72EC10} {411690A4-0021-4509-BF24-900437B5DC6E} = {DE184A47-CF5F-41C0-AB7D-CAD0AF2DAE75} + {7338D82E-C258-4739-AE85-3B8B0D27AAED} = {46CFCDC6-4358-48EB-A901-5618B6530CEE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8D25EAAD-E43A-466A-95DA-ECE1F3C462DC} diff --git a/claude-cli-prompt-8.1.14.md b/claude-cli-prompt-8.1.14.md new file mode 100644 index 000000000..72656951d --- /dev/null +++ b/claude-cli-prompt-8.1.14.md @@ -0,0 +1,39 @@ +# WTM 8.1.14 Claude CLI Startup Prompt + +Place WTM-8.1.14-SPEC.md in repo root, then start claude and paste this prompt: + +--- + +You are the senior .NET maintenance engineer for the WTM framework fork. +Execute the WTM 8.1.14 stabilization spec from WTM-8.1.14-SPEC.md in this repo. + +Rules: +1. Read WTM-8.1.14-SPEC.md first with cat WTM-8.1.14-SPEC.md +2. Execute Task 1 through 6 strictly in order +3. Each Task = 1 git commit with the exact commit message from the spec +4. dotnet build after every Task +5. If build fails, STOP and show me the error. Do not guess. +6. For Task 2 (deps): show me the upgrade plan BEFORE applying it + +Phase 0: Prerequisites +- Confirm v8.1.13 is merged: git log --oneline -5 dotnet8 +- git checkout dotnet8 && git pull origin dotnet8 +- git checkout -b feature/8.1.14-stabilize +- dotnet build WalkingTec.Mvvm.sln -c Release (baseline check) + +Phase 1: Create GitHub Issues #6 through #9 using gh issue create + +Phase 2: Execute Tasks 1-6 following the spec exactly +- Task 1: grep ALL .Result/.Wait() first, fix systematically +- Task 2: show upgrade plan, wait for my OK, then apply +- Task 3: create .editorconfig exactly as specified +- Task 4: enable Nullable in Core only, use #nullable disable for noisy legacy files +- Task 5: create xUnit project, add InternalsVisibleTo, write tests, run tests +- Task 6: update CI yaml + +Phase 3: Push and PR +- git push origin feature/8.1.14-stabilize +- Create PR targeting dotnet8 +- Do NOT merge. Wait for my confirmation. + +Start now. Phase 0 first, report baseline build status. diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.Shared/WtmBlazorUtils/BasePage.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.Shared/WtmBlazorUtils/BasePage.cs index 89016ecd6..a64efcd3a 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.Shared/WtmBlazorUtils/BasePage.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.Shared/WtmBlazorUtils/BasePage.cs @@ -529,21 +529,21 @@ public string GetServerUrl() } } - public Task>> DefaultTreeConverter(IEnumerable data) where T:TreePoco + public async Task>> DefaultTreeConverter(IEnumerable data) where T:TreePoco { List> rv = new List>(); if(data == null || data.Count() == 0) { - return Task.FromResult(rv.AsEnumerable()); + return rv.AsEnumerable(); } foreach (var item in data) { TableTreeNode tt = new TableTreeNode(item); tt.HasChildren = item.HasChildren; - tt.Items = DefaultTreeConverter(item.Children).Result; + tt.Items = await DefaultTreeConverter(item.Children); rv.Add(tt); } - return Task.FromResult(rv.AsEnumerable()); + return rv.AsEnumerable(); } } } diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/DataPrivilegeVMs/DataPrivilegeListVM.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/DataPrivilegeVMs/DataPrivilegeListVM.cs index 6b9464eac..8af432d81 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/DataPrivilegeVMs/DataPrivilegeListVM.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/DataPrivilegeVMs/DataPrivilegeListVM.cs @@ -130,7 +130,7 @@ public override void AfterDoSearcher() Dictionary groupdata = new Dictionary(); if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").Result; + var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").GetAwaiter().GetResult(); if(dd.Data != null) { foreach (var item in dd.Data) diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/DataPrivilegeVMs/DataPrivilegeVM.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/DataPrivilegeVMs/DataPrivilegeVM.cs index aa3564868..e7ecde6ef 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/DataPrivilegeVMs/DataPrivilegeVM.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/DataPrivilegeVMs/DataPrivilegeVM.cs @@ -77,7 +77,7 @@ public override void Validate() string user = null; if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById").Result; + var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById").GetAwaiter().GetResult(); if (check.Data != null) { user = check.Data.Where(x => x.Value.ToString() == Entity.UserCode).Select(x => x.Value.ToString()).FirstOrDefault(); diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkGroupVMs/FrameworkGroupVM.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkGroupVMs/FrameworkGroupVM.cs index 30326329f..0a7a93357 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkGroupVMs/FrameworkGroupVM.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkGroupVMs/FrameworkGroupVM.cs @@ -34,13 +34,13 @@ public override void Validate() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkMenuVMs/FrameworkMenuVM2.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkMenuVMs/FrameworkMenuVM2.cs index 3550ccff2..9602caa94 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkMenuVMs/FrameworkMenuVM2.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkMenuVMs/FrameworkMenuVM2.cs @@ -269,7 +269,7 @@ public void AddPrivilege(List menuids) } } DC.SaveChanges(); - Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).Wait(); + Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).GetAwaiter().GetResult(); } diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkRoleVMs/FrameworkRoleMDVM2.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkRoleVMs/FrameworkRoleMDVM2.cs index b79eb180a..db256d4ad 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkRoleVMs/FrameworkRoleMDVM2.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkRoleVMs/FrameworkRoleMDVM2.cs @@ -24,7 +24,7 @@ protected override FrameworkRole GetById(object Id) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").Result.Data.Entity; + return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").GetAwaiter().GetResult().Data.Entity; } else { diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkRoleVMs/FrameworkRoleVM.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkRoleVMs/FrameworkRoleVM.cs index 8066549fb..64b22fff4 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkRoleVMs/FrameworkRoleVM.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkRoleVMs/FrameworkRoleVM.cs @@ -21,13 +21,13 @@ public override DuplicatedInfo SetDuplicatedCheck() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkTenantVMs/FrameworkTenantVM.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkTenantVMs/FrameworkTenantVM.cs index 3b3ca2681..4620f5433 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkTenantVMs/FrameworkTenantVM.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo.ViewModel/FrameworkTenantVMs/FrameworkTenantVM.cs @@ -79,7 +79,7 @@ private void TenantOperation() if (tenantdc.Database.EnsureCreated() == true) { tenantdc.SetTenantCode(Entity.TCode); - tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).Wait(); + tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).GetAwaiter().GetResult(); } AddTenantData(tenantdc, fps); } @@ -127,7 +127,7 @@ private void AddTenantData(IDataContext dc, List fps) } dc.SaveChanges(); var key = $"{GlobalConstants.CacheKey.UserInfo}:{"admin" + "$`$" + Entity.TCode}"; - Cache.DeleteAsync(key).Wait(); + Cache.DeleteAsync(key).GetAwaiter().GetResult(); } public override void DoDelete() { diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/AccountController.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/AccountController.cs index 09ff16eef..5cb507abe 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/AccountController.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/AccountController.cs @@ -137,9 +137,9 @@ public IActionResult Reg(SimpleReg regInfo) [HttpPost("[action]")] [AllRights] [ProducesResponseType(typeof(Token), StatusCodes.Status200OK)] - public IActionResult RefreshToken(string refreshToken) + public async Task RefreshToken(string refreshToken) { - var rv = Wtm.RefreshToken(); + var rv = await Wtm.RefreshTokenAsync(); if (rv == null) { return BadRequest(); @@ -198,11 +198,11 @@ public IActionResult CheckUserInfo(bool IsApi = true) [AllRights] [HttpPost("[action]")] - public IActionResult ChangePassword(ChangePasswordVM vm) + public async Task ChangePassword(ChangePasswordVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (!ModelState.IsValid) { @@ -243,11 +243,11 @@ public async Task Logout() [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -255,11 +255,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -267,11 +267,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -279,11 +279,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -291,11 +291,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); @@ -303,11 +303,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/DataPrivilegeController.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/DataPrivilegeController.cs index 0521d7d46..63b3187d1 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/DataPrivilegeController.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/DataPrivilegeController.cs @@ -137,22 +137,22 @@ public ActionResult GetPrivileges() [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroups() + public async Task GetUserGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroupsTree() + public async Task GetUserGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkGroupController.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkGroupController.cs index 607479b1e..ba8cb3f6f 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkGroupController.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkGroupController.cs @@ -19,11 +19,11 @@ public class FrameworkGroupController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkGroupSearcher searcher) + public async Task Search(FrameworkGroupSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -128,7 +128,7 @@ public async Task BatchDelete(string[] ids) DC.Set().RemoveRange(gr); DC.SaveChanges(); await Wtm.RemoveUserCacheByGroup(GroupCode.ToArray()); - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(ids.Count()); } } @@ -185,7 +185,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkGroupImportVM vm) + public async Task Import(FrameworkGroupImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) @@ -198,18 +198,18 @@ public ActionResult Import(FrameworkGroupImportVM vm) } else { - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } [AllRights] [HttpGet("[action]")] - public IActionResult GetParents() + public async Task GetParents() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents"); } var data = DC.Set().GetSelectListItems(Wtm, x => x.GroupName); return Ok(data); @@ -217,11 +217,11 @@ public IActionResult GetParents() [AllRights] [HttpGet("[action]")] - public IActionResult GetParentsTree() + public async Task GetParentsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree"); } var data = DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName); return Ok(data); diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkRoleController.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkRoleController.cs index 62724cfde..ef7ce2a10 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkRoleController.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkRoleController.cs @@ -19,11 +19,11 @@ public class FrameworkRoleController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkRoleSearcher searcher) + public async Task Search(FrameworkRoleSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -216,7 +216,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkRoleImportVM vm) + public async Task Import(FrameworkRoleImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { @@ -229,7 +229,7 @@ public ActionResult Import(FrameworkRoleImportVM vm) } else { - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } diff --git a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkUserController.cs b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkUserController.cs index e213fe8dd..0b9ab286c 100644 --- a/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkUserController.cs +++ b/demo/WalkingTec.Mvvm.BlazorDemo/WalkingTec.Mvvm.BlazorDemo/_Admin/Controllers/FrameworkUserController.cs @@ -20,11 +20,11 @@ public class FrameworkUserController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkUserSearcher searcher) + public async Task Search(FrameworkUserSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -222,11 +222,11 @@ public ActionResult Import(FrameworkUserImportVM vm) [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -234,11 +234,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -246,11 +246,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -258,11 +258,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -270,11 +270,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x=>x.UserCode).ToList(); return Ok(users); @@ -282,11 +282,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/AccountController.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/AccountController.cs index c693ede36..d94610491 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/AccountController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/AccountController.cs @@ -137,9 +137,9 @@ public IActionResult Reg(SimpleReg regInfo) [HttpPost("[action]")] [AllRights] [ProducesResponseType(typeof(Token), StatusCodes.Status200OK)] - public IActionResult RefreshToken(string refreshToken) + public async Task RefreshToken(string refreshToken) { - var rv = Wtm.RefreshToken(); + var rv = await Wtm.RefreshTokenAsync(); if (rv == null) { return BadRequest(); @@ -198,11 +198,11 @@ public IActionResult CheckUserInfo(bool IsApi = true) [AllRights] [HttpPost("[action]")] - public IActionResult ChangePassword(ChangePasswordVM vm) + public async Task ChangePassword(ChangePasswordVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (!ModelState.IsValid) { @@ -243,11 +243,11 @@ public async Task Logout() [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -255,11 +255,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -267,11 +267,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -279,11 +279,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -291,11 +291,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); @@ -303,11 +303,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/DataPrivilegeController.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/DataPrivilegeController.cs index 0521d7d46..63b3187d1 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/DataPrivilegeController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/DataPrivilegeController.cs @@ -137,22 +137,22 @@ public ActionResult GetPrivileges() [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroups() + public async Task GetUserGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroupsTree() + public async Task GetUserGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkGroupController.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkGroupController.cs index 607479b1e..ba8cb3f6f 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkGroupController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkGroupController.cs @@ -19,11 +19,11 @@ public class FrameworkGroupController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkGroupSearcher searcher) + public async Task Search(FrameworkGroupSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -128,7 +128,7 @@ public async Task BatchDelete(string[] ids) DC.Set().RemoveRange(gr); DC.SaveChanges(); await Wtm.RemoveUserCacheByGroup(GroupCode.ToArray()); - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(ids.Count()); } } @@ -185,7 +185,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkGroupImportVM vm) + public async Task Import(FrameworkGroupImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) @@ -198,18 +198,18 @@ public ActionResult Import(FrameworkGroupImportVM vm) } else { - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } [AllRights] [HttpGet("[action]")] - public IActionResult GetParents() + public async Task GetParents() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents"); } var data = DC.Set().GetSelectListItems(Wtm, x => x.GroupName); return Ok(data); @@ -217,11 +217,11 @@ public IActionResult GetParents() [AllRights] [HttpGet("[action]")] - public IActionResult GetParentsTree() + public async Task GetParentsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree"); } var data = DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName); return Ok(data); diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkRoleController.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkRoleController.cs index 62724cfde..ef7ce2a10 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkRoleController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkRoleController.cs @@ -19,11 +19,11 @@ public class FrameworkRoleController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkRoleSearcher searcher) + public async Task Search(FrameworkRoleSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -216,7 +216,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkRoleImportVM vm) + public async Task Import(FrameworkRoleImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { @@ -229,7 +229,7 @@ public ActionResult Import(FrameworkRoleImportVM vm) } else { - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkUserController.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkUserController.cs index e213fe8dd..0b9ab286c 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkUserController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ApiControllers/FrameworkUserController.cs @@ -20,11 +20,11 @@ public class FrameworkUserController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkUserSearcher searcher) + public async Task Search(FrameworkUserSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -222,11 +222,11 @@ public ActionResult Import(FrameworkUserImportVM vm) [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -234,11 +234,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -246,11 +246,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -258,11 +258,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -270,11 +270,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x=>x.UserCode).ToList(); return Ok(users); @@ -282,11 +282,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/DataPrivilegeController.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/DataPrivilegeController.cs index d8bf17704..4d4e6dadb 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/DataPrivilegeController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/DataPrivilegeController.cs @@ -133,11 +133,11 @@ public IActionResult ExportExcel(DataPrivilegeListVM vm) return vm.GetExportData(); } [AllRights] - public IActionResult GetUserGroups() + public async Task GetUserGroups() { WalkingTec.Mvvm.Admin.Api.DataPrivilegeController userapi = new Mvvm.Admin.Api.DataPrivilegeController(); userapi.Wtm = Wtm; - var rv = userapi.GetUserGroupsTree() as OkObjectResult; + var rv = (await userapi.GetUserGroupsTree()) as OkObjectResult; List users = new List(); if (rv != null && rv.Value is string && rv.Value != null) { diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkGroupController.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkGroupController.cs index e0f76adea..f07770f19 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkGroupController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkGroupController.cs @@ -26,12 +26,12 @@ public ActionResult Index() [ActionDescription("Sys.Search")] [HttpPost] - public IActionResult Search(FrameworkGroupSearcher searcher) + public async Task Search(FrameworkGroupSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { searcher.IsPlainText = false; - return Wtm.CallAPI("mainhost", "/api/_frameworkgroup/search", HttpMethodEnum.POST, searcher).Result.ToActionResult(); + return (await Wtm.CallAPI("mainhost", "/api/_frameworkgroup/search", HttpMethodEnum.POST, searcher)).ToActionResult(); } var vm = Wtm.CreateVM(passInit: true); if (ModelState.IsValid) @@ -188,7 +188,7 @@ public ActionResult Import() [HttpPost] [ActionDescription("Sys.Import")] - public ActionResult Import(FrameworkGroupImportVM vm, IFormCollection nouse) + public async Task Import(FrameworkGroupImportVM vm, IFormCollection nouse) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { @@ -200,7 +200,7 @@ public ActionResult Import(FrameworkGroupImportVM vm, IFormCollection nouse) } else { - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return FFResult().CloseDialog().RefreshGrid().Alert(Localizer["Sys.ImportSuccess", vm.EntityList.Count.ToString()]); } } @@ -232,11 +232,11 @@ public IActionResult ExportExcel(FrameworkGroupListVM vm) } [AllRights] - public IActionResult GetParents() + public async Task GetParents() { WalkingTec.Mvvm.Admin.Api.FrameworkGroupController userapi = new Mvvm.Admin.Api.FrameworkGroupController(); userapi.Wtm = Wtm; - var rv = userapi.GetParentsTree() as OkObjectResult; + var rv = (await userapi.GetParentsTree()) as OkObjectResult; List users = new List(); if (rv != null && rv.Value is string && rv.Value != null) { diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkRoleController.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkRoleController.cs index c15e1f29d..d8b089bd0 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkRoleController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkRoleController.cs @@ -23,12 +23,12 @@ public ActionResult Index() } [ActionDescription("Sys.Search")] [HttpPost] - public IActionResult Search(FrameworkRoleSearcher searcher) + public async Task Search(FrameworkRoleSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { searcher.IsPlainText = false; - return Wtm.CallAPI("mainhost", "/api/_frameworkrole/search", HttpMethodEnum.POST, searcher).Result.ToActionResult(); + return (await Wtm.CallAPI("mainhost", "/api/_frameworkrole/search", HttpMethodEnum.POST, searcher)).ToActionResult(); } var vm = Wtm.CreateVM(passInit: true); if (ModelState.IsValid) @@ -184,7 +184,7 @@ public ActionResult Import() [HttpPost] [ActionDescription("Sys.Import")] - public ActionResult Import(FrameworkRoleImportVM vm, IFormCollection nouse) + public async Task Import(FrameworkRoleImportVM vm, IFormCollection nouse) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { @@ -196,7 +196,7 @@ public ActionResult Import(FrameworkRoleImportVM vm, IFormCollection nouse) } else { - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant); return FFResult().CloseDialog().RefreshGrid().Alert(Localizer["Sys.ImportSuccess", vm.EntityList.Count.ToString()]); } } diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkUserController.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkUserController.cs index 8c9b81c8a..86ba42405 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkUserController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/Controllers/FrameworkUserController.cs @@ -372,11 +372,11 @@ public ActionResult Enable(Guid id, bool enable) } [AllRights] - public ActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { WalkingTec.Mvvm.Admin.Api.AccountController userapi = new WalkingTec.Mvvm.Admin.Api.AccountController(); userapi.Wtm = Wtm; - var rv = userapi.GetUserById(keywords) as OkObjectResult; + var rv = (await userapi.GetUserById(keywords)) as OkObjectResult; List users = new List(); if (rv != null && rv.Value is string && rv.Value != null) { @@ -402,11 +402,11 @@ public IActionResult ExportExcel(FrameworkUserListVM vm) } [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { WalkingTec.Mvvm.Admin.Api.AccountController userapi = new WalkingTec.Mvvm.Admin.Api.AccountController(); userapi.Wtm = Wtm; - var rv = userapi.GetFrameworkRoles() as OkObjectResult; + var rv = (await userapi.GetFrameworkRoles()) as OkObjectResult; List users = new List(); if (rv != null && rv.Value is string && rv.Value != null) { @@ -420,11 +420,11 @@ public IActionResult GetFrameworkRoles() } [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { WalkingTec.Mvvm.Admin.Api.AccountController userapi = new WalkingTec.Mvvm.Admin.Api.AccountController(); userapi.Wtm = Wtm; - var rv = userapi.GetFrameworkGroupsTree() as OkObjectResult; + var rv = (await userapi.GetFrameworkGroupsTree()) as OkObjectResult; List users = new List(); if (rv != null && rv.Value is string && rv.Value != null) { diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs index 6b9464eac..8af432d81 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs @@ -130,7 +130,7 @@ public override void AfterDoSearcher() Dictionary groupdata = new Dictionary(); if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").Result; + var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").GetAwaiter().GetResult(); if(dd.Data != null) { foreach (var item in dd.Data) diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs index aa3564868..e7ecde6ef 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs @@ -77,7 +77,7 @@ public override void Validate() string user = null; if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById").Result; + var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById").GetAwaiter().GetResult(); if (check.Data != null) { user = check.Data.Where(x => x.Value.ToString() == Entity.UserCode).Select(x => x.Value.ToString()).FirstOrDefault(); diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupMDVM.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupMDVM.cs index 0a1452829..a78dba9b4 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupMDVM.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupMDVM.cs @@ -87,7 +87,7 @@ public bool DoChange() } } DC.SaveChanges(); - Wtm.RemoveUserCacheByGroup(GroupCode).Wait(); + Wtm.RemoveUserCacheByGroup(GroupCode).GetAwaiter().GetResult(); return true; } diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs index 30326329f..0a7a93357 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs @@ -34,13 +34,13 @@ public override void Validate() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM.cs index f39579737..4dec56423 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM.cs @@ -392,7 +392,7 @@ public void AddPrivilege(List menuids) } } DC.SaveChanges(); - Wtm.RemoveUserCacheByRole(SelectedRolesIds.ToArray()).Wait(); + Wtm.RemoveUserCacheByRole(SelectedRolesIds.ToArray()).GetAwaiter().GetResult(); } diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs index 3550ccff2..9602caa94 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs @@ -269,7 +269,7 @@ public void AddPrivilege(List menuids) } } DC.SaveChanges(); - Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).Wait(); + Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).GetAwaiter().GetResult(); } diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM.cs index 44b668fc6..228668607 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM.cs @@ -21,7 +21,7 @@ protected override FrameworkRole GetById(object Id) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").Result.Data.Entity; + return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").GetAwaiter().GetResult().Data.Entity; } else { diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs index fa81f98cd..f897b0b83 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs @@ -24,7 +24,7 @@ protected override FrameworkRole GetById(object Id) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").Result.Data.Entity; + return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").GetAwaiter().GetResult().Data.Entity; } else { diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs index 8066549fb..64b22fff4 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs @@ -21,13 +21,13 @@ public override DuplicatedInfo SetDuplicatedCheck() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs index 3b3ca2681..4620f5433 100644 --- a/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs +++ b/demo/WalkingTec.Mvvm.Demo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs @@ -79,7 +79,7 @@ private void TenantOperation() if (tenantdc.Database.EnsureCreated() == true) { tenantdc.SetTenantCode(Entity.TCode); - tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).Wait(); + tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).GetAwaiter().GetResult(); } AddTenantData(tenantdc, fps); } @@ -127,7 +127,7 @@ private void AddTenantData(IDataContext dc, List fps) } dc.SaveChanges(); var key = $"{GlobalConstants.CacheKey.UserInfo}:{"admin" + "$`$" + Entity.TCode}"; - Cache.DeleteAsync(key).Wait(); + Cache.DeleteAsync(key).GetAwaiter().GetResult(); } public override void DoDelete() { diff --git a/demo/WalkingTec.Mvvm.Demo/Controllers/HomeController.cs b/demo/WalkingTec.Mvvm.Demo/Controllers/HomeController.cs index 6f4c7d197..4b2275bfa 100644 --- a/demo/WalkingTec.Mvvm.Demo/Controllers/HomeController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Controllers/HomeController.cs @@ -162,7 +162,7 @@ public Github GetGithubInfo() { var rv = Wtm.ReadFromCache("githubinfo", () => { - var s = Wtm.CallAPI("github", "repos/dotnetcore/wtm", 60).Result; + var s = Wtm.CallAPI("github", "repos/dotnetcore/wtm", 60).GetAwaiter().GetResult(); return s.Data; }, 1800); diff --git a/demo/WalkingTec.Mvvm.Demo/Controllers/LoginController.cs b/demo/WalkingTec.Mvvm.Demo/Controllers/LoginController.cs index 47a7eaaba..20d31c13f 100644 --- a/demo/WalkingTec.Mvvm.Demo/Controllers/LoginController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Controllers/LoginController.cs @@ -129,7 +129,7 @@ public async Task Logout() } else { - Wtm.CallAPI("mainhost", "/api/_account/logout", HttpMethodEnum.GET, new { }, 10).Wait(); + await Wtm.CallAPI("mainhost", "/api/_account/logout", HttpMethodEnum.GET, new { }, 10); HttpContext.Response.Redirect(ConfigInfo.MainHost); } } @@ -146,11 +146,11 @@ public ActionResult ChangePassword() [AllRights] [HttpPost] [ActionDescription("ChangePassword")] - public ActionResult ChangePassword(ChangePasswordVM vm) + public async Task ChangePassword(ChangePasswordVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var result = Wtm.CallAPI("mainhost", "/api/_account/ChangePassword", HttpMethodEnum.POST, vm, 10).Result; + var result = await Wtm.CallAPI("mainhost", "/api/_account/ChangePassword", HttpMethodEnum.POST, vm, 10); if (result.StatusCode == System.Net.HttpStatusCode.OK) { return FFResult().CloseDialog().Alert(Localizer["Login.ChangePasswordSuccess"]); diff --git a/demo/WalkingTec.Mvvm.Demo/Controllers/SchoolController.cs b/demo/WalkingTec.Mvvm.Demo/Controllers/SchoolController.cs index 9a2d8c5a2..bdf14d4c2 100644 --- a/demo/WalkingTec.Mvvm.Demo/Controllers/SchoolController.cs +++ b/demo/WalkingTec.Mvvm.Demo/Controllers/SchoolController.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using NPOI.HSSF.Util; @@ -83,7 +84,7 @@ public ActionResult Create() [HttpPost] [ActionDescription("新建")] - public ActionResult Create(SchoolVM vm) + public async Task Create(SchoolVM vm) { if (!ModelState.IsValid) { @@ -92,7 +93,7 @@ public ActionResult Create(SchoolVM vm) else { vm.DoAdd(); - var rv = vm.StartWorkflowAsync("学校审批").Result; + var rv = await vm.StartWorkflowAsync("学校审批"); if (!ModelState.IsValid) { vm.DoReInit(); @@ -116,7 +117,7 @@ public ActionResult Edit(string id) [ActionDescription("修改")] [HttpPost] - public ActionResult Edit(SchoolVM vm) + public async Task Edit(SchoolVM vm) { if (!ModelState.IsValid) { @@ -125,7 +126,7 @@ public ActionResult Edit(SchoolVM vm) else { vm.DoEdit(); - _ = vm.ContinueWorkflowAsync("同意", "adf adf asdf ","学校审批").Result; + _ = await vm.ContinueWorkflowAsync("同意", "adf adf asdf ","学校审批"); if (!ModelState.IsValid) { vm.DoReInit(); @@ -166,10 +167,10 @@ public ActionResult Delete(int id, IFormCollection nouse) #region 详细 [ActionDescription("详细")] - public ActionResult Details(int id) + public async Task Details(int id) { var vm = Wtm.CreateVM(id); - var test =vm.GetWorkflowTimeLineAsync().Result; + var test = await vm.GetWorkflowTimeLineAsync(); return PartialView(vm); } #endregion diff --git a/demo/WalkingTec.Mvvm.Demo/ViewModels/HomeVMs/RegVM.cs b/demo/WalkingTec.Mvvm.Demo/ViewModels/HomeVMs/RegVM.cs index 5b8cfa837..1e7d99c2c 100644 --- a/demo/WalkingTec.Mvvm.Demo/ViewModels/HomeVMs/RegVM.cs +++ b/demo/WalkingTec.Mvvm.Demo/ViewModels/HomeVMs/RegVM.cs @@ -72,7 +72,7 @@ public bool DoReg() DC.Set().Add(user); DC.SaveChanges(); var vm = Wtm.CreateVM(user.ID); - _=vm.StartWorkflowAsync().Result; + _=vm.StartWorkflowAsync().GetAwaiter().GetResult(); return true; } } diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/AccountController.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/AccountController.cs index 81dce9a3e..4f477c945 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/AccountController.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/AccountController.cs @@ -137,9 +137,9 @@ public IActionResult Reg(SimpleReg regInfo) [HttpPost("[action]")] [AllRights] [ProducesResponseType(typeof(Token), StatusCodes.Status200OK)] - public IActionResult RefreshToken(string refreshToken) + public async Task RefreshToken(string refreshToken) { - var rv = Wtm.RefreshToken(); + var rv = await Wtm.RefreshTokenAsync(); if (rv == null) { return BadRequest(); @@ -190,11 +190,11 @@ public IActionResult CheckUserInfo(bool IsApi = true) [AllRights] [HttpPost("[action]")] - public IActionResult ChangePassword(ChangePasswordVM vm) + public async Task ChangePassword(ChangePasswordVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (!ModelState.IsValid) { @@ -235,11 +235,11 @@ public async Task Logout() [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -247,11 +247,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -259,11 +259,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -271,11 +271,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -283,11 +283,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); @@ -295,11 +295,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/DataPrivilegeController.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/DataPrivilegeController.cs index 0521d7d46..63b3187d1 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/DataPrivilegeController.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/DataPrivilegeController.cs @@ -137,22 +137,22 @@ public ActionResult GetPrivileges() [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroups() + public async Task GetUserGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroupsTree() + public async Task GetUserGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkGroupController.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkGroupController.cs index 607479b1e..ba8cb3f6f 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkGroupController.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkGroupController.cs @@ -19,11 +19,11 @@ public class FrameworkGroupController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkGroupSearcher searcher) + public async Task Search(FrameworkGroupSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -128,7 +128,7 @@ public async Task BatchDelete(string[] ids) DC.Set().RemoveRange(gr); DC.SaveChanges(); await Wtm.RemoveUserCacheByGroup(GroupCode.ToArray()); - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(ids.Count()); } } @@ -185,7 +185,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkGroupImportVM vm) + public async Task Import(FrameworkGroupImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) @@ -198,18 +198,18 @@ public ActionResult Import(FrameworkGroupImportVM vm) } else { - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } [AllRights] [HttpGet("[action]")] - public IActionResult GetParents() + public async Task GetParents() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents"); } var data = DC.Set().GetSelectListItems(Wtm, x => x.GroupName); return Ok(data); @@ -217,11 +217,11 @@ public IActionResult GetParents() [AllRights] [HttpGet("[action]")] - public IActionResult GetParentsTree() + public async Task GetParentsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree"); } var data = DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName); return Ok(data); diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkRoleController.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkRoleController.cs index 62724cfde..ef7ce2a10 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkRoleController.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkRoleController.cs @@ -19,11 +19,11 @@ public class FrameworkRoleController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkRoleSearcher searcher) + public async Task Search(FrameworkRoleSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -216,7 +216,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkRoleImportVM vm) + public async Task Import(FrameworkRoleImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { @@ -229,7 +229,7 @@ public ActionResult Import(FrameworkRoleImportVM vm) } else { - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkUserController.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkUserController.cs index e213fe8dd..0b9ab286c 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkUserController.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/Controllers/FrameworkUserController.cs @@ -20,11 +20,11 @@ public class FrameworkUserController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkUserSearcher searcher) + public async Task Search(FrameworkUserSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -222,11 +222,11 @@ public ActionResult Import(FrameworkUserImportVM vm) [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -234,11 +234,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -246,11 +246,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -258,11 +258,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -270,11 +270,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x=>x.UserCode).ToList(); return Ok(users); @@ -282,11 +282,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs index 6b9464eac..8af432d81 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs @@ -130,7 +130,7 @@ public override void AfterDoSearcher() Dictionary groupdata = new Dictionary(); if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").Result; + var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").GetAwaiter().GetResult(); if(dd.Data != null) { foreach (var item in dd.Data) diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs index aa3564868..e7ecde6ef 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs @@ -77,7 +77,7 @@ public override void Validate() string user = null; if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById").Result; + var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById").GetAwaiter().GetResult(); if (check.Data != null) { user = check.Data.Where(x => x.Value.ToString() == Entity.UserCode).Select(x => x.Value.ToString()).FirstOrDefault(); diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs index 30326329f..0a7a93357 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs @@ -34,13 +34,13 @@ public override void Validate() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs index 3550ccff2..9602caa94 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs @@ -269,7 +269,7 @@ public void AddPrivilege(List menuids) } } DC.SaveChanges(); - Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).Wait(); + Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).GetAwaiter().GetResult(); } diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs index b79eb180a..db256d4ad 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs @@ -24,7 +24,7 @@ protected override FrameworkRole GetById(object Id) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").Result.Data.Entity; + return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").GetAwaiter().GetResult().Data.Entity; } else { diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs index 8066549fb..64b22fff4 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs @@ -21,13 +21,13 @@ public override DuplicatedInfo SetDuplicatedCheck() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs index 3b3ca2681..4620f5433 100644 --- a/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs +++ b/demo/WalkingTec.Mvvm.ReactDemo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs @@ -79,7 +79,7 @@ private void TenantOperation() if (tenantdc.Database.EnsureCreated() == true) { tenantdc.SetTenantCode(Entity.TCode); - tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).Wait(); + tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).GetAwaiter().GetResult(); } AddTenantData(tenantdc, fps); } @@ -127,7 +127,7 @@ private void AddTenantData(IDataContext dc, List fps) } dc.SaveChanges(); var key = $"{GlobalConstants.CacheKey.UserInfo}:{"admin" + "$`$" + Entity.TCode}"; - Cache.DeleteAsync(key).Wait(); + Cache.DeleteAsync(key).GetAwaiter().GetResult(); } public override void DoDelete() { diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/AccountController.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/AccountController.cs index 42c9aeb95..396a9fc98 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/AccountController.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/AccountController.cs @@ -138,9 +138,9 @@ public IActionResult Reg(SimpleReg regInfo) [HttpPost("[action]")] [AllRights] [ProducesResponseType(typeof(Token), StatusCodes.Status200OK)] - public IActionResult RefreshToken(string refreshToken) + public async Task RefreshToken(string refreshToken) { - var rv = Wtm.RefreshToken(); + var rv = await Wtm.RefreshTokenAsync(); if (rv == null) { return BadRequest(); @@ -197,11 +197,11 @@ public IActionResult CheckUserInfo(bool IsApi = true) [AllRights] [HttpPost("[action]")] - public IActionResult ChangePassword(ChangePasswordVM vm) + public async Task ChangePassword(ChangePasswordVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (!ModelState.IsValid) { @@ -242,11 +242,11 @@ public async Task Logout() [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -254,11 +254,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -266,11 +266,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -278,11 +278,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -290,11 +290,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); @@ -302,11 +302,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/DataPrivilegeController.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/DataPrivilegeController.cs index 0521d7d46..63b3187d1 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/DataPrivilegeController.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/DataPrivilegeController.cs @@ -137,22 +137,22 @@ public ActionResult GetPrivileges() [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroups() + public async Task GetUserGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroupsTree() + public async Task GetUserGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkGroupController.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkGroupController.cs index 607479b1e..ba8cb3f6f 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkGroupController.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkGroupController.cs @@ -19,11 +19,11 @@ public class FrameworkGroupController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkGroupSearcher searcher) + public async Task Search(FrameworkGroupSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -128,7 +128,7 @@ public async Task BatchDelete(string[] ids) DC.Set().RemoveRange(gr); DC.SaveChanges(); await Wtm.RemoveUserCacheByGroup(GroupCode.ToArray()); - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(ids.Count()); } } @@ -185,7 +185,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkGroupImportVM vm) + public async Task Import(FrameworkGroupImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) @@ -198,18 +198,18 @@ public ActionResult Import(FrameworkGroupImportVM vm) } else { - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } [AllRights] [HttpGet("[action]")] - public IActionResult GetParents() + public async Task GetParents() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents"); } var data = DC.Set().GetSelectListItems(Wtm, x => x.GroupName); return Ok(data); @@ -217,11 +217,11 @@ public IActionResult GetParents() [AllRights] [HttpGet("[action]")] - public IActionResult GetParentsTree() + public async Task GetParentsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree"); } var data = DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName); return Ok(data); diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkRoleController.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkRoleController.cs index 62724cfde..ef7ce2a10 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkRoleController.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkRoleController.cs @@ -19,11 +19,11 @@ public class FrameworkRoleController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkRoleSearcher searcher) + public async Task Search(FrameworkRoleSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -216,7 +216,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkRoleImportVM vm) + public async Task Import(FrameworkRoleImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { @@ -229,7 +229,7 @@ public ActionResult Import(FrameworkRoleImportVM vm) } else { - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkUserController.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkUserController.cs index e213fe8dd..0b9ab286c 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkUserController.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/Controllers/FrameworkUserController.cs @@ -20,11 +20,11 @@ public class FrameworkUserController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkUserSearcher searcher) + public async Task Search(FrameworkUserSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -222,11 +222,11 @@ public ActionResult Import(FrameworkUserImportVM vm) [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -234,11 +234,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -246,11 +246,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -258,11 +258,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -270,11 +270,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x=>x.UserCode).ToList(); return Ok(users); @@ -282,11 +282,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs index 6b9464eac..8af432d81 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs @@ -130,7 +130,7 @@ public override void AfterDoSearcher() Dictionary groupdata = new Dictionary(); if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").Result; + var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").GetAwaiter().GetResult(); if(dd.Data != null) { foreach (var item in dd.Data) diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs index d3996495f..1b2c63b41 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs @@ -77,7 +77,7 @@ public override void Validate() string user = null; if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById?keywords=" + Entity.UserCode).Result; + var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById?keywords=" + Entity.UserCode).GetAwaiter().GetResult(); if (check.Data != null) { user = check.Data.Where(x => x.Value.ToString() == Entity.UserCode).Select(x => x.Value.ToString()).FirstOrDefault(); diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs index 30326329f..0a7a93357 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs @@ -34,13 +34,13 @@ public override void Validate() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs index 3550ccff2..9602caa94 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs @@ -269,7 +269,7 @@ public void AddPrivilege(List menuids) } } DC.SaveChanges(); - Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).Wait(); + Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).GetAwaiter().GetResult(); } diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs index b79eb180a..db256d4ad 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs @@ -24,7 +24,7 @@ protected override FrameworkRole GetById(object Id) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").Result.Data.Entity; + return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").GetAwaiter().GetResult().Data.Entity; } else { diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs index 8066549fb..64b22fff4 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs @@ -21,13 +21,13 @@ public override DuplicatedInfo SetDuplicatedCheck() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs index 3b3ca2681..4620f5433 100644 --- a/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs +++ b/demo/WalkingTec.Mvvm.Vue3Demo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs @@ -79,7 +79,7 @@ private void TenantOperation() if (tenantdc.Database.EnsureCreated() == true) { tenantdc.SetTenantCode(Entity.TCode); - tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).Wait(); + tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).GetAwaiter().GetResult(); } AddTenantData(tenantdc, fps); } @@ -127,7 +127,7 @@ private void AddTenantData(IDataContext dc, List fps) } dc.SaveChanges(); var key = $"{GlobalConstants.CacheKey.UserInfo}:{"admin" + "$`$" + Entity.TCode}"; - Cache.DeleteAsync(key).Wait(); + Cache.DeleteAsync(key).GetAwaiter().GetResult(); } public override void DoDelete() { diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/AccountController.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/AccountController.cs index 81dce9a3e..4f477c945 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/AccountController.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/AccountController.cs @@ -137,9 +137,9 @@ public IActionResult Reg(SimpleReg regInfo) [HttpPost("[action]")] [AllRights] [ProducesResponseType(typeof(Token), StatusCodes.Status200OK)] - public IActionResult RefreshToken(string refreshToken) + public async Task RefreshToken(string refreshToken) { - var rv = Wtm.RefreshToken(); + var rv = await Wtm.RefreshTokenAsync(); if (rv == null) { return BadRequest(); @@ -190,11 +190,11 @@ public IActionResult CheckUserInfo(bool IsApi = true) [AllRights] [HttpPost("[action]")] - public IActionResult ChangePassword(ChangePasswordVM vm) + public async Task ChangePassword(ChangePasswordVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (!ModelState.IsValid) { @@ -235,11 +235,11 @@ public async Task Logout() [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -247,11 +247,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -259,11 +259,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -271,11 +271,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -283,11 +283,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); @@ -295,11 +295,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_account/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_account/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/DataPrivilegeController.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/DataPrivilegeController.cs index 0521d7d46..63b3187d1 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/DataPrivilegeController.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/DataPrivilegeController.cs @@ -137,22 +137,22 @@ public ActionResult GetPrivileges() [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroups() + public async Task GetUserGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } [AllRights] [HttpGet("[action]")] - public IActionResult GetUserGroupsTree() + public async Task GetUserGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_DataPrivilege/GetUserGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkGroupController.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkGroupController.cs index 607479b1e..ba8cb3f6f 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkGroupController.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkGroupController.cs @@ -19,11 +19,11 @@ public class FrameworkGroupController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkGroupSearcher searcher) + public async Task Search(FrameworkGroupSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -128,7 +128,7 @@ public async Task BatchDelete(string[] ids) DC.Set().RemoveRange(gr); DC.SaveChanges(); await Wtm.RemoveUserCacheByGroup(GroupCode.ToArray()); - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(ids.Count()); } } @@ -185,7 +185,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkGroupImportVM vm) + public async Task Import(FrameworkGroupImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) @@ -198,18 +198,18 @@ public ActionResult Import(FrameworkGroupImportVM vm) } else { - Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveGroupCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } [AllRights] [HttpGet("[action]")] - public IActionResult GetParents() + public async Task GetParents() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParents"); } var data = DC.Set().GetSelectListItems(Wtm, x => x.GroupName); return Ok(data); @@ -217,11 +217,11 @@ public IActionResult GetParents() [AllRights] [HttpGet("[action]")] - public IActionResult GetParentsTree() + public async Task GetParentsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkgroup/GetParentsTree"); } var data = DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName); return Ok(data); diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkRoleController.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkRoleController.cs index 62724cfde..ef7ce2a10 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkRoleController.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkRoleController.cs @@ -19,11 +19,11 @@ public class FrameworkRoleController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkRoleSearcher searcher) + public async Task Search(FrameworkRoleSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -216,7 +216,7 @@ public IActionResult GetExcelTemplate() [ActionDescription("Sys.Import")] [HttpPost("[action]")] - public ActionResult Import(FrameworkRoleImportVM vm) + public async Task Import(FrameworkRoleImportVM vm) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { @@ -229,7 +229,7 @@ public ActionResult Import(FrameworkRoleImportVM vm) } else { - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + await Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant); return Ok(vm.EntityList.Count); } } diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkUserController.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkUserController.cs index e213fe8dd..0b9ab286c 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkUserController.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/Controllers/FrameworkUserController.cs @@ -20,11 +20,11 @@ public class FrameworkUserController : BaseApiController { [ActionDescription("Sys.Search")] [HttpPost("[action]")] - public IActionResult Search(FrameworkUserSearcher searcher) + public async Task Search(FrameworkUserSearcher searcher) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm).Result; + return await Request.RedirectCall(Wtm); } if (ModelState.IsValid) { @@ -222,11 +222,11 @@ public ActionResult Import(FrameworkUserImportVM vm) [HttpGet("GetFrameworkRoles")] [ActionDescription("GetRoles")] [AllRights] - public IActionResult GetFrameworkRoles() + public async Task GetFrameworkRoles() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkRoles"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.RoleName, x => x.RoleCode)); } @@ -234,11 +234,11 @@ public IActionResult GetFrameworkRoles() [HttpGet("GetFrameworkGroups")] [ActionDescription("GetGroups")] [AllRights] - public IActionResult GetFrameworkGroups() + public async Task GetFrameworkGroups() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroups"); } return Ok(DC.Set().GetSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -246,11 +246,11 @@ public IActionResult GetFrameworkGroups() [HttpGet("GetFrameworkGroupsTree")] [ActionDescription("GetGroupsTree")] [AllRights] - public IActionResult GetFrameworkGroupsTree() + public async Task GetFrameworkGroupsTree() { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetFrameworkGroupsTree"); } return Ok(DC.Set().GetTreeSelectListItems(Wtm, x => x.GroupName, x => x.GroupCode)); } @@ -258,11 +258,11 @@ public IActionResult GetFrameworkGroupsTree() [HttpGet("GetUserById")] [AllRights] - public IActionResult GetUserById(string keywords) + public async Task GetUserById(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserById"); } var users = DC.Set().Where(x => x.ITCode.ToLower().StartsWith(keywords.ToLower())).GetSelectListItems(Wtm, x => x.Name + "(" + x.ITCode + ")", x => x.ITCode); return Ok(users); @@ -270,11 +270,11 @@ public IActionResult GetUserById(string keywords) [HttpGet("GetUserByGroup")] [AllRights] - public IActionResult GetUserByGroup(string keywords) + public async Task GetUserByGroup(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByGroup"); } var users = DC.Set().Where(x => x.GroupCode == keywords).Select(x=>x.UserCode).ToList(); return Ok(users); @@ -282,11 +282,11 @@ public IActionResult GetUserByGroup(string keywords) [HttpGet("GetUserByRole")] [AllRights] - public IActionResult GetUserByRole(string keywords) + public async Task GetUserByRole(string keywords) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole").Result; + return await Request.RedirectCall(Wtm, "/api/_frameworkuser/GetUserByRole"); } var users = DC.Set().Where(x => x.RoleCode == keywords).Select(x => x.UserCode).ToList(); return Ok(users); diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs index 6b9464eac..8af432d81 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeListVM.cs @@ -130,7 +130,7 @@ public override void AfterDoSearcher() Dictionary groupdata = new Dictionary(); if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").Result; + var dd = Wtm.CallAPI>("mainhost", "/api/_account/GetFrameworkGroups").GetAwaiter().GetResult(); if(dd.Data != null) { foreach (var item in dd.Data) diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs index aa3564868..e7ecde6ef 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/DataPrivilegeVMs/DataPrivilegeVM.cs @@ -77,7 +77,7 @@ public override void Validate() string user = null; if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById").Result; + var check = Wtm.CallAPI>("mainhost", "/api/_account/GetUserById").GetAwaiter().GetResult(); if (check.Data != null) { user = check.Data.Where(x => x.Value.ToString() == Entity.UserCode).Select(x => x.Value.ToString()).FirstOrDefault(); diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs index 30326329f..0a7a93357 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkGroupVMs/FrameworkGroupVM.cs @@ -34,13 +34,13 @@ public override void Validate() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveGroupCache(LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs index 3550ccff2..9602caa94 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkMenuVMs/FrameworkMenuVM2.cs @@ -269,7 +269,7 @@ public void AddPrivilege(List menuids) } } DC.SaveChanges(); - Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).Wait(); + Wtm.RemoveUserCacheByRole(SelectedRolesCodes.ToArray()).GetAwaiter().GetResult(); } diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs index b79eb180a..db256d4ad 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleMDVM2.cs @@ -24,7 +24,7 @@ protected override FrameworkRole GetById(object Id) { if (ConfigInfo.HasMainHost && Wtm.LoginUserInfo?.CurrentTenant == null) { - return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").Result.Data.Entity; + return Wtm.CallAPI("mainhost", $"/api/_frameworkrole/{Id}").GetAwaiter().GetResult().Data.Entity; } else { diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs index 8066549fb..64b22fff4 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkRoleVMs/FrameworkRoleVM.cs @@ -21,13 +21,13 @@ public override DuplicatedInfo SetDuplicatedCheck() public override void DoAdd() { base.DoAdd(); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override void DoEdit(bool updateAllFields = false) { base.DoEdit(updateAllFields); - Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).Wait(); + Wtm.RemoveRoleCache(Wtm.LoginUserInfo.CurrentTenant).GetAwaiter().GetResult(); } public override async Task DoDeleteAsync() diff --git a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs index 3b3ca2681..4620f5433 100644 --- a/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs +++ b/demo/WalkingTec.Mvvm.VueDemo/Areas/_Admin/ViewModels/FrameworkTenantVMs/FrameworkTenantVM.cs @@ -79,7 +79,7 @@ private void TenantOperation() if (tenantdc.Database.EnsureCreated() == true) { tenantdc.SetTenantCode(Entity.TCode); - tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).Wait(); + tenantdc.DataInit(Wtm.GlobaInfo.AllModule, Wtm.GlobaInfo.IsSpa).GetAwaiter().GetResult(); } AddTenantData(tenantdc, fps); } @@ -127,7 +127,7 @@ private void AddTenantData(IDataContext dc, List fps) } dc.SaveChanges(); var key = $"{GlobalConstants.CacheKey.UserInfo}:{"admin" + "$`$" + Entity.TCode}"; - Cache.DeleteAsync(key).Wait(); + Cache.DeleteAsync(key).GetAwaiter().GetResult(); } public override void DoDelete() { diff --git a/docs/plans/2026-03-03-complete-8.1.13-security.md b/docs/plans/2026-03-03-complete-8.1.13-security.md new file mode 100644 index 000000000..f065f8954 --- /dev/null +++ b/docs/plans/2026-03-03-complete-8.1.13-security.md @@ -0,0 +1,541 @@ +# Complete 8.1.13 Security Branch Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** 補完 feature/8.1.13-security 分支中已建好骨架但尚未接線的安全升級,使分支可正確編譯、測試通過,並準備合併進 dotnet8。 + +**Architecture:** 四處「接線」工作:(1) 登入邏輯改用 PBKDF2 驗證,(2) DataContext 補上 RefreshToken DbSet,(3) 刪除舊的重複 ITokenService,(4) 補上缺少的 DB 遷移 SQL 與 API 端點。 + +**Tech Stack:** ASP.NET Core 8, EF Core 8, Microsoft.AspNetCore.Identity (PasswordHasher), xUnit / MSTest + +--- + +## 完整缺口清單(執行前確認) + +| # | 缺口 | 嚴重度 | 影響檔案 | +|---|------|--------|---------| +| G1 | `FrameworkUser.Password` StringLength 仍為 32,存不進 PBKDF2 | CRITICAL | `Models/FrameworkUser.cs` | +| G2 | `DataContext` 缺少 `DbSet` | CRITICAL | `DataContext.cs` | +| G3 | 舊 `Support/ITokenService.cs` 未刪除,與新介面衝突 | CRITICAL | `Support/ITokenService.cs` | +| G4 | `WTMContext.DoLogin` 仍用 `Utils.GetMD5String` 做密碼比對 | CRITICAL | `WTMContext.cs:448` | +| G5 | 無 `/api/_account/refresh` 和 `/api/_account/revoke` API 端點 | HIGH | `_FrameworkController.cs` 或新檔案 | +| G6 | MySQL/PostgreSQL/SQLite/Oracle 遷移 SQL 缺失 | HIGH | `db-migration-8.1.13.sql` | +| G7 | 測試中 `Assert.AreEqual(data.Password, Utils.GetMD5String("password"))` 需更新 | MEDIUM | `test/` | +| G8 | `PasswordHashHelper` 和 `RefreshToken` 無單元測試 | MEDIUM | `test/` | +| G9 | 過期 RefreshToken 無清理機制 | LOW | 可後續再做 | + +--- + +### Task 1: 修正 FrameworkUser.Password 欄位長度 [G1] + +**Files:** +- Modify: `src/WalkingTec.Mvvm.Core/Models/FrameworkUser.cs:26-29` + +**Step 1: 讀取現況** + +```csharp +// 現況(約 line 26-29) +[Display(Name = "_Admin.Password")] +[StringLength(32, ErrorMessage = "Validate.{0}stringmax{1}")] +public string Password { get; set; } +``` + +**Step 2: 修改欄位長度** + +將 `StringLength(32)` 改為 `StringLength(256)`: + +```csharp +[Display(Name = "_Admin.Password")] +[StringLength(256, ErrorMessage = "Validate.{0}stringmax{1}")] +public string Password { get; set; } +``` + +**Step 3: Commit** + +```bash +git add src/WalkingTec.Mvvm.Core/Models/FrameworkUser.cs +git commit -m "fix(model): increase Password column length from 32 to 256 for PBKDF2" +``` + +--- + +### Task 2: 在 DataContext 加入 RefreshTokenEntity DbSet [G2] + +**Files:** +- Modify: `src/WalkingTec.Mvvm.Core/DataContext.cs` (在現有 DbSet 區段結尾加入) + +**Step 1: 確認現有 DbSet 最後一行** + +```csharp +// DataContext.cs 約 line 35-50 +public DbSet BaseFrameworkMenus { get; set; } +// ... +public DbSet Elsa_WorkflowInstances { get; set; } +// ← 在此之後加入 +``` + +**Step 2: 加入 DbSet** + +在 `Elsa_WorkflowInstances` 那行之後加入: + +```csharp +public DbSet FrameworkRefreshTokens { get; set; } +``` + +**Step 3: Commit** + +```bash +git add src/WalkingTec.Mvvm.Core/DataContext.cs +git commit -m "feat(data): register RefreshTokenEntity DbSet in DataContext" +``` + +--- + +### Task 3: 刪除舊的重複 ITokenService [G3] + +**Files:** +- Delete: `src/WalkingTec.Mvvm.Core/Support/ITokenService.cs` +- Check: 確認所有 using `WalkingTec.Mvvm.Core.Support` 中對 ITokenService 的參照已移至 `WalkingTec.Mvvm.Core` + +**Step 1: 確認參照** + +搜尋所有使用舊介面的地方: +```bash +grep -rn "Core.Support.ITokenService\|Support.Json.ITokenService\|using.*Support.*Token" src/ --include="*.cs" +``` + +若無結果,直接刪除。若有,先更新 using 再刪。 + +**Step 2: 刪除舊檔案** + +```bash +git rm src/WalkingTec.Mvvm.Core/Support/ITokenService.cs +git commit -m "refactor: remove legacy ITokenService from Support namespace (replaced by Core.Auth)" +``` + +--- + +### Task 4: 接線 WTMContext.DoLogin 使用 PasswordHashHelper [G4] + +**Files:** +- Modify: `src/WalkingTec.Mvvm.Core/WTMContext.cs:430-476` + +**Step 1: 讀取現況** + +```csharp +// 現況 line 446-449 +else +{ + exist = BaseUserQuery.IgnoreQueryFilters().Any(x => + x.ITCode == username && + x.Password == Utils.GetMD5String(password) && + x.TenantCode == tenant && + x.IsValid == true); +} +``` + +**Step 2: 新實作邏輯** + +PBKDF2 驗證無法在 LINQ to SQL 中比對(因為 hash 含 salt),需先把 user 撈出來再在記憶體中驗證: + +```csharp +else +{ + var userRecord = BaseUserQuery.IgnoreQueryFilters() + .Where(x => x.ITCode == username && + x.TenantCode == tenant && + x.IsValid == true) + .Select(x => new { x.ITCode, x.Password }) + .FirstOrDefault(); + if (userRecord != null) + { + var verifyResult = PasswordHashHelper.VerifyPassword( + userRecord.Password, password); + if (verifyResult == PasswordVerifyResult.Failed) + { + exist = false; + } + else + { + exist = true; + // 自動升級:若為舊 MD5 hash,趁登入時重新 hash + if (verifyResult == PasswordVerifyResult.SuccessRehashNeeded) + { + var fullUser = BaseUserQuery.IgnoreQueryFilters() + .FirstOrDefault(x => x.ITCode == username && + x.TenantCode == tenant); + if (fullUser != null) + { + fullUser.Password = PasswordHashHelper.HashPassword(password); + DC.SaveChanges(); + } + } + } + } +} +``` + +**Step 3: Commit** + +```bash +git add src/WalkingTec.Mvvm.Core/WTMContext.cs +git commit -m "feat(auth): integrate PasswordHashHelper into DoLogin with auto-rehash on MD5 upgrade" +``` + +--- + +### Task 5: 加入 Refresh / Revoke Token API 端點 [G5] + +**Files:** +- Modify: `src/WalkingTec.Mvvm.Mvc/_FrameworkController.cs` + +**Step 1: 確認現有 RefreshToken 方法位置** + +```bash +grep -n "RefreshToken\|RevokeToken" src/WalkingTec.Mvvm.Mvc/_FrameworkController.cs +``` + +**Step 2: 加入 API 端點** + +在 `_FrameworkController.cs` 中找到 `/api/_account/loginjwt` 附近,新增: + +```csharp +[AllowAnonymous] +[HttpPost("api/_account/refreshtoken")] +public async Task RefreshToken([FromBody] RefreshTokenRequest req) +{ + if (string.IsNullOrEmpty(req?.RefreshToken)) + return BadRequest(new { message = "RefreshToken is required" }); + var ip = HttpContext.Connection.RemoteIpAddress?.ToString(); + var tokenService = HttpContext.RequestServices + .GetRequiredService(); + var token = await tokenService.RefreshTokenAsync(req.RefreshToken, ip); + if (token == null) + return Unauthorized(new { message = "Invalid or expired refresh token" }); + return Ok(token); +} + +[HttpPost("api/_account/revoketoken")] +public async Task RevokeToken([FromBody] RefreshTokenRequest req) +{ + if (string.IsNullOrEmpty(req?.RefreshToken)) + return BadRequest(new { message = "RefreshToken is required" }); + var ip = HttpContext.Connection.RemoteIpAddress?.ToString(); + var tokenService = HttpContext.RequestServices + .GetRequiredService(); + await tokenService.RevokeTokenAsync(req.RefreshToken, ip); + return Ok(new { message = "Token revoked" }); +} +``` + +同檔案或在 Core 的 DTO 目錄下加: +```csharp +public class RefreshTokenRequest +{ + public string RefreshToken { get; set; } +} +``` + +**Step 3: Commit** + +```bash +git add src/WalkingTec.Mvvm.Mvc/_FrameworkController.cs +git commit -m "feat(api): add /api/_account/refreshtoken and /api/_account/revoketoken endpoints" +``` + +--- + +### Task 6: 補完多資料庫遷移 SQL [G6] + +**Files:** +- Modify: `db-migration-8.1.13.sql` + +**Step 1: 在現有 MSSQL 後追加各 DB 版本** + +```sql +-- ============================================================ +-- MySQL / MariaDB +-- ============================================================ +-- P0-1 +ALTER TABLE `FrameworkUser` MODIFY COLUMN `Password` VARCHAR(256) NOT NULL; +-- P0-2 +CREATE TABLE IF NOT EXISTS `FrameworkRefreshTokens` ( + `ID` CHAR(36) NOT NULL PRIMARY KEY, + `Token` VARCHAR(256) NOT NULL, + `ITCode` VARCHAR(50) NOT NULL, + `TenantCode` VARCHAR(50) NULL, + `ExpiresUtc` DATETIME(6) NOT NULL, + `CreatedUtc` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6), + `CreatedByIp` VARCHAR(50) NULL, + `RevokedUtc` DATETIME(6) NULL, + `RevokedByIp` VARCHAR(50) NULL, + `ReplacedByToken` VARCHAR(256) NULL, + `RevokeReason` VARCHAR(100) NULL +); +CREATE INDEX IX_RefreshToken_Token ON `FrameworkRefreshTokens`(`Token`); +CREATE INDEX IX_RefreshToken_ITCode ON `FrameworkRefreshTokens`(`ITCode`); + +-- ============================================================ +-- PostgreSQL +-- ============================================================ +-- P0-1 +ALTER TABLE "FrameworkUser" ALTER COLUMN "Password" TYPE VARCHAR(256); +-- P0-2 +CREATE TABLE IF NOT EXISTS "FrameworkRefreshTokens" ( + "ID" UUID NOT NULL PRIMARY KEY DEFAULT gen_random_uuid(), + "Token" VARCHAR(256) NOT NULL, + "ITCode" VARCHAR(50) NOT NULL, + "TenantCode" VARCHAR(50) NULL, + "ExpiresUtc" TIMESTAMPTZ NOT NULL, + "CreatedUtc" TIMESTAMPTZ NOT NULL DEFAULT NOW(), + "CreatedByIp" VARCHAR(50) NULL, + "RevokedUtc" TIMESTAMPTZ NULL, + "RevokedByIp" VARCHAR(50) NULL, + "ReplacedByToken" VARCHAR(256) NULL, + "RevokeReason" VARCHAR(100) NULL +); +CREATE INDEX IF NOT EXISTS IX_RefreshToken_Token ON "FrameworkRefreshTokens"("Token"); +CREATE INDEX IF NOT EXISTS IX_RefreshToken_ITCode ON "FrameworkRefreshTokens"("ITCode"); + +-- ============================================================ +-- SQLite (開發 / 測試用) +-- ============================================================ +-- P0-1: SQLite ALTER COLUMN 不支援直接修改,但 VARCHAR(256) 實際是 TEXT,無限制 +-- 若使用 EF Core migration 則無需手動處理 +-- P0-2 +CREATE TABLE IF NOT EXISTS "FrameworkRefreshTokens" ( + "ID" TEXT NOT NULL PRIMARY KEY, + "Token" TEXT NOT NULL, + "ITCode" TEXT NOT NULL, + "TenantCode" TEXT NULL, + "ExpiresUtc" TEXT NOT NULL, + "CreatedUtc" TEXT NOT NULL DEFAULT (datetime('now')), + "CreatedByIp" TEXT NULL, + "RevokedUtc" TEXT NULL, + "RevokedByIp" TEXT NULL, + "ReplacedByToken" TEXT NULL, + "RevokeReason" TEXT NULL +); +CREATE INDEX IF NOT EXISTS IX_RefreshToken_Token ON "FrameworkRefreshTokens"("Token"); +CREATE INDEX IF NOT EXISTS IX_RefreshToken_ITCode ON "FrameworkRefreshTokens"("ITCode"); + +-- ============================================================ +-- Oracle +-- ============================================================ +-- P0-1 +ALTER TABLE "FrameworkUser" MODIFY "Password" NVARCHAR2(256) NOT NULL; +-- P0-2 +CREATE TABLE "FrameworkRefreshTokens" ( + "ID" RAW(16) DEFAULT SYS_GUID() NOT NULL PRIMARY KEY, + "Token" NVARCHAR2(256) NOT NULL, + "ITCode" NVARCHAR2(50) NOT NULL, + "TenantCode" NVARCHAR2(50) NULL, + "ExpiresUtc" TIMESTAMP NOT NULL, + "CreatedUtc" TIMESTAMP DEFAULT SYSTIMESTAMP NOT NULL, + "CreatedByIp" NVARCHAR2(50) NULL, + "RevokedUtc" TIMESTAMP NULL, + "RevokedByIp" NVARCHAR2(50) NULL, + "ReplacedByToken" NVARCHAR2(256) NULL, + "RevokeReason" NVARCHAR2(100) NULL +); +CREATE INDEX IX_RefreshToken_Token ON "FrameworkRefreshTokens"("Token"); +CREATE INDEX IX_RefreshToken_ITCode ON "FrameworkRefreshTokens"("ITCode"); +``` + +**Step 2: Commit** + +```bash +git add db-migration-8.1.13.sql +git commit -m "docs: add MySQL/PostgreSQL/SQLite/Oracle migration scripts for v8.1.13" +``` + +--- + +### Task 7: 更新現有測試斷言 [G7] + +**Files:** +- Modify: `test/WalkingTec.Mvvm.Admin.Test/FrameworkUserApiTest.cs:53` +- Modify: `test/WalkingTec.Mvvm.Admin.Test/FrameworkUserControllerTest.cs:66` + +**Step 1: 找到所有 MD5 斷言** + +```bash +grep -n "GetMD5String\|Utils.GetMD5" test/ -r --include="*.cs" +``` + +**Step 2: 替換斷言** + +PBKDF2 hash 每次不同,不能直接比對字串,改為用 PasswordHashHelper.VerifyPassword 驗證: + +將: +```csharp +Assert.AreEqual(data.Password, Utils.GetMD5String("password")); +``` +改為: +```csharp +var verifyResult = PasswordHashHelper.VerifyPassword(data.Password, "password"); +Assert.AreNotEqual(PasswordVerifyResult.Failed, verifyResult); +``` + +**Step 3: Commit** + +```bash +git add test/ +git commit -m "test: update password assertions to use PasswordHashHelper.VerifyPassword" +``` + +--- + +### Task 8: 新增 PasswordHashHelper 單元測試 [G8] + +**Files:** +- Create: `test/WalkingTec.Mvvm.Core.Test/PasswordHashHelperTest.cs` + +**Step 1: 建立測試檔案** + +```csharp +using Microsoft.VisualStudio.TestTools.UnitTesting; +using WalkingTec.Mvvm.Core; + +namespace WalkingTec.Mvvm.Core.Test +{ + [TestClass] + public class PasswordHashHelperTest + { + [TestMethod] + public void HashPassword_ReturnsNonMd5Format() + { + var hash = PasswordHashHelper.HashPassword("test123"); + Assert.IsFalse(PasswordHashHelper.IsLegacyMD5Hash(hash)); + Assert.IsTrue(hash.Length > 32); + } + + [TestMethod] + public void VerifyPassword_WithPbkdf2_ReturnsSuccess() + { + var hash = PasswordHashHelper.HashPassword("mypassword"); + var result = PasswordHashHelper.VerifyPassword(hash, "mypassword"); + Assert.AreEqual(PasswordVerifyResult.Success, result); + } + + [TestMethod] + public void VerifyPassword_WithWrongPassword_ReturnsFailed() + { + var hash = PasswordHashHelper.HashPassword("mypassword"); + var result = PasswordHashHelper.VerifyPassword(hash, "wrongpassword"); + Assert.AreEqual(PasswordVerifyResult.Failed, result); + } + + [TestMethod] + public void VerifyPassword_WithLegacyMD5_ReturnsSuccessRehashNeeded() + { + // 模擬舊系統的 MD5 hash + var md5Hash = PasswordHashHelper.ComputeMD5("legacypassword"); + var result = PasswordHashHelper.VerifyPassword(md5Hash, "legacypassword"); + Assert.AreEqual(PasswordVerifyResult.SuccessRehashNeeded, result); + } + + [TestMethod] + public void VerifyPassword_WithLegacyMD5_WrongPassword_ReturnsFailed() + { + var md5Hash = PasswordHashHelper.ComputeMD5("legacypassword"); + var result = PasswordHashHelper.VerifyPassword(md5Hash, "wrong"); + Assert.AreEqual(PasswordVerifyResult.Failed, result); + } + + [TestMethod] + public void IsLegacyMD5Hash_ValidMd5_ReturnsTrue() + { + var md5 = PasswordHashHelper.ComputeMD5("test"); + Assert.IsTrue(PasswordHashHelper.IsLegacyMD5Hash(md5)); + } + + [TestMethod] + public void HashPassword_EmptyString_ReturnsEmpty() + { + var hash = PasswordHashHelper.HashPassword(string.Empty); + Assert.AreEqual(string.Empty, hash); + } + } +} +``` + +注意:`ComputeMD5` 目前是 `internal`,需改為 `public` 或 `internal` + `InternalsVisibleTo`。 + +若不想改可見度,可直接用 `Utils.GetMD5String` 計算 MD5 值。 + +**Step 2: Commit** + +```bash +git add test/WalkingTec.Mvvm.Core.Test/PasswordHashHelperTest.cs +git commit -m "test: add unit tests for PasswordHashHelper (PBKDF2 + MD5 migration)" +``` + +--- + +### Task 9: 更新 CHANGELOG 與版本號,準備合併 [最終] + +**Files:** +- Modify: `CHANGELOG.md` +- Modify: `version.props` + +**Step 1: 更新 CHANGELOG** + +在 `## v8.x.x` 區段最上方加入: + +```markdown +## 8.1.13 (2026-03-xx) + +* **安全:** 密碼儲存從 MD5 升級至 PBKDF2(ASP.NET Core Identity PasswordHasher),自動向下相容舊 MD5 帳號 +* **安全:** JWT 新增 Refresh Token 機制,支援 Token Rotation 防止重複使用 +* **依賴:** DotNetCore.NPOI 1.2.3 → NPOI 2.7.6 +* **依賴:** 移除 .NET Core 2.1.x 舊依賴套件 +* **CI:** 新增 GitHub Actions 建置、測試與弱點掃描工作流 +* **Breaking Change:** FrameworkUser.Password 欄位由 32 字元擴展為 256 字元,**部署前必須執行 db-migration-8.1.13.sql** +``` + +**Step 2: 更新版本號** + +`version.props` 的 `VersionPrefix` 從 `8.1.12` 改為 `8.1.13`。 + +**Step 3: 最終 Commit** + +```bash +git add CHANGELOG.md version.props +git commit -m "chore: bump version to 8.1.13, update CHANGELOG" +``` + +--- + +### Task 10: PR 到 dotnet8 + +```bash +git push origin feature/8.1.13-security +``` + +在 GitHub 上建立 PR: +- base: `dotnet8` +- compare: `feature/8.1.13-security` +- Title: `feat(security): v8.1.13 - PBKDF2 password hashing + JWT refresh token rotation` +- 描述中標注 Breaking Change 並連結 `db-migration-8.1.13.sql` + +--- + +## 執行順序依賴 + +``` +Task 1 (FrameworkUser StringLength) +Task 2 (DataContext DbSet) → 這兩個可並行 +Task 3 (刪除舊 ITokenService) + ↓ +Task 4 (DoLogin 接線) ← 依賴 Task 1, 2, 3 完成 + ↓ +Task 5 (API 端點) ← 可與 Task 6, 7, 8 並行 +Task 6 (多 DB 遷移 SQL) ← 獨立 +Task 7 (測試斷言) ← 依賴 Task 4 +Task 8 (新單元測試) ← 獨立 + ↓ +Task 9 (版本號 + CHANGELOG) + ↓ +Task 10 (PR) +``` diff --git a/docs/plans/2026-03-04-8.1.14-stabilize.md b/docs/plans/2026-03-04-8.1.14-stabilize.md new file mode 100644 index 000000000..036505cb6 --- /dev/null +++ b/docs/plans/2026-03-04-8.1.14-stabilize.md @@ -0,0 +1,149 @@ +# WTM 8.1.14 Stabilization Implementation Plan + +> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. + +**Goal:** Complete remaining 5 tasks of 8.1.14 stabilization cycle (ASYNC-1 already done). + +**Architecture:** Sequential file edits across .csproj, new .editorconfig, new test project, CI workflow update. No runtime changes — pure build/config. + +**Tech Stack:** .NET 8.0, EF Core 8, xUnit, FluentAssertions, GitHub Actions + +--- + +## Prerequisite Status +- [x] ASYNC-1: Eliminate sync-over-async (DONE, commit 7772fec6) +- [ ] DEPS-1: Dependency audit & update (Issue #9) +- [ ] QUALITY-1: .editorconfig (Issue #10) +- [ ] QUALITY-2: Nullable Reference Types in Core (Issue #10) +- [ ] TEST-1: Unit test project (Issue #11) +- [ ] CI-UPDATE: Add test result artifact upload + +--- + +## Task 1: DEPS-1 — Dependency Audit & Update + +**Files:** +- Modify: `src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj` +- Modify: `src/WalkingTec.Mvvm.Mvc/WalkingTec.Mvvm.Mvc.csproj` + +**Version upgrade table (within same major only):** + +| Package | Current | Target | +|---------|---------|--------| +| Microsoft.EntityFrameworkCore.* (all 4) | 8.0.3 | 8.0.22 | +| Microsoft.Extensions.Identity.Core | 8.0.3 | 8.0.22 | +| Microsoft.Extensions.Localization | 8.0.3 | 8.0.22 | +| Microsoft.Extensions.Hosting.Abstractions | 8.0.0 | 8.0.1 | +| Microsoft.Extensions.Http | 8.0.0 | 8.0.1 | +| Microsoft.Extensions.Logging.Configuration | 8.0.0 | 8.0.1 | +| Microsoft.Extensions.Logging.Console | 8.0.0 | 8.0.1 | +| Microsoft.Extensions.Logging.Debug | 8.0.0 | 8.0.1 | +| Microsoft.Extensions.Configuration.Json | 8.0.0 | 8.0.1 | +| Microsoft.Extensions.Configuration.EnvironmentVariables | 8.0.0 | 8.0.1 | +| Microsoft.AspNetCore.Authorization | 8.0.3 | 8.0.22 | +| Microsoft.AspNetCore.Authentication.JwtBearer | 8.0.3 | 8.0.22 | +| Microsoft.AspNetCore.DataProtection | 8.0.3 | 8.0.22 | +| Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation | 8.0.3 | 8.0.22 | +| Microsoft.AspNetCore.SpaServices.Extensions | 8.0.3 | 8.0.22 | +| Npgsql.EntityFrameworkCore.PostgreSQL | 8.0.2 | 8.0.11 | +| Oracle.EntityFrameworkCore | 8.21.121 | 8.23.70 | +| Pomelo.EntityFrameworkCore.MySql | 8.0.2 | 8.0.3 | +| Quartz | 3.8.1 | 3.16.0 | +| Elsa.Server.Core + all Elsa.* | 2.14.1 | 2.15.2 | +| Swashbuckle.AspNetCore.* (3 packages) | 6.5.0 | 6.6.2 | + +**Leave unchanged:** NPOI 2.7.6, Aliyun.OSS.SDK.NetCore 2.13.0, Fare 2.2.1, System.Runtime.Loader 4.3.0, Microsoft.AspNetCore.Http 2.1.34 (legacy compat ref), DUWENINK.Captcha 0.7.0, VueCliMiddleware 6.0.0 + +**Commit message:** +``` +fix(deps): upgrade packages to latest stable within major versions [DEPS-1] + +EF Core: 8.0.3 → 8.0.22 +Microsoft.AspNetCore.*: 8.0.3 → 8.0.22 +Microsoft.Extensions.*: 8.0.0 → 8.0.1 +Npgsql: 8.0.2 → 8.0.11 +Oracle.EF: 8.21.121 → 8.23.70 +Pomelo: 8.0.2 → 8.0.3 +Quartz: 3.8.1 → 3.16.0 +Elsa 2.x: 2.14.1 → 2.15.2 +Swashbuckle: 6.5.0 → 6.6.2 +No major version boundary crossings. + +Closes #9 +``` + +--- + +## Task 2: QUALITY-1 — Add .editorconfig + +**Files:** +- Create: `.editorconfig` (repo root) + +Content per spec (verbatim from WTM-8.1.14-SPEC.md). + +**Commit message:** +``` +chore: add .editorconfig with C# coding standards [QUALITY-1] + +Part of #10 +``` + +--- + +## Task 3: QUALITY-2 — Enable Nullable Reference Types in Core + +**Files:** +- Modify: `src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj` +- Scan & suppress: any Core .cs files with >50 nullable warnings + +**Steps:** +1. Add `enable` to Core.csproj +2. Scan all Core .cs files for nullable issues +3. Fix Tier-1 security-critical files (PasswordHashHelper, RefreshTokenEntity, ITokenService) +4. Add `#nullable disable` to legacy files with high warning counts + +**Commit message:** +``` +chore: enable Nullable Reference Types in Core project [QUALITY-2] + +Closes #10 +``` + +--- + +## Task 4: TEST-1 — Unit Test Project + +**Files:** +- Create: `src/WalkingTec.Mvvm.Core.Tests/WalkingTec.Mvvm.Core.Tests.csproj` +- Create: `src/WalkingTec.Mvvm.Core.Tests/PasswordHashHelperTests.cs` +- Create: `src/WalkingTec.Mvvm.Core.Tests/RefreshTokenEntityTests.cs` +- Modify: `WalkingTec.Mvvm.sln` (add test project) +- Modify: `src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj` (add InternalsVisibleTo) + +**Commit message:** +``` +test: add unit test project with security-critical baseline tests [TEST-1] + +Closes #11 +``` + +--- + +## Task 5: CI-UPDATE — Add Test Result Artifacts + +**Files:** +- Modify: `.github/workflows/ci-build.yml` + +**Commit message:** +``` +ci: upload test result artifacts in CI workflow [CI-UPDATE] +``` + +--- + +## Final Steps (after CI passes — DO NOT AUTO-MERGE) +```bash +git push origin feature/8.1.14-stabilize +gh pr create --base dotnet8 --title "v8.1.14: Stabilization — deps, quality, tests" ... +# Wait for owner confirmation before merge +``` diff --git a/src/WalkingTec.Mvvm.Core.Tests/PasswordHashHelperTests.cs b/src/WalkingTec.Mvvm.Core.Tests/PasswordHashHelperTests.cs new file mode 100644 index 000000000..468604f28 --- /dev/null +++ b/src/WalkingTec.Mvvm.Core.Tests/PasswordHashHelperTests.cs @@ -0,0 +1,122 @@ +using FluentAssertions; +using WalkingTec.Mvvm.Core; +using Xunit; + +namespace WalkingTec.Mvvm.Core.Tests +{ + public class PasswordHashHelperTests + { + [Fact] + public void HashPassword_ReturnsNonEmptyString() + { + var hash = PasswordHashHelper.HashPassword("test123"); + hash.Should().NotBeNullOrEmpty(); + hash.Should().NotBe("test123"); + } + + [Fact] + public void HashPassword_EmptyInput_ReturnsEmpty() + { + PasswordHashHelper.HashPassword("").Should().BeEmpty(); + PasswordHashHelper.HashPassword(null).Should().BeEmpty(); + } + + [Fact] + public void HashPassword_DifferentCalls_ProduceDifferentHashes() + { + var hash1 = PasswordHashHelper.HashPassword("test123"); + var hash2 = PasswordHashHelper.HashPassword("test123"); + hash1.Should().NotBe(hash2, "PBKDF2 uses random salt"); + } + + [Fact] + public void VerifyPassword_CorrectPassword_ReturnsSuccess() + { + var hash = PasswordHashHelper.HashPassword("myPassword"); + var result = PasswordHashHelper.VerifyPassword(hash, "myPassword"); + result.Should().Be(PasswordVerifyResult.Success); + } + + [Fact] + public void VerifyPassword_WrongPassword_ReturnsFailed() + { + var hash = PasswordHashHelper.HashPassword("myPassword"); + var result = PasswordHashHelper.VerifyPassword(hash, "wrongPassword"); + result.Should().Be(PasswordVerifyResult.Failed); + } + + [Fact] + public void VerifyPassword_NullInputs_ReturnsFailed() + { + PasswordHashHelper.VerifyPassword(null, "pw") + .Should().Be(PasswordVerifyResult.Failed); + PasswordHashHelper.VerifyPassword("hash", null) + .Should().Be(PasswordVerifyResult.Failed); + PasswordHashHelper.VerifyPassword(null, null) + .Should().Be(PasswordVerifyResult.Failed); + } + + [Fact] + public void VerifyPassword_LegacyMD5_ReturnsSuccessRehashNeeded() + { + var md5Hash = PasswordHashHelper.ComputeMD5("000000"); + var result = PasswordHashHelper.VerifyPassword(md5Hash, "000000"); + result.Should().Be(PasswordVerifyResult.SuccessRehashNeeded); + } + + [Fact] + public void VerifyPassword_LegacyMD5_WrongPassword_ReturnsFailed() + { + var md5Hash = PasswordHashHelper.ComputeMD5("000000"); + var result = PasswordHashHelper.VerifyPassword(md5Hash, "111111"); + result.Should().Be(PasswordVerifyResult.Failed); + } + + [Fact] + public void IsLegacyMD5Hash_ValidMD5_ReturnsTrue() + { + PasswordHashHelper.IsLegacyMD5Hash("670B14728AD9902AECBA32E22FA4F6BD") + .Should().BeTrue(); + } + + [Fact] + public void IsLegacyMD5Hash_PBKDF2Hash_ReturnsFalse() + { + var pbkdf2 = PasswordHashHelper.HashPassword("test"); + PasswordHashHelper.IsLegacyMD5Hash(pbkdf2).Should().BeFalse(); + } + + [Fact] + public void IsLegacyMD5Hash_NullOrEmpty_ReturnsFalse() + { + PasswordHashHelper.IsLegacyMD5Hash(null).Should().BeFalse(); + PasswordHashHelper.IsLegacyMD5Hash("").Should().BeFalse(); + } + + [Fact] + public void IsLegacyMD5Hash_WrongLength_ReturnsFalse() + { + PasswordHashHelper.IsLegacyMD5Hash("ABC123").Should().BeFalse(); + } + + [Fact] + public void MigrationFlow_MD5ToNewHash_Verify_Success() + { + // Simulate: user had MD5 password, logs in, system upgrades + var legacyMD5 = PasswordHashHelper.ComputeMD5("secretPassword"); + + // Step 1: Verify against legacy hash + var verifyResult = PasswordHashHelper.VerifyPassword( + legacyMD5, "secretPassword"); + verifyResult.Should().Be(PasswordVerifyResult.SuccessRehashNeeded); + + // Step 2: Generate new PBKDF2 hash + var newHash = PasswordHashHelper.HashPassword("secretPassword"); + + // Step 3: Verify against new hash + var verifyNew = PasswordHashHelper.VerifyPassword( + newHash, "secretPassword"); + verifyNew.Should().Be(PasswordVerifyResult.Success); + } + } +} diff --git a/src/WalkingTec.Mvvm.Core.Tests/RefreshTokenEntityTests.cs b/src/WalkingTec.Mvvm.Core.Tests/RefreshTokenEntityTests.cs new file mode 100644 index 000000000..c8bd98839 --- /dev/null +++ b/src/WalkingTec.Mvvm.Core.Tests/RefreshTokenEntityTests.cs @@ -0,0 +1,67 @@ +using System; +using FluentAssertions; +using WalkingTec.Mvvm.Core; +using Xunit; + +namespace WalkingTec.Mvvm.Core.Tests +{ + public class RefreshTokenEntityTests + { + [Fact] + public void NewToken_IsActive() + { + var token = new RefreshTokenEntity + { + Token = "test-token", + ITCode = "admin", + ExpiresUtc = DateTime.UtcNow.AddDays(7) + }; + token.IsActive.Should().BeTrue(); + token.IsExpired.Should().BeFalse(); + token.IsRevoked.Should().BeFalse(); + } + + [Fact] + public void ExpiredToken_IsNotActive() + { + var token = new RefreshTokenEntity + { + Token = "test-token", + ITCode = "admin", + ExpiresUtc = DateTime.UtcNow.AddMinutes(-1) + }; + token.IsActive.Should().BeFalse(); + token.IsExpired.Should().BeTrue(); + } + + [Fact] + public void RevokedToken_IsNotActive() + { + var token = new RefreshTokenEntity + { + Token = "test-token", + ITCode = "admin", + ExpiresUtc = DateTime.UtcNow.AddDays(7), + RevokedUtc = DateTime.UtcNow + }; + token.IsActive.Should().BeFalse(); + token.IsRevoked.Should().BeTrue(); + } + + [Fact] + public void NewToken_HasGeneratedID() + { + var token = new RefreshTokenEntity(); + token.ID.Should().NotBe(Guid.Empty); + } + + [Fact] + public void NewToken_HasCreatedUtcSet() + { + var before = DateTime.UtcNow.AddSeconds(-1); + var token = new RefreshTokenEntity(); + var after = DateTime.UtcNow.AddSeconds(1); + token.CreatedUtc.Should().BeAfter(before).And.BeBefore(after); + } + } +} diff --git a/src/WalkingTec.Mvvm.Core.Tests/WalkingTec.Mvvm.Core.Tests.csproj b/src/WalkingTec.Mvvm.Core.Tests/WalkingTec.Mvvm.Core.Tests.csproj new file mode 100644 index 000000000..6b58d228c --- /dev/null +++ b/src/WalkingTec.Mvvm.Core.Tests/WalkingTec.Mvvm.Core.Tests.csproj @@ -0,0 +1,26 @@ + + + + net8.0 + enable + false + true + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + diff --git a/src/WalkingTec.Mvvm.Core/Attributes/ActionDescriptionAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/ActionDescriptionAttribute.cs index ee3a209aa..2d3d83c43 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/ActionDescriptionAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/ActionDescriptionAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Linq; using Microsoft.Extensions.Localization; diff --git a/src/WalkingTec.Mvvm.Core/Attributes/AllRightsAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/AllRightsAttribute.cs index 52d5a9ae4..79b652f07 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/AllRightsAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/AllRightsAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Attributes/CanNotEditAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/CanNotEditAttribute.cs index f30198f56..c30e48bf7 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/CanNotEditAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/CanNotEditAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Attributes/DebugOnlyAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/DebugOnlyAttribute.cs index 21083f808..bdb821bd9 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/DebugOnlyAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/DebugOnlyAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Attributes/FixConnectionAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/FixConnectionAttribute.cs index 25c13c51f..6795c1414 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/FixConnectionAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/FixConnectionAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Attributes/MainTenantOnly.cs b/src/WalkingTec.Mvvm.Core/Attributes/MainTenantOnly.cs index c6e40987c..4074ec047 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/MainTenantOnly.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/MainTenantOnly.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using Microsoft.AspNetCore.Authorization; diff --git a/src/WalkingTec.Mvvm.Core/Attributes/MiddleTableAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/MiddleTableAttribute.cs index 71ec40b45..ea0f6e4e4 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/MiddleTableAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/MiddleTableAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Attributes/NoLogAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/NoLogAttribute.cs index 8e9aa1776..64d6664da 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/NoLogAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/NoLogAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Attributes/PublicAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/PublicAttribute.cs index c69573748..9feb406a0 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/PublicAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/PublicAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using Microsoft.AspNetCore.Authorization; diff --git a/src/WalkingTec.Mvvm.Core/Attributes/ReInitAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/ReInitAttribute.cs index 16f1a1c24..727419d86 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/ReInitAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/ReInitAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Attributes/SoftFKAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/SoftFKAttribute.cs index f4fb6d8e2..41eacf5a4 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/SoftFKAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/SoftFKAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Attributes/SoftKeyAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/SoftKeyAttribute.cs index a97cc4fc9..75a70b530 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/SoftKeyAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/SoftKeyAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Attributes/ValidateFormItemOnlyAttribute.cs b/src/WalkingTec.Mvvm.Core/Attributes/ValidateFormItemOnlyAttribute.cs index ef48eecce..46b377d82 100644 --- a/src/WalkingTec.Mvvm.Core/Attributes/ValidateFormItemOnlyAttribute.cs +++ b/src/WalkingTec.Mvvm.Core/Attributes/ValidateFormItemOnlyAttribute.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Auth/ITokenService.cs b/src/WalkingTec.Mvvm.Core/Auth/ITokenService.cs index fe6e1f2e8..fd06bbef8 100644 --- a/src/WalkingTec.Mvvm.Core/Auth/ITokenService.cs +++ b/src/WalkingTec.Mvvm.Core/Auth/ITokenService.cs @@ -6,10 +6,10 @@ namespace WalkingTec.Mvvm.Core public interface ITokenService { Task IssueTokenAsync(LoginUserInfo loginUserInfo, - string ipAddress = null); + string? ipAddress = null); Task RefreshTokenAsync(string refreshToken, - string ipAddress = null); + string? ipAddress = null); Task RevokeTokenAsync(string refreshToken, - string ipAddress = null, string reason = null); + string? ipAddress = null, string? reason = null); } } diff --git a/src/WalkingTec.Mvvm.Core/BaseBatchVM.cs b/src/WalkingTec.Mvvm.Core/BaseBatchVM.cs index e91dd8f4b..4809df9a2 100644 --- a/src/WalkingTec.Mvvm.Core/BaseBatchVM.cs +++ b/src/WalkingTec.Mvvm.Core/BaseBatchVM.cs @@ -1,3 +1,4 @@ +#nullable disable using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Primitives; diff --git a/src/WalkingTec.Mvvm.Core/BaseCRUDVM.cs b/src/WalkingTec.Mvvm.Core/BaseCRUDVM.cs index d5566ffcd..c190d2e83 100644 --- a/src/WalkingTec.Mvvm.Core/BaseCRUDVM.cs +++ b/src/WalkingTec.Mvvm.Core/BaseCRUDVM.cs @@ -1,3 +1,4 @@ +#nullable disable using Elsa.Models; using Elsa.Persistence.Specifications; using Elsa.Persistence; diff --git a/src/WalkingTec.Mvvm.Core/BaseImportVM.cs b/src/WalkingTec.Mvvm.Core/BaseImportVM.cs index 91fe5c9b5..da343b16d 100644 --- a/src/WalkingTec.Mvvm.Core/BaseImportVM.cs +++ b/src/WalkingTec.Mvvm.Core/BaseImportVM.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections; using System.Collections.Generic; diff --git a/src/WalkingTec.Mvvm.Core/BasePagedListVM.cs b/src/WalkingTec.Mvvm.Core/BasePagedListVM.cs index 710e01728..5b07f62a9 100644 --- a/src/WalkingTec.Mvvm.Core/BasePagedListVM.cs +++ b/src/WalkingTec.Mvvm.Core/BasePagedListVM.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/WalkingTec.Mvvm.Core/BaseSearcher.cs b/src/WalkingTec.Mvvm.Core/BaseSearcher.cs index b5ba52977..27c51c593 100644 --- a/src/WalkingTec.Mvvm.Core/BaseSearcher.cs +++ b/src/WalkingTec.Mvvm.Core/BaseSearcher.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/BaseTemplateVM.cs b/src/WalkingTec.Mvvm.Core/BaseTemplateVM.cs index bd409ec39..e809d90b0 100644 --- a/src/WalkingTec.Mvvm.Core/BaseTemplateVM.cs +++ b/src/WalkingTec.Mvvm.Core/BaseTemplateVM.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/BaseVM.cs b/src/WalkingTec.Mvvm.Core/BaseVM.cs index f691a3510..2438b4def 100644 --- a/src/WalkingTec.Mvvm.Core/BaseVM.cs +++ b/src/WalkingTec.Mvvm.Core/BaseVM.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/CS.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/CS.cs index 98143fb53..26454a53e 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/CS.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/CS.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/Configs.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/Configs.cs index 70d21226b..ef29166d7 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/Configs.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/Configs.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Globalization; diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/CookieOptions.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/CookieOptions.cs index 2b54df0b4..748c8e36a 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/CookieOptions.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/CookieOptions.cs @@ -1,3 +1,4 @@ +#nullable disable namespace WalkingTec.Mvvm.Core { diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/Cors.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/Cors.cs index c8b2c1829..cbb7be7db 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/Cors.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/Cors.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/DFS.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/DFS.cs index c48c11d28..08dc48fdc 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/DFS.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/DFS.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/DFSTracker.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/DFSTracker.cs index b066df2c2..fc694fa65 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/DFSTracker.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/DFSTracker.cs @@ -1,3 +1,4 @@ +#nullable disable namespace WalkingTec.Mvvm.Core { /// diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/DefaultConfigConsts.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/DefaultConfigConsts.cs index 48460607c..3a1faeead 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/DefaultConfigConsts.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/DefaultConfigConsts.cs @@ -1,3 +1,4 @@ +#nullable disable namespace WalkingTec.Mvvm.Core.ConfigOptions { /// diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/Domain.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/Domain.cs index 0136a870a..0083f6ba2 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/Domain.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/Domain.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/FileUploadOptions.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/FileUploadOptions.cs index 552859ac4..79bf7dfdd 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/FileUploadOptions.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/FileUploadOptions.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; namespace WalkingTec.Mvvm.Core.ConfigOptions diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/JwtOptions.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/JwtOptions.cs index 1fa155e7f..0aa22f6d8 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/JwtOptions.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/JwtOptions.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Text; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/KV.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/KV.cs index a62d27ca2..2b5185de9 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/KV.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/KV.cs @@ -1,3 +1,4 @@ +#nullable disable namespace WalkingTec.Mvvm.Core { /// diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/UEditorOptions.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/UEditorOptions.cs index 230815b66..32ffa4c59 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/UEditorOptions.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/UEditorOptions.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Text.Json.Serialization; diff --git a/src/WalkingTec.Mvvm.Core/ConfigOptions/UIOptions.cs b/src/WalkingTec.Mvvm.Core/ConfigOptions/UIOptions.cs index 7766e5a12..cfbefc4f3 100644 --- a/src/WalkingTec.Mvvm.Core/ConfigOptions/UIOptions.cs +++ b/src/WalkingTec.Mvvm.Core/ConfigOptions/UIOptions.cs @@ -1,3 +1,4 @@ +#nullable disable namespace WalkingTec.Mvvm.Core.ConfigOptions { public class UIOptions diff --git a/src/WalkingTec.Mvvm.Core/CoreProgram.cs b/src/WalkingTec.Mvvm.Core/CoreProgram.cs index e46bb30cc..a38486b5c 100644 --- a/src/WalkingTec.Mvvm.Core/CoreProgram.cs +++ b/src/WalkingTec.Mvvm.Core/CoreProgram.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Text.Json; using Microsoft.Extensions.Localization; using Microsoft.Extensions.Options; diff --git a/src/WalkingTec.Mvvm.Core/DataContext.cs b/src/WalkingTec.Mvvm.Core/DataContext.cs index 478845bf6..e73ef4f6c 100644 --- a/src/WalkingTec.Mvvm.Core/DataContext.cs +++ b/src/WalkingTec.Mvvm.Core/DataContext.cs @@ -1,3 +1,4 @@ +#nullable disable using Microsoft.Data.SqlClient; using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; diff --git a/src/WalkingTec.Mvvm.Core/Enums.cs b/src/WalkingTec.Mvvm.Core/Enums.cs index c9c0e53ce..c54377e4c 100644 --- a/src/WalkingTec.Mvvm.Core/Enums.cs +++ b/src/WalkingTec.Mvvm.Core/Enums.cs @@ -1,3 +1,4 @@ +#nullable disable using System.ComponentModel.DataAnnotations; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Exceptions/NullOrEmptyStringException.cs b/src/WalkingTec.Mvvm.Core/Exceptions/NullOrEmptyStringException.cs index 4d0f7f3c8..f67af3d8b 100644 --- a/src/WalkingTec.Mvvm.Core/Exceptions/NullOrEmptyStringException.cs +++ b/src/WalkingTec.Mvvm.Core/Exceptions/NullOrEmptyStringException.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Runtime.Serialization; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/ConfigExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/ConfigExtension.cs index 8b0b915c6..fbe79ee34 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/ConfigExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/ConfigExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.IO; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/DCExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/DCExtension.cs index 169bb94bb..78629dfd3 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/DCExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/DCExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections; using System.Collections.Generic; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/DistinctExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/DistinctExtension.cs index 9aba5fe68..dbb5c8d2b 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/DistinctExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/DistinctExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/ITreeDataExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/ITreeDataExtension.cs index 1cc91d6a6..a4af0b864 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/ITreeDataExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/ITreeDataExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/ListExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/ListExtension.cs index 51141d45c..1e1f0faa4 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/ListExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/ListExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/ListVMExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/ListVMExtension.cs index 034d1efc1..bcf98e7eb 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/ListVMExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/ListVMExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/LoginUserInfoExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/LoginUserInfoExtension.cs index 5b90d9faa..8e5b48cea 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/LoginUserInfoExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/LoginUserInfoExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/MenuExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/MenuExtension.cs index 6d84ceae3..99e728c36 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/MenuExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/MenuExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/PagedListExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/PagedListExtension.cs index 28cb96a7e..230c636d2 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/PagedListExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/PagedListExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Linq.Expressions; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DateTimeHelper.cs b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DateTimeHelper.cs index 584e350e2..4faba1a63 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DateTimeHelper.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DateTimeHelper.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core.Extensions diff --git a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DictionaryExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DictionaryExtension.cs index 5b68f48ca..e4647d1cd 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DictionaryExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DictionaryExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DistributedCacheExtensions.cs b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DistributedCacheExtensions.cs index badc204a8..93f6a9fba 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DistributedCacheExtensions.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/DistributedCacheExtensions.cs @@ -1,3 +1,4 @@ +#nullable disable // // DistributedCacheExtensions.cs // diff --git a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/EnumExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/EnumExtension.cs index a28cde8b0..dd383f64c 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/EnumExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/EnumExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections; using System.Collections.Generic; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/StringExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/StringExtension.cs index 3cae1b680..eec096598 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/StringExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/StringExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections; using System.Collections.Generic; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/SystemExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/SystemExtension.cs index d38ce8a1a..9a1bffe62 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/SystemExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/SystemExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Reflection; diff --git a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/TypeExtension.cs b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/TypeExtension.cs index 71fffc300..f8ddaabf3 100644 --- a/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/TypeExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Extensions/SystemExtensions/TypeExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Collections.Immutable; diff --git a/src/WalkingTec.Mvvm.Core/GlobalConstants.cs b/src/WalkingTec.Mvvm.Core/GlobalConstants.cs index f6dee6e5b..5aa215255 100644 --- a/src/WalkingTec.Mvvm.Core/GlobalConstants.cs +++ b/src/WalkingTec.Mvvm.Core/GlobalConstants.cs @@ -1,3 +1,4 @@ +#nullable disable namespace WalkingTec.Mvvm.Core { public static class GlobalConstants diff --git a/src/WalkingTec.Mvvm.Core/GlobalData.cs b/src/WalkingTec.Mvvm.Core/GlobalData.cs index 1aa99bbd1..5850f18b7 100644 --- a/src/WalkingTec.Mvvm.Core/GlobalData.cs +++ b/src/WalkingTec.Mvvm.Core/GlobalData.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/GlobalServices.cs b/src/WalkingTec.Mvvm.Core/GlobalServices.cs index 39d0f50ff..351994426 100644 --- a/src/WalkingTec.Mvvm.Core/GlobalServices.cs +++ b/src/WalkingTec.Mvvm.Core/GlobalServices.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; diff --git a/src/WalkingTec.Mvvm.Core/Grid/GridAction.cs b/src/WalkingTec.Mvvm.Core/Grid/GridAction.cs index 9ec865d60..f19c2513e 100644 --- a/src/WalkingTec.Mvvm.Core/Grid/GridAction.cs +++ b/src/WalkingTec.Mvvm.Core/Grid/GridAction.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Web; diff --git a/src/WalkingTec.Mvvm.Core/Grid/GridActionExtension.cs b/src/WalkingTec.Mvvm.Core/Grid/GridActionExtension.cs index 6a2ceb99e..20d7b6184 100644 --- a/src/WalkingTec.Mvvm.Core/Grid/GridActionExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Grid/GridActionExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq.Expressions; diff --git a/src/WalkingTec.Mvvm.Core/Grid/GridActionExtension`Old.cs b/src/WalkingTec.Mvvm.Core/Grid/GridActionExtension`Old.cs index d4146dc7d..f4aa161ba 100644 --- a/src/WalkingTec.Mvvm.Core/Grid/GridActionExtension`Old.cs +++ b/src/WalkingTec.Mvvm.Core/Grid/GridActionExtension`Old.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Grid/GridColumn.cs b/src/WalkingTec.Mvvm.Core/Grid/GridColumn.cs index 649a547c2..53c024337 100644 --- a/src/WalkingTec.Mvvm.Core/Grid/GridColumn.cs +++ b/src/WalkingTec.Mvvm.Core/Grid/GridColumn.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Grid/GridColumnExtension`Old.cs b/src/WalkingTec.Mvvm.Core/Grid/GridColumnExtension`Old.cs index e82fc813b..975fd6a1b 100644 --- a/src/WalkingTec.Mvvm.Core/Grid/GridColumnExtension`Old.cs +++ b/src/WalkingTec.Mvvm.Core/Grid/GridColumnExtension`Old.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Grid/GridHeaderExtension.cs b/src/WalkingTec.Mvvm.Core/Grid/GridHeaderExtension.cs index f82dcf24b..fe78e50ed 100644 --- a/src/WalkingTec.Mvvm.Core/Grid/GridHeaderExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Grid/GridHeaderExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq.Expressions; diff --git a/src/WalkingTec.Mvvm.Core/Grid/IGridColumn.cs b/src/WalkingTec.Mvvm.Core/Grid/IGridColumn.cs index 4454608cf..c5b2d78e2 100644 --- a/src/WalkingTec.Mvvm.Core/Grid/IGridColumn.cs +++ b/src/WalkingTec.Mvvm.Core/Grid/IGridColumn.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Drawing; diff --git a/src/WalkingTec.Mvvm.Core/Helper/EntityHelper.cs b/src/WalkingTec.Mvvm.Core/Helper/EntityHelper.cs index 65a7537e2..85dc7a230 100644 --- a/src/WalkingTec.Mvvm.Core/Helper/EntityHelper.cs +++ b/src/WalkingTec.Mvvm.Core/Helper/EntityHelper.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Data; diff --git a/src/WalkingTec.Mvvm.Core/Helper/IServiceExtension.cs b/src/WalkingTec.Mvvm.Core/Helper/IServiceExtension.cs index 55da1cfef..34356c446 100644 --- a/src/WalkingTec.Mvvm.Core/Helper/IServiceExtension.cs +++ b/src/WalkingTec.Mvvm.Core/Helper/IServiceExtension.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; diff --git a/src/WalkingTec.Mvvm.Core/Helper/LogDebug.cs b/src/WalkingTec.Mvvm.Core/Helper/LogDebug.cs index a9273fa8d..3b23ce7dd 100644 --- a/src/WalkingTec.Mvvm.Core/Helper/LogDebug.cs +++ b/src/WalkingTec.Mvvm.Core/Helper/LogDebug.cs @@ -1,3 +1,4 @@ +#nullable disable //using System; //using System.Diagnostics; diff --git a/src/WalkingTec.Mvvm.Core/Helper/LogTrace.cs b/src/WalkingTec.Mvvm.Core/Helper/LogTrace.cs index 80526cd35..a0f5bcc81 100644 --- a/src/WalkingTec.Mvvm.Core/Helper/LogTrace.cs +++ b/src/WalkingTec.Mvvm.Core/Helper/LogTrace.cs @@ -1,3 +1,4 @@ +#nullable disable //using System; //using System.Diagnostics; //using System.Reflection; diff --git a/src/WalkingTec.Mvvm.Core/Helper/PropertyHelper.cs b/src/WalkingTec.Mvvm.Core/Helper/PropertyHelper.cs index cf6e8c111..4182c7be9 100644 --- a/src/WalkingTec.Mvvm.Core/Helper/PropertyHelper.cs +++ b/src/WalkingTec.Mvvm.Core/Helper/PropertyHelper.cs @@ -1,3 +1,4 @@ +#nullable disable using Microsoft.Extensions.Localization; using Microsoft.Extensions.Primitives; using System; diff --git a/src/WalkingTec.Mvvm.Core/IBasePagedListVM.cs b/src/WalkingTec.Mvvm.Core/IBasePagedListVM.cs index 57205ac5c..32466aed5 100644 --- a/src/WalkingTec.Mvvm.Core/IBasePagedListVM.cs +++ b/src/WalkingTec.Mvvm.Core/IBasePagedListVM.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/IBaseVM.cs b/src/WalkingTec.Mvvm.Core/IBaseVM.cs index 477cafdf8..e4d57b584 100644 --- a/src/WalkingTec.Mvvm.Core/IBaseVM.cs +++ b/src/WalkingTec.Mvvm.Core/IBaseVM.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using Microsoft.Extensions.Caching.Distributed; diff --git a/src/WalkingTec.Mvvm.Core/IDataContext.cs b/src/WalkingTec.Mvvm.Core/IDataContext.cs index d9caa8bb2..2ec6cbabe 100644 --- a/src/WalkingTec.Mvvm.Core/IDataContext.cs +++ b/src/WalkingTec.Mvvm.Core/IDataContext.cs @@ -1,3 +1,4 @@ +#nullable disable using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; diff --git a/src/WalkingTec.Mvvm.Core/ISessionService.cs b/src/WalkingTec.Mvvm.Core/ISessionService.cs index 1beb7141a..56b2d44b0 100644 --- a/src/WalkingTec.Mvvm.Core/ISessionService.cs +++ b/src/WalkingTec.Mvvm.Core/ISessionService.cs @@ -1,3 +1,4 @@ +#nullable disable namespace WalkingTec.Mvvm.Core { /// diff --git a/src/WalkingTec.Mvvm.Core/IUIService.cs b/src/WalkingTec.Mvvm.Core/IUIService.cs index 4dd45fcbf..e40ff452a 100644 --- a/src/WalkingTec.Mvvm.Core/IUIService.cs +++ b/src/WalkingTec.Mvvm.Core/IUIService.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Implement/DefaultUIService.cs b/src/WalkingTec.Mvvm.Core/Implement/DefaultUIService.cs index 916ae78de..35515adc4 100644 --- a/src/WalkingTec.Mvvm.Core/Implement/DefaultUIService.cs +++ b/src/WalkingTec.Mvvm.Core/Implement/DefaultUIService.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Json/BodyConverter.cs b/src/WalkingTec.Mvvm.Core/Json/BodyConverter.cs index 97815c704..211a7d0e7 100644 --- a/src/WalkingTec.Mvvm.Core/Json/BodyConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/BodyConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Json/BoolStringConverter.cs b/src/WalkingTec.Mvvm.Core/Json/BoolStringConverter.cs index ad00b3ee0..d8cff3fe6 100644 --- a/src/WalkingTec.Mvvm.Core/Json/BoolStringConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/BoolStringConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Reflection; diff --git a/src/WalkingTec.Mvvm.Core/Json/DateRangeConverter.cs b/src/WalkingTec.Mvvm.Core/Json/DateRangeConverter.cs index 4bafe8bf7..9105c81ea 100644 --- a/src/WalkingTec.Mvvm.Core/Json/DateRangeConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/DateRangeConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Json/DateTimeConverter.cs b/src/WalkingTec.Mvvm.Core/Json/DateTimeConverter.cs index 74628d4a5..c93d53436 100644 --- a/src/WalkingTec.Mvvm.Core/Json/DateTimeConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/DateTimeConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Json/DynamicDataConverter.cs b/src/WalkingTec.Mvvm.Core/Json/DynamicDataConverter.cs index c4ad80536..5d3523a6c 100644 --- a/src/WalkingTec.Mvvm.Core/Json/DynamicDataConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/DynamicDataConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Json/NullableConverter.cs b/src/WalkingTec.Mvvm.Core/Json/NullableConverter.cs index 6b5f5f234..0d9aa21a3 100644 --- a/src/WalkingTec.Mvvm.Core/Json/NullableConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/NullableConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Json/NullableEnumConverter.cs b/src/WalkingTec.Mvvm.Core/Json/NullableEnumConverter.cs index 9b2edee56..8f5c1dc0a 100644 --- a/src/WalkingTec.Mvvm.Core/Json/NullableEnumConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/NullableEnumConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Json/PocoConverter.cs b/src/WalkingTec.Mvvm.Core/Json/PocoConverter.cs index d95fdffa4..109599c0a 100644 --- a/src/WalkingTec.Mvvm.Core/Json/PocoConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/PocoConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Json/RawStringConverter.cs b/src/WalkingTec.Mvvm.Core/Json/RawStringConverter.cs index fa9a3f107..0eff67d2f 100644 --- a/src/WalkingTec.Mvvm.Core/Json/RawStringConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/RawStringConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text.Encodings.Web; diff --git a/src/WalkingTec.Mvvm.Core/Json/StringConverter.cs b/src/WalkingTec.Mvvm.Core/Json/StringConverter.cs index 3fb412eeb..055d45520 100644 --- a/src/WalkingTec.Mvvm.Core/Json/StringConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/StringConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Json/StringIgnoreLTGTConverter.cs b/src/WalkingTec.Mvvm.Core/Json/StringIgnoreLTGTConverter.cs index ef3cedf6b..13ca21c4e 100644 --- a/src/WalkingTec.Mvvm.Core/Json/StringIgnoreLTGTConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/StringIgnoreLTGTConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Text.Json; using System.Text.Json.Serialization; diff --git a/src/WalkingTec.Mvvm.Core/Json/TypeConverter.cs b/src/WalkingTec.Mvvm.Core/Json/TypeConverter.cs index 3cd77a110..795f6483f 100644 --- a/src/WalkingTec.Mvvm.Core/Json/TypeConverter.cs +++ b/src/WalkingTec.Mvvm.Core/Json/TypeConverter.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text.Encodings.Web; diff --git a/src/WalkingTec.Mvvm.Core/JsonResultModel.cs b/src/WalkingTec.Mvvm.Core/JsonResultModel.cs index 550ec91e3..0209bef09 100644 --- a/src/WalkingTec.Mvvm.Core/JsonResultModel.cs +++ b/src/WalkingTec.Mvvm.Core/JsonResultModel.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/LoginUserInfo.cs b/src/WalkingTec.Mvvm.Core/LoginUserInfo.cs index ebafb3cc6..5eabb7ef3 100644 --- a/src/WalkingTec.Mvvm.Core/LoginUserInfo.cs +++ b/src/WalkingTec.Mvvm.Core/LoginUserInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/MSD.cs b/src/WalkingTec.Mvvm.Core/MSD.cs index 56ed5c4f4..e101099b0 100644 --- a/src/WalkingTec.Mvvm.Core/MSD.cs +++ b/src/WalkingTec.Mvvm.Core/MSD.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Models/ActionLog.cs b/src/WalkingTec.Mvvm.Core/Models/ActionLog.cs index 3e7c87b04..5ef68eda4 100644 --- a/src/WalkingTec.Mvvm.Core/Models/ActionLog.cs +++ b/src/WalkingTec.Mvvm.Core/Models/ActionLog.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/BasePoco.cs b/src/WalkingTec.Mvvm.Core/Models/BasePoco.cs index 54abcb976..119e91a63 100644 --- a/src/WalkingTec.Mvvm.Core/Models/BasePoco.cs +++ b/src/WalkingTec.Mvvm.Core/Models/BasePoco.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.ComponentModel.DataAnnotations; using System.Text.Json.Serialization; diff --git a/src/WalkingTec.Mvvm.Core/Models/DataPrivilege.cs b/src/WalkingTec.Mvvm.Core/Models/DataPrivilege.cs index 07b7aa8a1..3077948d1 100644 --- a/src/WalkingTec.Mvvm.Core/Models/DataPrivilege.cs +++ b/src/WalkingTec.Mvvm.Core/Models/DataPrivilege.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/WalkingTec.Mvvm.Core/Models/Elsa_Bookmark.cs b/src/WalkingTec.Mvvm.Core/Models/Elsa_Bookmark.cs index 6fb824d33..6399289e0 100644 --- a/src/WalkingTec.Mvvm.Core/Models/Elsa_Bookmark.cs +++ b/src/WalkingTec.Mvvm.Core/Models/Elsa_Bookmark.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/Elsa_Trigger.cs b/src/WalkingTec.Mvvm.Core/Models/Elsa_Trigger.cs index d145dd9fb..386a3b21c 100644 --- a/src/WalkingTec.Mvvm.Core/Models/Elsa_Trigger.cs +++ b/src/WalkingTec.Mvvm.Core/Models/Elsa_Trigger.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowDefinition.cs b/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowDefinition.cs index 7a4b987c3..aab8e6f22 100644 --- a/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowDefinition.cs +++ b/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowDefinition.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowExecutionLogRecord.cs b/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowExecutionLogRecord.cs index ec15b2fc8..9400a0f04 100644 --- a/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowExecutionLogRecord.cs +++ b/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowExecutionLogRecord.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowInstance.cs b/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowInstance.cs index 524fd5701..79571d0b3 100644 --- a/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowInstance.cs +++ b/src/WalkingTec.Mvvm.Core/Models/Elsa_WorkflowInstance.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/FileAttachment.cs b/src/WalkingTec.Mvvm.Core/Models/FileAttachment.cs index d4707731d..7735a631f 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FileAttachment.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FileAttachment.cs @@ -1,3 +1,4 @@ +#nullable disable using Microsoft.EntityFrameworkCore; using System; using System.ComponentModel; diff --git a/src/WalkingTec.Mvvm.Core/Models/FrameworkGroup.cs b/src/WalkingTec.Mvvm.Core/Models/FrameworkGroup.cs index d43f303f7..93d617948 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FrameworkGroup.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FrameworkGroup.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/WalkingTec.Mvvm.Core/Models/FrameworkMenu.cs b/src/WalkingTec.Mvvm.Core/Models/FrameworkMenu.cs index 55dbc0907..892e78aa5 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FrameworkMenu.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FrameworkMenu.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/FrameworkRole.cs b/src/WalkingTec.Mvvm.Core/Models/FrameworkRole.cs index 35dc60929..120086185 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FrameworkRole.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FrameworkRole.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/WalkingTec.Mvvm.Core/Models/FrameworkTenant.cs b/src/WalkingTec.Mvvm.Core/Models/FrameworkTenant.cs index eb3b08620..2b28364a9 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FrameworkTenant.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FrameworkTenant.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/FrameworkUser.cs b/src/WalkingTec.Mvvm.Core/Models/FrameworkUser.cs index 26400f0e5..dce07cdd3 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FrameworkUser.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FrameworkUser.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/FrameworkUserGroup.cs b/src/WalkingTec.Mvvm.Core/Models/FrameworkUserGroup.cs index dd1928218..65716ee44 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FrameworkUserGroup.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FrameworkUserGroup.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/WalkingTec.Mvvm.Core/Models/FrameworkUserRole.cs b/src/WalkingTec.Mvvm.Core/Models/FrameworkUserRole.cs index baf0163ce..62f539f73 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FrameworkUserRole.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FrameworkUserRole.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/WalkingTec.Mvvm.Core/Models/FrameworkWorkflow.cs b/src/WalkingTec.Mvvm.Core/Models/FrameworkWorkflow.cs index d7ab8e31e..e76eaee75 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FrameworkWorkflow.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FrameworkWorkflow.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/WalkingTec.Mvvm.Core/Models/FunctionPrivilege.cs b/src/WalkingTec.Mvvm.Core/Models/FunctionPrivilege.cs index 686ca29b0..dbcabf75a 100644 --- a/src/WalkingTec.Mvvm.Core/Models/FunctionPrivilege.cs +++ b/src/WalkingTec.Mvvm.Core/Models/FunctionPrivilege.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/WalkingTec.Mvvm.Core/Models/ISearcher.cs b/src/WalkingTec.Mvvm.Core/Models/ISearcher.cs index 029380807..ef1876f2d 100644 --- a/src/WalkingTec.Mvvm.Core/Models/ISearcher.cs +++ b/src/WalkingTec.Mvvm.Core/Models/ISearcher.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using WalkingTec.Mvvm.Core; diff --git a/src/WalkingTec.Mvvm.Core/Models/ISubFile.cs b/src/WalkingTec.Mvvm.Core/Models/ISubFile.cs index 4aa27ac25..900ef041f 100644 --- a/src/WalkingTec.Mvvm.Core/Models/ISubFile.cs +++ b/src/WalkingTec.Mvvm.Core/Models/ISubFile.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Models/ITenant.cs b/src/WalkingTec.Mvvm.Core/Models/ITenant.cs index 6617044a0..836dd10a9 100644 --- a/src/WalkingTec.Mvvm.Core/Models/ITenant.cs +++ b/src/WalkingTec.Mvvm.Core/Models/ITenant.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Models/IWorkflow.cs b/src/WalkingTec.Mvvm.Core/Models/IWorkflow.cs index aee148da8..fb34e1373 100644 --- a/src/WalkingTec.Mvvm.Core/Models/IWorkflow.cs +++ b/src/WalkingTec.Mvvm.Core/Models/IWorkflow.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Models/IWtmFile.cs b/src/WalkingTec.Mvvm.Core/Models/IWtmFile.cs index f04d6f48c..141c294df 100644 --- a/src/WalkingTec.Mvvm.Core/Models/IWtmFile.cs +++ b/src/WalkingTec.Mvvm.Core/Models/IWtmFile.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.IO; diff --git a/src/WalkingTec.Mvvm.Core/Models/PersistPoco.cs b/src/WalkingTec.Mvvm.Core/Models/PersistPoco.cs index 6d8c17dce..3709cfe65 100644 --- a/src/WalkingTec.Mvvm.Core/Models/PersistPoco.cs +++ b/src/WalkingTec.Mvvm.Core/Models/PersistPoco.cs @@ -1,3 +1,4 @@ +#nullable disable using System.ComponentModel.DataAnnotations; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Models/RefreshTokenEntity.cs b/src/WalkingTec.Mvvm.Core/Models/RefreshTokenEntity.cs index 769d901e9..3f0ab7ed4 100644 --- a/src/WalkingTec.Mvvm.Core/Models/RefreshTokenEntity.cs +++ b/src/WalkingTec.Mvvm.Core/Models/RefreshTokenEntity.cs @@ -11,30 +11,30 @@ public class RefreshTokenEntity public Guid ID { get; set; } = Guid.NewGuid(); [Required, StringLength(256)] - public string Token { get; set; } + public string Token { get; set; } = null!; [Required, StringLength(50)] - public string ITCode { get; set; } + public string ITCode { get; set; } = null!; [StringLength(50)] - public string TenantCode { get; set; } + public string? TenantCode { get; set; } public DateTime ExpiresUtc { get; set; } public DateTime CreatedUtc { get; set; } = DateTime.UtcNow; [StringLength(50)] - public string CreatedByIp { get; set; } + public string? CreatedByIp { get; set; } public DateTime? RevokedUtc { get; set; } [StringLength(50)] - public string RevokedByIp { get; set; } + public string? RevokedByIp { get; set; } [StringLength(256)] - public string ReplacedByToken { get; set; } + public string? ReplacedByToken { get; set; } [StringLength(100)] - public string RevokeReason { get; set; } + public string? RevokeReason { get; set; } [NotMapped] public bool IsExpired => DateTime.UtcNow >= ExpiresUtc; diff --git a/src/WalkingTec.Mvvm.Core/Models/TopBasePoco.cs b/src/WalkingTec.Mvvm.Core/Models/TopBasePoco.cs index 1d6c03678..9562bfcd9 100644 --- a/src/WalkingTec.Mvvm.Core/Models/TopBasePoco.cs +++ b/src/WalkingTec.Mvvm.Core/Models/TopBasePoco.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; diff --git a/src/WalkingTec.Mvvm.Core/Models/TreePoco.cs b/src/WalkingTec.Mvvm.Core/Models/TreePoco.cs index 11e1c0265..b9f985ec1 100644 --- a/src/WalkingTec.Mvvm.Core/Models/TreePoco.cs +++ b/src/WalkingTec.Mvvm.Core/Models/TreePoco.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/PasswordHashHelper.cs b/src/WalkingTec.Mvvm.Core/PasswordHashHelper.cs index eb6abf04c..57d0d7ab8 100644 --- a/src/WalkingTec.Mvvm.Core/PasswordHashHelper.cs +++ b/src/WalkingTec.Mvvm.Core/PasswordHashHelper.cs @@ -12,14 +12,14 @@ public static class PasswordHashHelper private static readonly Regex _md5Pattern = new(@"^[0-9A-F]{32}$", RegexOptions.Compiled); - public static string HashPassword(string password) + public static string HashPassword(string? password) { if (string.IsNullOrEmpty(password)) return string.Empty; return _hasher.HashPassword(string.Empty, password); } public static PasswordVerifyResult VerifyPassword( - string storedHash, string password) + string? storedHash, string? password) { if (string.IsNullOrEmpty(storedHash) || string.IsNullOrEmpty(password)) @@ -45,13 +45,13 @@ public static PasswordVerifyResult VerifyPassword( }; } - public static bool IsLegacyMD5Hash(string hash) + public static bool IsLegacyMD5Hash(string? hash) { if (string.IsNullOrEmpty(hash) || hash.Length != 32) return false; return _md5Pattern.IsMatch(hash); } - internal static string ComputeMD5(string input) + internal static string ComputeMD5(string? input) { if (string.IsNullOrEmpty(input)) return string.Empty; byte[] buffer = Encoding.UTF8.GetBytes(input); diff --git a/src/WalkingTec.Mvvm.Core/Support/AuthConstants.cs b/src/WalkingTec.Mvvm.Core/Support/AuthConstants.cs index 9e63ad062..a9141ab56 100644 --- a/src/WalkingTec.Mvvm.Core/Support/AuthConstants.cs +++ b/src/WalkingTec.Mvvm.Core/Support/AuthConstants.cs @@ -1,3 +1,4 @@ +#nullable disable namespace WalkingTec.Mvvm.Core.Auth { public static class AuthConstants diff --git a/src/WalkingTec.Mvvm.Core/Support/ChartData.cs b/src/WalkingTec.Mvvm.Core/Support/ChartData.cs index b23d5a0b8..a642c010d 100644 --- a/src/WalkingTec.Mvvm.Core/Support/ChartData.cs +++ b/src/WalkingTec.Mvvm.Core/Support/ChartData.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Support/ClaimComparer.cs b/src/WalkingTec.Mvvm.Core/Support/ClaimComparer.cs index cc6b2f5ae..9e3acf654 100644 --- a/src/WalkingTec.Mvvm.Core/Support/ClaimComparer.cs +++ b/src/WalkingTec.Mvvm.Core/Support/ClaimComparer.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Security.Claims; diff --git a/src/WalkingTec.Mvvm.Core/Support/ColumnFormatInfo.cs b/src/WalkingTec.Mvvm.Core/Support/ColumnFormatInfo.cs index 7b68b3b50..c0d852d96 100644 --- a/src/WalkingTec.Mvvm.Core/Support/ColumnFormatInfo.cs +++ b/src/WalkingTec.Mvvm.Core/Support/ColumnFormatInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Support/CommonEqualityComparer.cs b/src/WalkingTec.Mvvm.Core/Support/CommonEqualityComparer.cs index 2e773f2c9..16296e02d 100644 --- a/src/WalkingTec.Mvvm.Core/Support/CommonEqualityComparer.cs +++ b/src/WalkingTec.Mvvm.Core/Support/CommonEqualityComparer.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Support/DataPrivilegeInfo.cs b/src/WalkingTec.Mvvm.Core/Support/DataPrivilegeInfo.cs index 290a49b1f..b74a129f3 100644 --- a/src/WalkingTec.Mvvm.Core/Support/DataPrivilegeInfo.cs +++ b/src/WalkingTec.Mvvm.Core/Support/DataPrivilegeInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Support/DateRange.cs b/src/WalkingTec.Mvvm.Core/Support/DateRange.cs index d85cb1dd9..dbd9a22f2 100644 --- a/src/WalkingTec.Mvvm.Core/Support/DateRange.cs +++ b/src/WalkingTec.Mvvm.Core/Support/DateRange.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text.RegularExpressions; diff --git a/src/WalkingTec.Mvvm.Core/Support/DuplicateInfo.cs b/src/WalkingTec.Mvvm.Core/Support/DuplicateInfo.cs index ab329cbac..09a61ef6e 100644 --- a/src/WalkingTec.Mvvm.Core/Support/DuplicateInfo.cs +++ b/src/WalkingTec.Mvvm.Core/Support/DuplicateInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Support/DynamicData.cs b/src/WalkingTec.Mvvm.Core/Support/DynamicData.cs index e4178bae5..721f6929f 100644 --- a/src/WalkingTec.Mvvm.Core/Support/DynamicData.cs +++ b/src/WalkingTec.Mvvm.Core/Support/DynamicData.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Dynamic; diff --git a/src/WalkingTec.Mvvm.Core/Support/ExcelPropety.cs b/src/WalkingTec.Mvvm.Core/Support/ExcelPropety.cs index 8a714bcfb..58ca25ef7 100644 --- a/src/WalkingTec.Mvvm.Core/Support/ExcelPropety.cs +++ b/src/WalkingTec.Mvvm.Core/Support/ExcelPropety.cs @@ -1,3 +1,4 @@ +#nullable disable using NPOI.HSSF.UserModel; using NPOI.OpenXmlFormats.Spreadsheet; using NPOI.SS.UserModel; diff --git a/src/WalkingTec.Mvvm.Core/Support/ExpressionVisitors.cs b/src/WalkingTec.Mvvm.Core/Support/ExpressionVisitors.cs index 4db5c8e8a..ecf922064 100644 --- a/src/WalkingTec.Mvvm.Core/Support/ExpressionVisitors.cs +++ b/src/WalkingTec.Mvvm.Core/Support/ExpressionVisitors.cs @@ -1,3 +1,4 @@ +#nullable disable using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query.Internal; using System; diff --git a/src/WalkingTec.Mvvm.Core/Support/ExtraClass.cs b/src/WalkingTec.Mvvm.Core/Support/ExtraClass.cs index 8f1ffd268..213e525ec 100644 --- a/src/WalkingTec.Mvvm.Core/Support/ExtraClass.cs +++ b/src/WalkingTec.Mvvm.Core/Support/ExtraClass.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; using System.Linq; using System.Net; diff --git a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/IWtmFileHandler.cs b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/IWtmFileHandler.cs index ec2a14521..90a998b79 100644 --- a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/IWtmFileHandler.cs +++ b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/IWtmFileHandler.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.IO; diff --git a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmDataBaseFileHandler.cs b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmDataBaseFileHandler.cs index 3cb7532ac..1261fd86e 100644 --- a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmDataBaseFileHandler.cs +++ b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmDataBaseFileHandler.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmFileHandlerBase.cs b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmFileHandlerBase.cs index 7bf888d2b..b063fc4f9 100644 --- a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmFileHandlerBase.cs +++ b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmFileHandlerBase.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.IO; diff --git a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmFileProvider.cs b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmFileProvider.cs index e69720114..efeb7b8f1 100644 --- a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmFileProvider.cs +++ b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmFileProvider.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmLocalFileHandler.cs b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmLocalFileHandler.cs index 3cdc05dfc..ca46f6923 100644 --- a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmLocalFileHandler.cs +++ b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmLocalFileHandler.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmOssFileHandler.cs b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmOssFileHandler.cs index 1b6f5d478..b5af583c2 100644 --- a/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmOssFileHandler.cs +++ b/src/WalkingTec.Mvvm.Core/Support/FileHandlers/WtmOssFileHandler.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/ApiListModel.cs b/src/WalkingTec.Mvvm.Core/Support/Json/ApiListModel.cs index 2edc6545a..f7f741eb9 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/ApiListModel.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/ApiListModel.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleAction.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleAction.cs index 99bc38bc9..e93193518 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleAction.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleAction.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleArea.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleArea.cs index 98c17d21b..9c15c4386 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleArea.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleArea.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleDataPri.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleDataPri.cs index c87ccb864..359cf79c8 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleDataPri.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleDataPri.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core.Support.Json diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleFunctionPri.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleFunctionPri.cs index 47f3710e9..74d035f31 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleFunctionPri.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleFunctionPri.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core.Support.Json diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleGroup.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleGroup.cs index 4d452d3f8..9564090a6 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleGroup.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleGroup.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core.Support.Json diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleLog.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleLog.cs index af8687a6c..7ec43dc40 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleLog.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleLog.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleMenu.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleMenu.cs index f62daa3de..04fde9063 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleMenu.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleMenu.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleModule.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleModule.cs index cf19799ce..fd31d38e0 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleModule.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleModule.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleRole.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleRole.cs index 6733e0fe3..ae151d9c5 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleRole.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleRole.cs @@ -1,3 +1,4 @@ +#nullable disable using System; namespace WalkingTec.Mvvm.Core.Support.Json diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleUserInfo.cs b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleUserInfo.cs index 98691d3c5..a7b3ed797 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/SimpleUserInfo.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/SimpleUserInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; diff --git a/src/WalkingTec.Mvvm.Core/Support/Json/Token.cs b/src/WalkingTec.Mvvm.Core/Support/Json/Token.cs index 73f184950..646e8eccb 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Json/Token.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Json/Token.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Text.Json.Serialization; diff --git a/src/WalkingTec.Mvvm.Core/Support/ListItem.cs b/src/WalkingTec.Mvvm.Core/Support/ListItem.cs index 580c6df0d..c89a7c0fd 100644 --- a/src/WalkingTec.Mvvm.Core/Support/ListItem.cs +++ b/src/WalkingTec.Mvvm.Core/Support/ListItem.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Support/NugetInfo.cs b/src/WalkingTec.Mvvm.Core/Support/NugetInfo.cs index 08439dac3..99cc20fae 100644 --- a/src/WalkingTec.Mvvm.Core/Support/NugetInfo.cs +++ b/src/WalkingTec.Mvvm.Core/Support/NugetInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Text; diff --git a/src/WalkingTec.Mvvm.Core/Support/Quartz/QuartzAttributes.cs b/src/WalkingTec.Mvvm.Core/Support/Quartz/QuartzAttributes.cs index fb1633a80..ab8683140 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Quartz/QuartzAttributes.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Quartz/QuartzAttributes.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Support/Quartz/QuartzHostService.cs b/src/WalkingTec.Mvvm.Core/Support/Quartz/QuartzHostService.cs index 59df7c4e9..7536ea036 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Quartz/QuartzHostService.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Quartz/QuartzHostService.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Support/Quartz/WtmJob.cs b/src/WalkingTec.Mvvm.Core/Support/Quartz/WtmJob.cs index eaf7149fc..c5f7d4de7 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Quartz/WtmJob.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Quartz/WtmJob.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Support/Quartz/WtmJobFactory.cs b/src/WalkingTec.Mvvm.Core/Support/Quartz/WtmJobFactory.cs index d15a9af11..87828e8ff 100644 --- a/src/WalkingTec.Mvvm.Core/Support/Quartz/WtmJobFactory.cs +++ b/src/WalkingTec.Mvvm.Core/Support/Quartz/WtmJobFactory.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Support/SupportedGroupMapping.cs b/src/WalkingTec.Mvvm.Core/Support/SupportedGroupMapping.cs index c6ca58365..bfe2451ec 100644 --- a/src/WalkingTec.Mvvm.Core/Support/SupportedGroupMapping.cs +++ b/src/WalkingTec.Mvvm.Core/Support/SupportedGroupMapping.cs @@ -1,3 +1,4 @@ +#nullable disable using System.Collections.Generic; namespace WalkingTec.Mvvm.Core diff --git a/src/WalkingTec.Mvvm.Core/Support/TypeComparer.cs b/src/WalkingTec.Mvvm.Core/Support/TypeComparer.cs index b36e6315b..9dd2269d9 100644 --- a/src/WalkingTec.Mvvm.Core/Support/TypeComparer.cs +++ b/src/WalkingTec.Mvvm.Core/Support/TypeComparer.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; diff --git a/src/WalkingTec.Mvvm.Core/Support/WTMLogger.cs b/src/WalkingTec.Mvvm.Core/Support/WTMLogger.cs index 00980f394..11a671753 100644 --- a/src/WalkingTec.Mvvm.Core/Support/WTMLogger.cs +++ b/src/WalkingTec.Mvvm.Core/Support/WTMLogger.cs @@ -1,3 +1,4 @@ +#nullable disable using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; diff --git a/src/WalkingTec.Mvvm.Core/Support/WebProxy.cs b/src/WalkingTec.Mvvm.Core/Support/WebProxy.cs index e7cdab5c1..0b3323028 100644 --- a/src/WalkingTec.Mvvm.Core/Support/WebProxy.cs +++ b/src/WalkingTec.Mvvm.Core/Support/WebProxy.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Net; diff --git a/src/WalkingTec.Mvvm.Core/Support/WtmLocalizationOption.cs b/src/WalkingTec.Mvvm.Core/Support/WtmLocalizationOption.cs index 8ad42a384..cf9c98888 100644 --- a/src/WalkingTec.Mvvm.Core/Support/WtmLocalizationOption.cs +++ b/src/WalkingTec.Mvvm.Core/Support/WtmLocalizationOption.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/Utils.cs b/src/WalkingTec.Mvvm.Core/Utils.cs index ace31b844..85ccfc639 100644 --- a/src/WalkingTec.Mvvm.Core/Utils.cs +++ b/src/WalkingTec.Mvvm.Core/Utils.cs @@ -1,3 +1,4 @@ +#nullable disable using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Distributed; using NPOI.HSSF.Util; diff --git a/src/WalkingTec.Mvvm.Core/WTMContext.cs b/src/WalkingTec.Mvvm.Core/WTMContext.cs index 127f65cbc..642ed4600 100644 --- a/src/WalkingTec.Mvvm.Core/WTMContext.cs +++ b/src/WalkingTec.Mvvm.Core/WTMContext.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.IdentityModel.Tokens.Jwt; @@ -491,32 +492,38 @@ public LoginUserInfo DoLogin(string username, string password, string tenant) return DoLoginAsync(username, password, tenant).GetAwaiter().GetResult(); } - public Token RefreshToken() + public async Task RefreshTokenAsync() { - if(LoginUserInfo == null) + if (LoginUserInfo == null) { return null; } string rt = null; if (ConfigInfo.HasMainHost && LoginUserInfo?.CurrentTenant == null) { - var r = CallAPI("mainhost", $"/api/_account/RefreshToken", HttpMethodEnum.POST, new { }).Result; + var r = await CallAPI("mainhost", $"/api/_account/RefreshToken", HttpMethodEnum.POST, new { }); rt = r?.Data?.AccessToken; } else { rt = LoginUserInfo.RemoteToken; - } + } var _authService = ServiceProvider.GetRequiredService(); - var rv = _authService.IssueTokenAsync(new LoginUserInfo + var rv = await _authService.IssueTokenAsync(new LoginUserInfo { ITCode = LoginUserInfo.ITCode, TenantCode = LoginUserInfo.TenantCode, RemoteToken = rt - }).Result; + }); return rv; } + [Obsolete("Use RefreshTokenAsync to avoid ThreadPool starvation. RefreshToken blocks threads on every token refresh.")] + public Token RefreshToken() + { + return RefreshTokenAsync().GetAwaiter().GetResult(); + } + public T ReadFromCache(string key, Func setFunc, int? timeout = null) { if (Cache.TryGetValue(key, out T rv) == false || rv == null) diff --git a/src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj b/src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj index 9c72c129f..c112658c1 100644 --- a/src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj +++ b/src/WalkingTec.Mvvm.Core/WalkingTec.Mvvm.Core.csproj @@ -5,6 +5,7 @@ WalkingTec.Mvvm.Core $(AssemblyName) true + enable @@ -12,28 +13,32 @@ - + - - - - + + + + - + - + - - - - + + + + - + + + + + diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveActivity.cs b/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveActivity.cs index 07f8fce0b..bfdde2a17 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveActivity.cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveActivity.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; @@ -94,7 +95,8 @@ public object GetOptions(PropertyInfo property) { try { - var check = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowRoles").Result; + // TODO: GetOptions() is constrained by IActivityPropertyOptionsProvider (sync); use GetAwaiter().GetResult() + var check = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowRoles").GetAwaiter().GetResult(); if (check.Data != null) { rv = check.Data; @@ -107,7 +109,8 @@ public object GetOptions(PropertyInfo property) { try { - var check = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowGroups").Result; + // TODO: GetOptions() is constrained by IActivityPropertyOptionsProvider (sync); use GetAwaiter().GetResult() + var check = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowGroups").GetAwaiter().GetResult(); if (check.Data != null) { rv = check.Data; @@ -120,7 +123,8 @@ public object GetOptions(PropertyInfo property) { try { - var check = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowGroups").Result; + // TODO: GetOptions() is constrained by IActivityPropertyOptionsProvider (sync); use GetAwaiter().GetResult() + var check = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowGroups").GetAwaiter().GetResult(); if (check.Data != null) { rv = check.Data; @@ -171,7 +175,8 @@ protected override IActivityExecutionResult OnExecute(ActivityExecutionContext c { query = $"itcode={submitter}"; - var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowMyGroupManagers?{query}").Result; + // TODO: OnExecute() is constrained by Elsa Activity base class (sync); use GetAwaiter().GetResult() + var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowMyGroupManagers?{query}").GetAwaiter().GetResult(); users = names.Data ?? new List(); if (users.Count > 0) { @@ -189,7 +194,8 @@ protected override IActivityExecutionResult OnExecute(ActivityExecutionContext c query += $"ids={item}&"; } query += "1=1"; - var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowGroupManagers?{query}").Result; + // TODO: OnExecute() is constrained by Elsa Activity base class (sync); use GetAwaiter().GetResult() + var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowGroupManagers?{query}").GetAwaiter().GetResult(); managers = names.Data ?? new List(); foreach (var item in managers) { @@ -208,7 +214,8 @@ protected override IActivityExecutionResult OnExecute(ActivityExecutionContext c query += $"itcode={item}&"; } query += "1=1"; - var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowUsers?{query}").Result; + // TODO: OnExecute() is constrained by Elsa Activity base class (sync); use GetAwaiter().GetResult() + var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowUsers?{query}").GetAwaiter().GetResult(); users = names.Data ?? new List(); ApproveUsersFullText.AddRange(users.Select(x => $"{x.Text}({x.Value})").ToList()); foreach (var item in ApproveUsers) @@ -236,7 +243,8 @@ protected override IActivityExecutionResult OnExecute(ActivityExecutionContext c query += $"ids={item}&"; } query += "1=1"; - var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowRoles?{query}").Result; + // TODO: OnExecute() is constrained by Elsa Activity base class (sync); use GetAwaiter().GetResult() + var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowRoles?{query}").GetAwaiter().GetResult(); roles = names.Data ?? new List(); ApproveUsersFullText.AddRange(roles.Select(x => $"{x.Text}").ToList()); foreach (var item in ApproveRoles) @@ -264,7 +272,8 @@ protected override IActivityExecutionResult OnExecute(ActivityExecutionContext c query += $"ids={item}&"; } query += "1=1"; - var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowGroups?{query}").Result; + // TODO: OnExecute() is constrained by Elsa Activity base class (sync); use GetAwaiter().GetResult() + var names = _wtm.CallAPI>("", $"{_wtm.HostAddress}/_workflowapi/GetWorkflowGroups?{query}").GetAwaiter().GetResult(); groups = names.Data ?? new List(); ApproveUsersFullText.AddRange(groups.Select(x => $"{x.Text}").ToList()); foreach (var item in ApproveGroups) diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveInfo.cs b/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveInfo.cs index 3045b9ab7..599495894 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveInfo.cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveInfo.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveTimeLine.cs b/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveTimeLine.cs index ed7d07b9c..ba44bdd72 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveTimeLine.cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/ApproveTimeLine.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/BookMark.cs b/src/WalkingTec.Mvvm.Core/WorkFlow/BookMark.cs index 0b9496745..846feb493 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/BookMark.cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/BookMark.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/ElsaTenantAccessor .cs b/src/WalkingTec.Mvvm.Core/WorkFlow/ElsaTenantAccessor .cs index 71ab8c607..88a54356e 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/ElsaTenantAccessor .cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/ElsaTenantAccessor .cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/IApproveNotification.cs b/src/WalkingTec.Mvvm.Core/WorkFlow/IApproveNotification.cs index 024ae8c5d..b76ef9d4d 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/IApproveNotification.cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/IApproveNotification.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/InstanceWrap.cs b/src/WalkingTec.Mvvm.Core/WorkFlow/InstanceWrap.cs index 353a4adbf..9068c7d78 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/InstanceWrap.cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/InstanceWrap.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/ResultWrap.cs b/src/WalkingTec.Mvvm.Core/WorkFlow/ResultWrap.cs index db7c821dc..5ce05fb6b 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/ResultWrap.cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/ResultWrap.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/WorkflowRefresher.cs b/src/WalkingTec.Mvvm.Core/WorkFlow/WorkflowRefresher.cs index a03c86939..12ae85053 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/WorkflowRefresher.cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/WorkflowRefresher.cs @@ -1,3 +1,4 @@ +#nullable disable using Elsa.Services; using Elsa.Services.Models; using Microsoft.EntityFrameworkCore; diff --git a/src/WalkingTec.Mvvm.Core/WorkFlow/WtmApproveInput.cs b/src/WalkingTec.Mvvm.Core/WorkFlow/WtmApproveInput.cs index a3843645f..fa673224f 100644 --- a/src/WalkingTec.Mvvm.Core/WorkFlow/WtmApproveInput.cs +++ b/src/WalkingTec.Mvvm.Core/WorkFlow/WtmApproveInput.cs @@ -1,3 +1,4 @@ +#nullable disable using System; using System.Collections.Generic; using System.Linq; diff --git a/src/WalkingTec.Mvvm.Mvc/Helper/FrameworkServiceExtension.cs b/src/WalkingTec.Mvvm.Mvc/Helper/FrameworkServiceExtension.cs index 5c98fdb17..12b2163fb 100644 --- a/src/WalkingTec.Mvvm.Mvc/Helper/FrameworkServiceExtension.cs +++ b/src/WalkingTec.Mvvm.Mvc/Helper/FrameworkServiceExtension.cs @@ -1089,12 +1089,14 @@ public static IApplicationBuilder UseWtmContext(this IApplicationBuilder app, bo foreach (var item in cs) { var dc = item.CreateDC(); - dc.DataInit(gd.AllModule, isspa == true || test != null).Wait(); + // TODO: UseWtmContext is a sync IApplicationBuilder extension; GetAwaiter().GetResult() used at startup + dc.DataInit(gd.AllModule, isspa == true || test != null).GetAwaiter().GetResult(); } } else { - fixdc.DataInit(gd.AllModule, isspa == true || test != null).Wait(); + // TODO: UseWtmContext is a sync IApplicationBuilder extension; GetAwaiter().GetResult() used at startup + fixdc.DataInit(gd.AllModule, isspa == true || test != null).GetAwaiter().GetResult(); } } diff --git a/src/WalkingTec.Mvvm.Mvc/Helper/SessionExtension.cs b/src/WalkingTec.Mvvm.Mvc/Helper/SessionExtension.cs index 06c285a23..ceb6ea76b 100644 --- a/src/WalkingTec.Mvvm.Mvc/Helper/SessionExtension.cs +++ b/src/WalkingTec.Mvvm.Mvc/Helper/SessionExtension.cs @@ -8,7 +8,8 @@ public static class SessionExtensions public static void Set(this ISession session, string key, T value) { session.SetString(key, JsonSerializer.Serialize(value)); - session.CommitAsync().Wait(); + // TODO: Set is a sync extension; CommitAsync().GetAwaiter().GetResult() avoids Wait() deadlock + session.CommitAsync().GetAwaiter().GetResult(); } public static T Get(this ISession session, string key) diff --git a/src/WalkingTec.Mvvm.Mvc/Helper/WtmMiddleware.cs b/src/WalkingTec.Mvvm.Mvc/Helper/WtmMiddleware.cs index a01fab4d6..8dcb4880f 100644 --- a/src/WalkingTec.Mvvm.Mvc/Helper/WtmMiddleware.cs +++ b/src/WalkingTec.Mvvm.Mvc/Helper/WtmMiddleware.cs @@ -34,7 +34,7 @@ public async Task InvokeAsync(HttpContext context, WTMContext wtm) } if (context.Request.Path == "/v1/activities" && context.Request.QueryString.Value != "?inneruse=1") { - var txt = wtm.CallAPI("", $"{wtm.HostAddress}/v1/activities?inneruse=1").Result.Data; + var txt = (await wtm.CallAPI("", $"{wtm.HostAddress}/v1/activities?inneruse=1")).Data; //Assembly assembly = Assembly.GetExecutingAssembly(); //var loc = "WalkingTec.Mvvm.Mvc.Workflow.json"; //var textStreamReader = new StreamReader(assembly.GetManifestResourceStream(loc)); @@ -68,7 +68,7 @@ public async Task InvokeAsync(HttpContext context, WTMContext wtm) context.Request.EnableBuffering(); context.Request.Body.Position = 0; StreamReader tr = new StreamReader(context.Request.Body); - string body = tr.ReadToEndAsync().Result; + string body = await tr.ReadToEndAsync(); context.Request.Body.Position = 0; if (context.Items.ContainsKey("DONOTUSE_REQUESTBODY") == false) { diff --git a/src/WalkingTec.Mvvm.Mvc/WalkingTec.Mvvm.Mvc.csproj b/src/WalkingTec.Mvvm.Mvc/WalkingTec.Mvvm.Mvc.csproj index b277dc0d3..a4184c0a3 100644 --- a/src/WalkingTec.Mvvm.Mvc/WalkingTec.Mvvm.Mvc.csproj +++ b/src/WalkingTec.Mvvm.Mvc/WalkingTec.Mvvm.Mvc.csproj @@ -91,13 +91,13 @@ - - - - - - - + + + + + + + diff --git a/src/WalkingTec.Mvvm.Mvc/_FrameworkController.cs b/src/WalkingTec.Mvvm.Mvc/_FrameworkController.cs index 323ccd092..86f7d00b3 100644 --- a/src/WalkingTec.Mvvm.Mvc/_FrameworkController.cs +++ b/src/WalkingTec.Mvvm.Mvc/_FrameworkController.cs @@ -128,7 +128,7 @@ public IActionResult GetEmptyData(string _DONOT_USE_VMNAME) /// [HttpPost] [ActionDescription("GetPagingData")] - public IActionResult GetPagingData(string _DONOT_USE_VMNAME, string _DONOT_USE_CS) + public async Task GetPagingData(string _DONOT_USE_VMNAME, string _DONOT_USE_CS) { var qs = new Dictionary(); foreach (var item in Request.Form.Keys) @@ -164,7 +164,7 @@ public IActionResult GetPagingData(string _DONOT_USE_VMNAME, string _DONOT_USE_C } if(string.IsNullOrEmpty(url) == false) { - var result = Wtm.CallAPI("mainhost", url, HttpMethodEnum.POST, listVM.Searcher, 10).Result; + var result = await Wtm.CallAPI("mainhost", url, HttpMethodEnum.POST, listVM.Searcher, 10); var rv = new ContentResult { ContentType = "application/json", @@ -571,7 +571,8 @@ public string GetGithubStarts() { return Wtm.ReadFromCache("githubstar", () => { - var s = Wtm.CallAPI("github", "/repos/dotnetcore/wtm").Result.Data; + // TODO: ReadFromCache factory is sync Func; GetAwaiter().GetResult() used inside sync callback + var s = Wtm.CallAPI("github", "/repos/dotnetcore/wtm").GetAwaiter().GetResult().Data; return s == null ? "" : s.stargazers_count.ToString(); }, 1800); } @@ -582,7 +583,8 @@ public ActionResult GetGithubInfo() { var rv = Wtm.ReadFromCache("githubinfo", () => { - var s = Wtm.CallAPI("github", "/repos/dotnetcore/wtm").Result; + // TODO: ReadFromCache factory is sync Func; GetAwaiter().GetResult() used inside sync callback + var s = Wtm.CallAPI("github", "/repos/dotnetcore/wtm").GetAwaiter().GetResult(); return JsonSerializer.Serialize(s); }, 1800); return Content(rv, "application/json"); diff --git a/src/WalkingTec.Mvvm.Mvc/_WorkflowApiController.cs b/src/WalkingTec.Mvvm.Mvc/_WorkflowApiController.cs index 2a64a65a9..2b3d5eacb 100644 --- a/src/WalkingTec.Mvvm.Mvc/_WorkflowApiController.cs +++ b/src/WalkingTec.Mvvm.Mvc/_WorkflowApiController.cs @@ -40,14 +40,14 @@ public class WorkflowApiController : BaseApiController [HttpGet("[action]")] [NoLog] [Public] - public IActionResult GetWorkflowUsers([FromQuery]string[] itcode) + public async Task GetWorkflowUsers([FromQuery]string[] itcode) { if (ConfigInfo.HasMainHost) { - return Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowUsers").Result; + return await Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowUsers"); } var tenant = Wtm.LoginUserInfo?.CurrentTenant; var rv = Wtm.BaseUserQuery.IgnoreQueryFilters().CheckContain(itcode.ToList(), x => x.ITCode).Where(x => x.TenantCode == tenant) @@ -62,11 +62,11 @@ public IActionResult GetWorkflowUsers([FromQuery]string[] itcode) [HttpGet("[action]")] [Public] [NoLog] - public IActionResult GetWorkflowGroups([FromQuery] string[] ids) + public async Task GetWorkflowGroups([FromQuery] string[] ids) { if (ConfigInfo.HasMainHost) { - return Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowGroups").Result; + return await Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowGroups"); } var tenant = Wtm.LoginUserInfo?.CurrentTenant; var rv = Wtm.DC.Set().CheckIDs(ids.ToList()) @@ -80,11 +80,11 @@ public IActionResult GetWorkflowGroups([FromQuery] string[] ids) [HttpGet("[action]")] [Public] [NoLog] - public IActionResult GetWorkflowGroupManagers([FromQuery] string[] ids) + public async Task GetWorkflowGroupManagers([FromQuery] string[] ids) { if (ConfigInfo.HasMainHost) { - return Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowGroupManagers").Result; + return await Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowGroupManagers"); } var tenant = Wtm.LoginUserInfo?.CurrentTenant; var rv = Wtm.DC.Set().CheckIDs(ids.ToList()) @@ -98,11 +98,11 @@ public IActionResult GetWorkflowGroupManagers([FromQuery] string[] ids) [HttpGet("[action]")] [Public] [NoLog] - public IActionResult GetWorkflowMyGroupManagers([FromQuery] string itcode) + public async Task GetWorkflowMyGroupManagers([FromQuery] string itcode) { if (ConfigInfo.HasMainHost) { - return Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowMyGroupManagers").Result; + return await Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowMyGroupManagers"); } var tenant = Wtm.LoginUserInfo?.CurrentTenant; var rv = Wtm.DC.Set().Where(x=>x.UserCode == itcode) @@ -115,13 +115,13 @@ public IActionResult GetWorkflowMyGroupManagers([FromQuery] string itcode) [HttpGet("[action]")] [Public] [NoLog] - public IActionResult GetWorkflowRoles([FromQuery] string[] ids) + public async Task GetWorkflowRoles([FromQuery] string[] ids) { if (ConfigInfo.HasMainHost) { - return Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowRoles").Result; + return await Request.RedirectCall(Wtm, "/_WorkflowApi/GetWorkflowRoles"); } var tenant = Wtm.LoginUserInfo?.CurrentTenant; var rv = Wtm.DC.Set().CheckIDs(ids.ToList()) diff --git a/src/WalkingTec.Mvvm.TagHelpers.LayUI/FlowInfoTagHelper.cs b/src/WalkingTec.Mvvm.TagHelpers.LayUI/FlowInfoTagHelper.cs index bd3217d0c..91da10b76 100644 --- a/src/WalkingTec.Mvvm.TagHelpers.LayUI/FlowInfoTagHelper.cs +++ b/src/WalkingTec.Mvvm.TagHelpers.LayUI/FlowInfoTagHelper.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; using WalkingTec.Mvvm.Core; @@ -12,12 +13,12 @@ namespace WalkingTec.Mvvm.TagHelpers.LayUI public class FlowInfoTagHelper : BaseElementTag { public ModelExpression Vm { get; set; } - public override void Process(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { - List data = new List(); + List data = new List(); if (Vm?.Model is IBaseCRUDVM vm) { - data = vm.GetWorkflowTimeLineAsync().Result; + data = await vm.GetWorkflowTimeLineAsync(); } output.TagName = "ul"; diff --git a/src/WalkingTec.Mvvm.TagHelpers.LayUI/Form/FieldSetTagHelper.cs b/src/WalkingTec.Mvvm.TagHelpers.LayUI/Form/FieldSetTagHelper.cs index 50432b056..2a88a9130 100644 --- a/src/WalkingTec.Mvvm.TagHelpers.LayUI/Form/FieldSetTagHelper.cs +++ b/src/WalkingTec.Mvvm.TagHelpers.LayUI/Form/FieldSetTagHelper.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Microsoft.AspNetCore.Razor.TagHelpers; namespace WalkingTec.Mvvm.TagHelpers.LayUI @@ -10,7 +11,7 @@ public class FieldSetTagHelper : BaseElementTag public string Title { get; set; } public FieldSetStyleEnum FieldSetStyle { get; set; } - public override void Process(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { output.TagName = "fieldset"; if (FieldSetStyle == FieldSetStyleEnum.Default) @@ -22,7 +23,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output) output.Attributes.SetAttribute("class", "layui-elem-field layui-field-title"); } string content = $@"{Title}"; - var innerContent = output.GetChildContentAsync().Result.GetContent(); + var innerContent = (await output.GetChildContentAsync()).GetContent(); if (string.IsNullOrEmpty(innerContent?.Trim()) == false) { content += $@"
{innerContent}
"; diff --git a/src/WalkingTec.Mvvm.TagHelpers.LayUI/Form/SelectorTagHelper.cs b/src/WalkingTec.Mvvm.TagHelpers.LayUI/Form/SelectorTagHelper.cs index 928eedc60..b30d2863a 100644 --- a/src/WalkingTec.Mvvm.TagHelpers.LayUI/Form/SelectorTagHelper.cs +++ b/src/WalkingTec.Mvvm.TagHelpers.LayUI/Form/SelectorTagHelper.cs @@ -1,3 +1,4 @@ +using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; using System.Text.Json; @@ -121,7 +122,7 @@ public class SelectorTagHelper : BaseFieldTag typeof(IEnumerable) }; - public override void Process(TagHelperContext context, TagHelperOutput output) + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { if (context.Items.ContainsKey("inselector") == false) { @@ -254,7 +255,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output) searcher.CopyContext(listVM); searcher.DoInit(); } - var content = output.GetChildContentAsync().Result.GetContent().Trim(); + var content = (await output.GetChildContentAsync()).GetContent().Trim(); #region 移除因 RowTagHelper 生成的外层 div 即
diff --git a/test/WalkingTec.Mvvm.Admin.Test/FrameworkUserApiTest.cs b/test/WalkingTec.Mvvm.Admin.Test/FrameworkUserApiTest.cs index fa3bc2857..6e9df20e5 100644 --- a/test/WalkingTec.Mvvm.Admin.Test/FrameworkUserApiTest.cs +++ b/test/WalkingTec.Mvvm.Admin.Test/FrameworkUserApiTest.cs @@ -27,7 +27,7 @@ public FrameworkUserApiTest() [TestMethod] public void SearchTest() { - var rv = _controller.Search(new FrameworkUserSearcher()); + var rv = _controller.Search(new FrameworkUserSearcher()).Result; Assert.IsTrue(string.IsNullOrEmpty((rv as ContentResult)?.Content)==false); }