Webアプリ.csproj
・TargetFramework
net5.0 に変更。
・nugetパッケージ
Microsoft.AspNetCore.App 2.2 を削除。
Microsoft.AspNetCore.Razor.Design 2.2 を削除。
Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv を、5.0に更新。
Microsoft.VisualStudio.Web.CodeGeneration.Design を、5.0に更新。
Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore 5.0 を、追加。
Microsoft.AspNetCore.Identity.EntityFrameworkCore 5.0 を、追加。
Microsoft.AspNetCore.Identity.UI 5.0 を、追加。
Microsoft.Data.SqlClient 3.0 を、追加。
Microsoft.EntityFrameworkCore 5.0 を、追加。
Microsoft.EntityFrameworkCore.SqlServer 5.0 を、追加。
Microsoft.EntityFrameworkCore.Tools 5.0 を、追加。
変更後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<ItemGroup> <PackageReference Include="BuildBundlerMinifier" Version="3.2.449" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="5.0.11" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="5.0.11" /> <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="5.0.11" /> <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv" Version="5.0.11" /> <PackageReference Include="Microsoft.Data.SqlClient" Version="3.0.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="5.0.11" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.11" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="5.0.11"> <PrivateAssets>all</PrivateAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> </PackageReference> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="5.0.2" /> <PackageReference Include="Sendgrid" Version="9.24.4" /> </ItemGroup> |
ApplicationDbContext.cs
・ChangeTracker.QueryTrackingBehavior 設定を追加。
変更後
1 2 3 4 5 6 7 8 9 10 11 12 |
using Microsoft.Data.SqlClient; public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking; } |
CustomTokenProvider.cs
・loggerパラメータを追加。
変更後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; namespace xxxxxx.TokenProviders { #region snippet1 public class CustomEmailConfirmationTokenProvider<TUser> : DataProtectorTokenProvider<TUser> where TUser : class { public CustomEmailConfirmationTokenProvider(IDataProtectionProvider dataProtectionProvider, IOptions<EmailConfirmationTokenProviderOptions> options, ILogger<DataProtectorTokenProvider<TUser>> logger) : base(dataProtectionProvider, options, logger) { } } public class EmailConfirmationTokenProviderOptions : DataProtectionTokenProviderOptions { public EmailConfirmationTokenProviderOptions() { Name = "EmailDataProtectorTokenProvider"; TokenLifespan = TimeSpan.FromHours(4); } } #endregion public class CustomPasswordResetTokenProvider<TUser> : DataProtectorTokenProvider<TUser> where TUser : class { public CustomPasswordResetTokenProvider(IDataProtectionProvider dataProtectionProvider, IOptions<PasswordResetTokenProviderOptions> options, ILogger<DataProtectorTokenProvider<TUser>> logger) : base(dataProtectionProvider, options, logger) { } } public class PasswordResetTokenProviderOptions : DataProtectionTokenProviderOptions { public PasswordResetTokenProviderOptions() { Name = "PasswordResetDataProtectorTokenProvider"; TokenLifespan = TimeSpan.FromHours(3); } } } |
Startup.cs
・.AddDefaultUI() のパラメータを削除。
・services.AddSession(options => の設定対象から、CookieDomain、CookieHttpOnly、CookiePath、CookieSecure を削除。
・Configure(IApplicationBuilder app, IHostingEnvironment env) に、app.UseRouting()、app.UseAuthorization() を追加。
・app.UseMvc() を app.UseEndpoints() に変更。
変更後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 |
using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using xxxxxx.Data; using xxxxxx.Services; using xxxxxx.TokenProviders; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Mvc.Razor; using System.Globalization; using Microsoft.AspNetCore.Localization; using Microsoft.Extensions.Caching.Memory; using Microsoft.AspNetCore.HttpOverrides; using System.Net; using System.IO; namespace xxxxxx { public class MyMemoryCache { public MemoryCache Cache { get; set; } public MyMemoryCache() { Cache = new MemoryCache(new MemoryCacheOptions { SizeLimit = 10000, // 使用量上限(IMemoryCacheオブジェクト数) CompactionPercentage = 0.30 // 使用量上限に達した時に空ける容量 }); } } public class Startup { private CultureInfo[] supportedCultures = new[] { new CultureInfo("en"), new CultureInfo("ja"), }; public IConfiguration Configuration { get; } public const string CurrentDirectory = "/var/aspnet/xxxxxx/"; public Startup(IConfiguration configuration, IHostingEnvironment env) { try { var os = Environment.OSVersion.ToString(); if (os.IndexOf("Windows") > -1) { // デバッグ実行 Configuration = configuration; return; } // Windowsじゃなかったら本番環境とみなす。Debugシンボルが使えない。 Environment.CurrentDirectory = CurrentDirectory; Console.WriteLine("----------------------------------------------------------------------------"); Console.WriteLine($"OS : {os}"); Console.WriteLine($"env.ContentRootPath : {env.ContentRootPath}"); Console.WriteLine($"env.WebRootPath : {env.WebRootPath}"); Console.WriteLine($"Environment.CurrentDirectory : {Environment.CurrentDirectory}"); Console.WriteLine($"Directory.GetCurrentDirectory() : {Directory.GetCurrentDirectory()}"); Console.WriteLine("----------------------------------------------------------------------------"); //Configuration = configuration; Configuration = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()) .AddEnvironmentVariables() .AddJsonFile("appsettings.json", false, true).Build(); } catch (Exception ex) { ExceptionSt.ExceptionCommon(ex); throw; } } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { try { var os = Environment.OSVersion.ToString(); services.AddTransient<CustomEmailConfirmationTokenProvider<IdentityUser>>(); services.AddTransient<CustomPasswordResetTokenProvider<IdentityUser>>(); services.AddTransient<IEmailSender, EmailSender>(); services.Configure<DataProtectionTokenProviderOptions>(o => o.TokenLifespan = TimeSpan.FromHours(3)); services.Configure<AuthMessageSenderOptions>(Configuration.GetSection("SendGrid")); services.Configure<RequestLocalizationOptions>(options => { options.DefaultRequestCulture = new RequestCulture("ja"); options.SupportedCultures = supportedCultures; options.SupportedUICultures = supportedCultures; }); services.Configure<IdentityOptions>(options => { // Default Lockout settings. options.Lockout.AllowedForNewUsers = true; // 新しいユーザーもロックアウト対象にする。 options.Lockout.MaxFailedAccessAttempts = 10; // 10回連続でログインに失敗したらロックアウト options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromHours(2); // ロックアウトが発生したら、その後2時間ログインできない。 // Default Password settings. options.Password.RequireDigit = true; // パスワードには、0 ~ 9 までの数値が必要です。 options.Password.RequireLowercase = true; // パスワードに小文字の文字が必要です。 options.Password.RequireUppercase = true; // パスワードに大文字が必要です。 options.Password.RequireNonAlphanumeric = true; // パスワードに英数字以外の文字が必要です。 options.Password.RequiredLength = 8; // パスワードの最小長。 options.Password.RequiredUniqueChars = 1; // パスワードに同じ文字は含めない。1は同じ文字を1つまで使えるという設定。 }); services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), sqlServerOptions => sqlServerOptions.CommandTimeout(60)) // 各SQLの実行を最大1分待つ。ユーザーが耐えられる限界。 ); services.AddDefaultIdentity<IdentityUser>(config => { config.SignIn.RequireConfirmedEmail = true; config.Tokens.ProviderMap.Add("CustomEmailConfirmation", new TokenProviderDescriptor( typeof(CustomEmailConfirmationTokenProvider<IdentityUser>))); config.Tokens.EmailConfirmationTokenProvider = "CustomEmailConfirmation"; config.Tokens.ProviderMap.Add("CustomPasswordReset", new TokenProviderDescriptor( typeof(CustomPasswordResetTokenProvider<IdentityUser>))); config.Tokens.PasswordResetTokenProvider = "CustomPasswordReset"; }) .AddDefaultUI() .AddEntityFrameworkStores<ApplicationDbContext>(); services.AddMemoryCache(); services.AddSingleton<MyMemoryCache>(); if (os.IndexOf("Windows") > -1) { // デバッグ実行モード。nonセキュア。 services.AddSession(options => { options.Cookie.Name = "xxxxxxWorks.Session"; options.Cookie.IsEssential = true; }); } else { // 本番モード。セキュア。 services.AddSession(options => { ////options.CookieName = "__Secure-xxxxxx"; //options.CookieDomain = "xxxxxx.com"; //options.CookieHttpOnly = true; //options.CookiePath = "/"; //options.CookieSecure = CookieSecurePolicy.Always; //options.Cookie.Name = "__Secure-xxxxxx"; options.Cookie.Domain = "xxxxxx.com"; options.Cookie.Path = "/"; options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; options.Cookie.MaxAge = TimeSpan.FromDays(30); options.Cookie.SameSite = SameSiteMode.Lax; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; //options.Cookie.Expiration = TimeSpan.FromDays(30); // エラーになる // Set a short timeout for easy testing. //options.IdleTimeoutx = TimeSpan.FromSeconds(10); // Make the session cookie essential }); } services.AddLocalization(options => options.ResourcesPath = "Resources"); services.AddMvc() .SetCompatibilityVersion(CompatibilityVersion.Version_2_2) .AddSessionStateTempDataProvider() .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix) .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResource)); }); } catch (Exception ex) { ExceptionSt.ExceptionCommon(ex); throw; } } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { try { app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); app.UseExceptionHandler("/Home/Error"); // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); app.UseRequestLocalization(new RequestLocalizationOptions { DefaultRequestCulture = new RequestCulture("ja"), // Formatting numbers, dates, etc. SupportedCultures = supportedCultures, // UI strings that we have localized. SupportedUICultures = supportedCultures }); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseSession(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{i?}"); endpoints.MapRazorPages(); }); } catch (Exception ex) { ExceptionSt.ExceptionCommon(ex); throw; } } } } |
データベース処理.cs
・using System.Data.SqlClient; 行を削除。
・using Microsoft.Data.SqlClient; 行を追加。
・ExecuteSqlCommand() を ExecuteSqlRaw() に変更。
・FromSql() を FromSqlRaw() に変更。
変更後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Threading.Tasks; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using xxxxxx.Models; using xxxxxx.Common; using xxxxxxEngine; namespace xxxxxx.Data { public static class SP_UserSetting { public static void Insert(ApplicationDbContext dbContext, long No, string email, string nickname, Gender Gender, DateTime BirthDate, int Career, string IPv4) { dbContext.Database .ExecuteSqlRaw("EXECUTE usr.spUserSetting_Insert @No, @Email, @Nickname, @Gender, @BirthDate, @Career, @IPv4", new SqlParameter("@No", No), new SqlParameter("@Email", email), new SqlParameter("@Nickname", nickname), new SqlParameter("@Gender", Gender), new SqlParameter("@BirthDate", BirthDate), new SqlParameter("@Career", Career), new SqlParameter("@IPv4", IPv4) ); } public static List<UserSetting> SelectProfile(ApplicationDbContext dbContext, long No) { return dbContext.UserSettingProfile .FromSqlRaw("EXECUTE usr.spUserSetting_SelectProfile @No", new SqlParameter("@No", No)) .ToList(); } } } |
データクラス.cs + xxxx.js
・データクラスのインスタンスをjsonデータにシリアライズする際、データクラスメンバ名を DataMember(Name = “xxxxxx”) で短縮していた場合、それはできなくなっているので、変数名をそのまま参照するように変更。
※データクラスのメンバ名の開始文字が大文字(WordList)でも、JavaScriptで参照する際は小文字始まり(wordList)で記述する必要あり。
C#の変更前と後
1 2 3 4 5 6 7 |
[DataContract] public class SvgWordMapJS { [DataMember(Name = "w")] // <- .net core 2.2 ではシリアライズ後の変数名がこれになっていたが、5.0は変数名そのまま public List<RelatedKeywordJS> WordList { get; set; } |
1 2 3 4 5 6 |
[DataContract] public class SvgWordMapJS { public List<RelatedKeywordJS> WordList { get; set; } |
JavaScriptの変更前と後
1 2 3 |
const wordList = data["w"]; |
1 2 3 |
const wordList = data.wordList; |
FolderProfile.pubxml
・TargetFramework
net5.0 に変更。
変更後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<?xml version="1.0" encoding="utf-8"?> <!-- このファイルは、Web プロジェクトの発行 / パッケージ処理で使用されます。この MSBuild ファイルを編集すると、 この処理の動作をカスタマイズできます。詳細については、https://go.microsoft.com/fwlink/?LinkID=208121 を参照してください。 --> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <WebPublishMethod>FileSystem</WebPublishMethod> <PublishProvider>FileSystem</PublishProvider> <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration> <LastUsedPlatform>x64</LastUsedPlatform> <SiteUrlToLaunchAfterPublish /> <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish> <ExcludeApp_Data>False</ExcludeApp_Data> <TargetFramework>net5.0</TargetFramework> <RuntimeIdentifier>linux-x64</RuntimeIdentifier> <ProjectGuid>797a0238-d001-4edf-9f18-3071614ef123</ProjectGuid> <SelfContained>false</SelfContained> <_IsPortable>true</_IsPortable> <publishUrl>C:\work\Deploy\xxxxxx</publishUrl> <DeleteExistingFiles>True</DeleteExistingFiles> </PropertyGroup> </Project> |
Testプロジェクト.csproj
・TargetFramework
net5.0 に変更。
・nugetパッケージ
Microsoft.NET.Test.Sdk を、17.0に更新。
MSTest.TestAdapter を、2.2に更新。
MSTest.TestFramework を、2.2に更新。
System.Text.Encoding.CodePages を、5.0に更新。
変更後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>net5.0</TargetFramework> <IsPackable>false</IsPackable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" /> <PackageReference Include="MSTest.TestAdapter" Version="2.2.7" /> <PackageReference Include="MSTest.TestFramework" Version="2.2.7" /> <PackageReference Include="System.Text.Encoding.CodePages" Version="5.0.0" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\xxxxx\xxxxx.csproj" /> </ItemGroup> </Project> |
/usr/bin/dotnet
・Linux上でAsp.Netを起動する際のコマンドパラメータ
–server.urls から –urls へ変更。
変更後
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# vi /etc/systemd/system/xxxxx.service [Unit] Description=xxxxx [Service] WorkingDirectory=/var/aspnet/xxxxx/ ExecStart=/usr/bin/dotnet /var/aspnet/xxxxx/xxxxx.dll --urls=http://localhost:80 Restart=always RestartSec=10 KillSignal=SIGINT SyslogIdentifier=xxxxx_Web User=root Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target |
コメント