SQL Server で 日付を取得する
SELECT CURRENT_TIMESTAMP --結果 = 2020-07-27 10:00:06.527
SELECT GETDATE() --結果 = 2020-07-27 10:00:06.527
SELECT SYSDATETIME() --結果 = 2020-07-27 10:00:06.5297366
SELECT SYSDATETIMEOFFSET() --結果 = 2020-07-27 10:00:06.5297366 +09:00
SELECT GETUTCDATE() --結果 = 2020-07-27 01:00:06.527
SELECT SYSUTCDATETIME() --結果 = 2020-07-27 01:00:06.5297366
SELECT CURRENT_TIMEZONE ( ) --結果 = (UTC+09:00) 大阪、札幌、東京
SELECT
GETDATE() ,
CURRENT_TIMEZONE ( ) ,
SYSDATETIMEOFFSET()
wsl -u root
(ここから先は unix ターミナルとなります)
whoami
sudo passwd root
以上です。
apt update
apt install tree
if "%PROCESSOR_ARCHITECTURE%" equ "x86" (
echo Windows 32ビットです
) else (
echo Windows64ビットです
)
pause
mu\y.ini に以下を追加
[mysqld]
innodb_use_native_aio=0
innodb_flush_method=normal
chcp 65001
echo off
echo;
if "%PROCESSOR_ARCHITECTURE%" EQU "x86" (
echo ●●● お使いのWindowsは32bitです ●●●
) else (
echo ●●● お使いのWindowsは64bitです ●●●
)
echo;
pause
REM cmd /k
var dic = new Dictionary<string, string>();
dic["hoge"] = "ほげほげ";
dic["fuga"] = "ふがふが";
string k = "hoge";
string v = (dic.ContainsKey(k)) ? dic[k] : null;
Console.WriteLine($"vの値は : {v}");
値が存在しないキーを渡した時は null が返ります。
using System.Linq;
int[] ary1 = new int[] { 1, 1, 2, 3, 3, 1 };
//一意の要素を抜き出して、配列に変換する
int[] resultArray = ary1.Distinct().ToArray();
@Html.Partial("MyPartial", new ViewDataDictionary(ViewData) { { "BookId", Model.Id } })
値は @ViewData["BookId"] です。
1. Windowsのディスクファイル(実はフォルダ)を右クリックし「パッケージの内容表示」を選択
2. 「xxxxxx.vmx」というファイル (xxxxxxx は環境によって変わります)をエディタで開いて次の行を一番後ろの行に追加する
mainMem.useNamedFile = "FALSE"
MemTrimRate = “0”
sched.mem.pshare.enable = "FALSE"
prefvmx.useRecommendedLockedMemSize = "TRUE"
https://www.vector.co.jp/soft/dl/win95/util/se295331.html
解凍してできるファイルの中から nkf32.exe を取り出して使用します。
nkf32.exe -w --overwrite myfile.txt
nkf32.exe -w8 --overwrite myfile.txt
var unsavedEntries = context.ChangeTracker.Entries().ToList();
var category = "C#";
var posts = context.Posts
.FromSql($"select * from Posts where Category = {category} and IsPrivate = 0")
.ToList();
SELECT * FROM myTable WHERE ID IN (1,2,3,4,5)
int[] ids = { 1, 2, 3, 4, 5};
var query = db.myTable.Where(item => ids.Contains(item.ID));
var badGuyIds = badGuys.Select(x => x.PersonId).ToArray();
context.Persons
.Where(p => !badGuyIds.Contain(p.PersonId))
.ToList();
ChangeTracker を使用します。
var modifiedEntries = context.ChangeTracker
.Entries()
.Where(x => x.State == EntityState.Modified)
.Select(x =>x.Entity)
.ToList();
5秒待つサンプル
var waitTask = Task.Delay( 5000 ); // msec
waitTask.Wait();
// ディレクトリない場合は作成
var tmpDir = "c:\test\";
if (! System.IO.Directory.Exists(tmpDir) ){
System.IO.Directory.CreateDirectory(tmpDir);
}
string stringValue = "1.35";
decimal d = System.Convert.ToDecimal( stringValue );
次のような変換メソッドがあります
ChangeType
FromBase64CharArray
FromBase64String
FromHexString
GetTypeCode
IsDBNull
ToBase64CharArray
ToBase64String
ToBoolean
ToByte
ToChar
ToDateTime
ToDecimal
ToDouble
ToHexString
ToInt16
ToInt32
ToInt64
ToSByte
ToSingle
ToString
ToUInt16
ToUInt32
ToUInt64
TryFromBase64Chars
TryFromBase64String
TryToBase64Chars
using (var context = new ShoppingContext())
{
var product = context.Products.Single(x => x.Name == "Test");
context.Products.Remove(product); // 削除
context.Remove(product); // 削除(こちらでもOK)
context.SaveChanges(); // 削除の適用
}
@($"{Context.Request.Scheme}://{Context.Request.Host}{Context.Request.Path}{Context.Request.QueryString}")
例 : ディレクトリ mydir を高速に削除します
cd "消したいディレクトリの親ディレクトリ"
rmdir /q /s mydir
public class HomeController : Controller
{
private IHostingEnvironment Environment;
public HomeController(IHostingEnvironment _environment)
{
Environment = _environment;
}
public IActionResult Index()
{
string wwwPath = this.Environment.WebRootPath;
string contentPath = this.Environment.ContentRootPath;
return View();
}
}
public class HomeController : Controller
{
private IWebHostEnvironment Environment;
public HomeController(IWebHostEnvironment _environment)
{
Environment = _environment;
}
public IActionResult Index()
{
string wwwPath = this.Environment.WebRootPath;
string contentPath = this.Environment.ContentRootPath;
return View();
}
}
string folder = "c:\\temp\\";
if ( ! Directory.Exists( folder ) )
{
Directory.CreateDirectory( folder );
}
web.config
<?xml version="1.0"?>
<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>
</configuration>
ダンプしたいときに使用すると便利でしょう。
class Foo {
public int A {get;set;}
public string B {get;set;}
}
...
Foo foo = new Foo {A = 1, B = "abc"};
foreach(var prop in foo.GetType().GetProperties()) {
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(foo, null));
}
コントローラー
ViewBag.title = "タイトルです-";
ViewBag.collections = collections;
return View("/Views/test.cshtml");
ビュー ( cshtml )
@foreach(var data in (@ViewBag.collections)) {
@data.name
}
</table>
ビュー ( cshtml )
@(User.Identity.IsAuthenticated ? "auth" : "anon")
PM> Install-Package AspNetCore.RouteAnalyzer
Control + Shift + P
Nuget Install
AspNetCore.RouteAnalyzer
Startup.cs
using AspNetCore.RouteAnalyzer; // Add
.....
public void ConfigureServices(IServiceCollection services)
{
....
services.AddRouteAnalyzer(); // Add
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
....
app.UseMvc(routes =>
{
routes.MapRouteAnalyzer("/routes"); // Add
....
});
}
Cannot use 'AspNetCore.RouteAnalyzer.Inner.Router' with Endpoint Routing
このようなエラーになる場合は次のように書き換えましょう
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
↓
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
System.DateTime dt = System.DateTime.Now;
string result = dt.ToString("yyyy-MM-dd HH:mm:ss");
Console.WriteLine(result);
result = dt.ToString("yyyy年MM月dd日 HH時mm分ss秒");
Console.WriteLine(result);
有名どころとして Windowsの node.js 用のバージョン管理ソフトがあります
nvm-windows
nodist
https://github.com/coreybutler/nvm-windows/releases nvm-setup.zip をダウンロードし、インストールする。
バージョンの確認
nvm version
nvm list available
nvm install 10.16.3
nvm list
一覧で結果が帰ってきます
14.15.0
* 10.16.3 (Currently using 64-bit executable)
nvm use 10.16.3
nvm use 14.15.0
node -v
https://github.com/coreybutler/nvm-windows/releases
から 最新の nvm-update.zip をダウンロードし、解凍して実行してインストールする。
管理者権限でコマンドプロンプトを立ち上げ nvm use <使いたいバージョン>を実行します
string message = string.Format("こんにちは、{0}さん。今は{1}時です。", name, hour);
↓
string message = $"こんにちは、{name}さん。 今は{hour}時です。";
このようなリレーションを設定してみます
Memo <----- 多対多リレーション -----> Category
namespace EFCoreFilterApp.Models
{
public class Category
{
public int ID { get; set; }
public long TenantID { get; set; }
public string Title { get; set; }
public bool IsDeleted { get; set; }
public ICollection<CategoryMemo> CategoryMemos { get; set; }
}
}
public class Memo
{
public int ID { get; set; }
public int CategoryID { get; set; }
public long TenantID { get; set; }
public string Title { get; set; }
public bool IsDeleted { get; set; }
public ICollection<CategoryMemo> CategoryMemos { get; set; }
}
namespace EFCoreFilterApp.Models
{
public class CategoryMemo
{
public int MemoId { get; set; }
public Memo Memo { get; set; }
public int CategoryId { get; set; }
public Category Category { get; set; }
}
}
namespace EFCoreFilterApp.Data
{
public class MyContext : DbContext
{
public MyContext(DbContextOptions options) : base(options) {}
public DbSet<Memo> Memo { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<CategoryMemo> CategoryMemo { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<CategoryMemo>().HasKey(bc => new { bc.MemoId, bc.CategoryId });
}
}
}
Includeメソッドで EagerLoading が行われます。
通常は(n+1)を起こさないためこのメソッドで取得するといいでしょう。
複雑なSQLになるときは実際に発行されるSQL文を見て検討が必要です。
var memos_m4 = _context.Memo
.Include(r => r.CategoryMemos)
.ToList();
引用 : https://blog.georgekosmidis.net/2019/08/08/action-results-in-asp-net-core-apis/
https://qiita.com/dongsu-iis/items/dd2d09692b6324bdd31b
https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.actionresult?view=aspnetcore-2.1
型 | 実装方法 | 説明 |
---|---|---|
ViewResult | View() | Razorエンジンが生成したHTMLコンテンツを返します |
PartialViewResult | PartialView() | Razorエンジンが生成した部分ビューのHTMLコンテンツを返します |
ContentResult | Content() | 生のテキストコンテンツを返します |
JsonResult | Json() | 文字通りJSON文字列 |
FileResult | File() | ファイル内容をブラウザーに送信、内容はByte配列 |
RedirectResult | Redirect() | 特定なURLへリダイレクトする |
RedirectToRouteResult | RedirectToAction(), RedirectToRoute() | 特定なコントローラーorアクションメソッドへリダイレクトする |
Nugetパッケージマネージャーから xUnit , Moq をインストールします。
dotnet new xunit -o tests -n MyApp.Test
tests フォルダにテスト用ファイルが作成されます。
cd tests
dotnet add reference ../MyApp.csproj
tests/MyApp.Test.csproj に MyApp.csproj の参照が追記されます
テスト実行前にフレームワークとテストフレームワークのバージョンを合わせておきましょう
tests/MyApp.Test.csproj
<TargetFramework>netcoreapp2.2</TargetFramework>
<PackageReference Include="xunit" Version="2.4.1" />
tests/UnitTest1.cs へテストケースを記述します
using System;
using Xunit;
using Moq;
namespace EFCoreFilterApp.Test
{
public class UnitTest1
{
[Fact]
public void Test1()
{
var mockRepo = new Mock<MyContext>();
var controller = new HomeController(mockRepo.Object);
Assert.True(false);
}
}
}
(↑ このテストケースは失敗します。)
テストの実行
(テストはプロジェクトのトップディレクトリから実行します)
dotnet test
テストケースの書き換え
Assert.True(false);
↓
Assert.True(true);
テストの再実行
cd tests
dotnet test
これでテストの準備が整いました、あとはテストケースを書いてテストを実行しましょう。
こちらにとてもうまくまとまっています。
xUnitで使用できるAssertion - Symfoware
等しいか(Equal)
等しくないか(NotEqual)
同じインスタンスでないか(NotSame)
同じインスタンスであるか(Same)
コレクションに含まれるか(Contains)
コレクションに含まれないか(DoesNotContain)
エラーが発生しないか(DoesNotThrow)
指定範囲に含まれるか(InRange)
指定クラスのインスタンスであるか(IsAssignableFrom)
空であるか(Empty)
Falseであるか(False)
指定のインスタンスであるか(IsType)
空でないか(NotEmpty)
指定のインスタンスではないか(IsNotType)
Nullでないか(NotNull)
nullであるか(Null)
trueであるか(True)
範囲に含まれないか(NotInRange)
指定のエラーが発生するか(Throws)
引用 : https://bit.ly/319sYVh 参考 : https://bit.ly/31eH5Jd
using Xunit.Abstractions;
private readonly ITestOutputHelper _output;
public Test2(ITestOutputHelper output)
{
_output = output;
}
_output.WriteLine("ほげほげ");
● c# の いにしえの ArrayListを使ってみる
using System.Collections;
myList を初期化( List との違いは 型指定がないことです。逆に出力するときに毎回キャストする必要があります。 )
ArrayList myList = new ArrayList();
myList.Add("ほげほげ");
例 : 改行(\n)で結合します。
Debug.WriteLine( string.Join("\n", (string[])myList.ToArray(typeof(string))) );
(キャストする必要があるのでこのような書き方になります。)
myList.Clear();
for (int i=0; i < myList.Count; i++) {
Debug.WriteLine("=======");
Debug.WriteLine(myList[i]);
Debug.WriteLine("=======");
}
Method | Usage |
---|---|
Add |
Adds a new entity to DbContext with Added state and starts tracking it.
This new entity data will be inserted into the database when SaveChanges() is called.
|
AddAsync | Asynchronous method for adding a new entity to DbContext with Added state and starts tracking it.
This new entity data will be inserted into the database when SaveChangesAsync() is called.
|
AddRange |
Adds a collection of new entities to DbContext with Added state and starts tracking it.
This new entity data will be inserted into the database when SaveChanges() is called.
|
AddRangeAsync | Asynchronous method for adding a collection of new entities which will be saved on SaveChangesAsync(). |
Attach |
Attaches a new or existing entity to DbContext with Unchanged state and starts tracking it.
|
AttachRange |
Attaches a collection of new or existing entities to DbContext with Unchanged state and starts tracking it.
|
Entry |
Gets an EntityEntry for the given entity. The entry provides access to change tracking information and operations for the entity.
|
Find | Finds an entity with the given primary key values. |
FindAsync | Asynchronous method for finding an entity with the given primary key values. |
Remove | Sets Deleted state to the specified entity which will delete the data when SaveChanges() is called. |
RemoveRange | Sets Deleted state to a collection of entities which will delete the data in a single DB round trip when SaveChanges() is called. |
SaveChanges | Execute INSERT, UPDATE or DELETE command to the database for the entities with Added, Modified or Deleted state. |
SaveChangesAsync | Asynchronous method of SaveChanges() |
Set | Creates a DbSet that can be used to query and save instances of TEntity. |
Update | Attaches disconnected entity with Modified state and start tracking it. The data will be saved when SaveChagnes() is called. |
UpdateRange | Attaches a collection of disconnected entities with Modified state and start tracking it. The data will be saved when SaveChagnes() is called. |
OnConfiguring | Override this method to configure the database (and other options) to be used for this context. This method is called for each instance of the context that is created. |
OnModelCreating | Override this method to further configure the model that was discovered by convention from the entity types exposed in DbSet properties on your derived context. |
https://www.entityframeworktutorial.net/efcore/entity-framework-core-dbcontext.aspx
変数 base を使用します。
using System;
class CBase {
public virtual void Foo () {
Console.WriteLine("CBase.Foo");
}
}
class CClass : CBase {
public override void Foo () {
Console.WriteLine("CClass.Foo");
// baseという特殊な変数が定義されているのでそれを使う。
base.Foo();
}
}
class Program {
static void Main () {
CClass cobj1 = new CClass();
cobj1.Foo();
}
}
引用: https://pknight.hatenablog.com/entry/20130201/1359713754
https://gist.github.com/nphmuller/05ff66dfa67e1d02cdefcd785661a34d
Extensions/EFCoreDump.cs に以下の内容で保存
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query.Internal;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Query;
//using System.Collections.Generic;
//using System.Text;
namespace Extensions
{
public static class EFCoreDump
{
private static readonly TypeInfo QueryCompilerTypeInfo = typeof(QueryCompiler).GetTypeInfo();
private static readonly FieldInfo QueryCompilerField = typeof(EntityQueryProvider).GetTypeInfo().DeclaredFields.First(x => x.Name == "_queryCompiler");
private static readonly FieldInfo QueryModelGeneratorField = QueryCompilerTypeInfo.DeclaredFields.First(x => x.Name == "_queryModelGenerator");
private static readonly FieldInfo DataBaseField = QueryCompilerTypeInfo.DeclaredFields.Single(x => x.Name == "_database");
private static readonly PropertyInfo DatabaseDependenciesField = typeof(Database).GetTypeInfo().DeclaredProperties.Single(x => x.Name == "Dependencies");
public static string ToSql<TEntity>(this IQueryable<TEntity> query) where TEntity : class
{
var queryCompiler = (QueryCompiler)QueryCompilerField.GetValue(query.Provider);
var modelGenerator = (QueryModelGenerator)QueryModelGeneratorField.GetValue(queryCompiler);
var queryModel = modelGenerator.ParseQuery(query.Expression);
var database = (IDatabase)DataBaseField.GetValue(queryCompiler);
var databaseDependencies = (DatabaseDependencies)DatabaseDependenciesField.GetValue(database);
var queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false);
var modelVisitor = (RelationalQueryModelVisitor)queryCompilationContext.CreateQueryModelVisitor();
modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
var sql = modelVisitor.Queries.First().ToString();
return sql;
}
}
}
using Extensions;
var datas1 = _context.MyTable.ToList();
var datas2 = _context.MyTable.FromSql( "SELECT * FROM MyTable" ).ToList();
とすると自動的にデバッグコンソールに SQL 文が出力されます。 また任意のタイミングで取り出したいときは次のようにして Tosql() メソッドで取り出すことができます
string sql_result = _context.MyTable.FromSql( "SELECT * FROM MyTable" ).Tosql();
コードファーストではまず Model ファイルを変更してから、マイグレーションコマンドを実行します。
(例: Models/Memo.cs)の中のテーブル定義を変更する
public class Memo
{
public long ID { get; set; }
[Required]
public string Title { get; set; }
public string Content { get; set; }
}
dotnet ef migrations add <任意の文字列>
<任意の文字列> は 日付やモデル名変更内容を記述するといいでしょう
20201231_Memo_add_Content_column
dotnet ef migrations add 20201231_Memo_add_Content_column
dotnet ef database update
マイグレーションファイルの一覧を表示
dotnet ef migrations list
マイグレーション名の一覧が表示されます。
dotnet ef database update <戻したいマイグレーション名>
dotnet ef migrations remove
最新のマイグレーションファイル 1件を削除します。 (削除しようとするマイグレーションファイルが既にデータベースに適用されているときは削除エラーとなります)
DBテーブル「Memo」に対して必ず「WHERE isDeleted= 0」条件を加えます。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Memo>().HasQueryFilter(s => s.isDeleted== 0 ); // WHERE isDeleted= 0 に限定する
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using EFCoreFilterApp1.Models;
namespace EFCoreFilterApp1.Data
{
public class MyContext : DbContext
{
public MyContext(DbContextOptions options) : base(options)
{
}
public DbSet<Memo> Memo { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Memo>().HasQueryFilter(s => s.MYID == 2 ); // WHERE MYID = 2 に限定する
}
}
}
echo ===============================================================
echo .env をコピーします
copy C:\test.txt C:\folder\test.txt
if not %ERRORLEVEL% == 0 (
echo ■■■■■エラーが発生しました■■■■■: ファイルがコピーできませんでした。
echo ===============================================================
PAUSE
)
echo ===============================================================
"defaultProfile": "{61c54bbd-c2c6-5271-96e7-009a87ff44bf}",
↑ ここの値を コマンドプロンプトの guid に変更します。
"profiles":
{
"defaults":
{
// ● フォント設定
// "fontFace": "Cascadia Code",
"fontFace": "Meslo",
"fontSize": 11
},
"list":
[
...............................
非同期ではないメソッドから 非同期メソッドを呼ぶ場合は次のようにします。
var task = accessor.GetResponseAsync("http://hatenablog.com/");
task.Wait();
メソッドが ConfiguredTaskAwaitable を返す時は、次のようにして待ちます。
var taskAwaitable = client.SendEmailAsync(msg).ConfigureAwait(false);
taskAwaitable.GetAwaiter().GetResult();
public async Task<int> MyMethodAsync( int id )
{
..........
}
としておいて、
int result = await MyMethodAsync( 123456 );
とします。
参考 : https://blog.xin9le.net/entry/2012/07/30/123150
var task = accessor.GetResponseAsync("http://hatenablog.com/");
string result = task.Result;
引用: https://hiroronn.hatenablog.jp/entry/20171005/1507207811
(最小セット)
/// <summary>
/// メソッドの説明
/// </summary>
/// <param name="age">xxxxx</param>
/// <param name="name">xxxxx</param>
/// <returns>返される値の説明</returns>
public string MyMethod(int age, string name)
{
// ..........
}
https://marketplace.visualstudio.com/items?itemName=k--kato.docomment
/// を入力すると自動で挿入されます。
Windows で grepを行うにはサクラエディタを使用します
.\sakura.exe -GREPMODE -GFOLDER=C:\my_folder -GFILE="*.cs" -GKEY="検索文字列" -GOPT=SRP
https://qiita.com/ledsun/items/ca77c60aad424438cdd7
.vs/config/applicationhost.config
<binding protocol="http" bindingInformation="*:51727:localhost" />
<!-- この行を追加 -->
<binding protocol="http" bindingInformation="*:51727:192.168.1.99" />
<!-- / この行を追加 -->
コマンドプロンプトを管理者として実行する
netsh http add urlacl url=http://192.168.1.99:51727/ user=everyone
アップロードできる最大サイズを 100MBytes にセットする場合
Web.config 以下をセットする
<configuration>
<system.web>
<httpRuntime targetFramework="4.6.1" />
</system.web>
</configuration>
↓
<configuration>
<system.web>
<httpRuntime targetFramework="4.6.1" maxRequestLength="102400" />
</system.web>
</configuration>
aspx
<%--========== debugボタン ==========--%>
<asp:Literal ID="LiteralDebugButton01" runat="server"></asp:Literal>
<%--========== /debugボタン ==========--%>
c#
#if DEBUG
LiteralDebugButton01.Text = "<button>(構成:debug)の時だけ表示されるボタン</button>";
#endif
これでDebugの時だけボタンが表示されます。(Releaseにすると消えます。)
using System.Collections.Generic;
using System.Linq;
namespace MyExtension
{
public static class MyExtensionClass
{
/// <summary>配列がnullか長さがゼロの時 true を返します。それ以外は false を返します。</summary>
/// <param name="array">The array to test.</param>
/// <returns>true if the array parameter is null or has a length of zero; otherwise, false.</returns>
public static bool IsNullOrEmpty<T>(this T[] array)
{
return array == null || array.Length == 0;
}
}
}
使い方
using MyExtension;
string[] my_array = {};
if ( ! my_array .IsNullOrEmpty() )
{
// foreach などの処理を行います。
}
こちらの方法で foreach できます。
C #
public List<string> Sites = new List<string> { "StackOverflow", "Super User", "Meta SO" };
ASPX
<% foreach (var site in Sites) { %>
<div>
<%= site %>
</div>
<% } %>
Web.Config
<configuration>
<appSettings file="appsettings.config">
<add key="key1" value="aiueo" />
<add key="key2" value="abcdefg" />
C#
string setting1 = ConfigurationManager.AppSettings["key1"];
C#
// ファイルのbase64
var file_base64 = Session["file_base64"] as String;
ImgTweetFile.ImageUrl = @"data:image/png;base64," + file_base64;
aspx
<asp:Image id="ImgTweetFile" runat="server" />
1. CheckApi.aspx
↓
2. Twitterログイン画面
↓
3. TwitterCallback.aspx
全ての aspx.cs ファイルには次のようにキーをセットしておきましょう(もちろん設定ファイルに外だしするのがベスト)
using CoreTweet;
public const string CONSUMER_KEY = "OWCPpT5DZYA1....................";
public const string CONSUMER_SECRET = "lrtzd7MxAX3oDW.....................................................";
public const string OAUTH_CALLBACK = "http://YOUR-SERVER.TLD/TwitterCallback.aspx";
protected void Page_Load(object sender, EventArgs e)
{
var oauth_session = OAuth.Authorize(CONSUMER_KEY, CONSUMER_SECRET, OAUTH_CALLBACK, null);
var url = oauth_session.AuthorizeUri;
Session["OAuthSession"] = oauth_session;
Response.Redirect(oauth_session.AuthorizeUri.OriginalString);
}
protected void Page_Load(object sender, EventArgs e)
{
string oauth_token = Request.QueryString["oauth_token"];
string oauth_verifier = Request.QueryString["oauth_verifier"];
// OAuthSessionインスタンスを復元
var oauth_session = Session["OAuthSession"] as OAuth.OAuthSession;
if (oauth_session == null)
{
throw new HttpException(403, "oauth_session is null");
}
var token = oauth_session.GetTokens(oauth_verifier);
if (token == null)
{
throw new HttpException(403, "oauth token is null");
}
// ツイートする
postImageAndTweet(token);
}
protected void postImageAndTweet(CoreTweet.Tokens token)
{
// 画像をアップロード
//media 引数には FileInfo, Stream, IEnumerable<byte> が指定できます。
//また media_data 引数に画像を BASE64 でエンコードした文字列を指定することができます。
MediaUploadResult upload_result = token.Media.Upload(media: new FileInfo(@"C:\img\up_test.png"));
// 画像とテキストをツイート
string tweet_text = "ツイートのテストです";
token.Statuses.Update(new {
status = tweet_text ,
media_ids= new long[] { upload_result.MediaId }
});
}
base64 でエンコードした画像データを使用する場合は
string png_base64 = "iVBORw0K...........ggg==";
MediaUploadResult upload_result = token.Media.Upload(media_data: png_base64);
のように media_data で渡します。
c#の配列のnullチェック
private int[] array;
private void Update()
{
if (array != null)
{
foreach (var n in array)
{
Debug.Log(n);
}
}
}
var Clothes = new List<Cloth>() {
new Cloth {id = 7000, name = "MY-ITEM-7000"} ,
new Cloth {id = 7001, name = "MY-ITEM-7001"} ,
};
Clothes.ForEach(x =>
{
Debug.WriteLine(x.ToStringReflection());
});
こちらのファイルを読み込ませる必要があります
using System.Linq;
using System.Reflection;
/// <summary>
/// object型の拡張メソッドを管理するクラス
/// </summary>
public static class ObjectExtensions
{
private const string SEPARATOR = ","; // 区切り記号として使用する文字列
private const string FORMAT = "{0}:{1}"; // 複合書式指定文字列
/// <summary>
/// すべての公開フィールドの情報を文字列にして返します
/// </summary>
public static string ToStringFields<T>(this T obj)
{
return string.Join(SEPARATOR, obj
.GetType()
.GetFields(BindingFlags.Instance | BindingFlags.Public)
.Select(c => string.Format(FORMAT, c.Name, c.GetValue(obj))));
}
/// <summary>
/// すべての公開プロパティの情報を文字列にして返します
/// </summary>
public static string ToStringProperties<T>(this T obj)
{
return string.Join(SEPARATOR, obj
.GetType()
.GetProperties(BindingFlags.Instance | BindingFlags.Public)
.Where(c => c.CanRead)
.Select(c => string.Format(FORMAT, c.Name, c.GetValue(obj, null))));
}
/// <summary>
/// すべての公開フィールドと公開プロパティの情報を文字列にして返します
/// </summary>
public static string ToStringReflection<T>(this T obj)
{
return obj.ToStringProperties();
}
}
あらかじめこちらで SQL Server へ接続できるユーザーを作成します。
SQL Server へ 「SQL Server認証」でログインするユーザーを作成し .Net アプリのDB接続に使用する|プログラムメモ
.NET Coreでコードファーストを使ってDBを作成するまでは大きく分けて次の手順となります。
・1. csファイルの作成と編集
- モデルクラスの作成
- DBコンテキストの作成
- Startup.cs の ConfigureServices() メソッド内に コンテキスト読込を追加
・2. マイグレーションファイルの生成( dotnet ef migrations add )
・3. マイグレーションの実行( dotnet ef database update )
dotnet コマンドは PowerShell から実行します。(Visual Studioのコンソールではありません。)
Models/Memo.cs を以下のように作成
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace 【アプリ名】.Models
{
public class Memo
{
public int ID { get; set; }
public string Title { get; set; }
}
}
IDを表すカラム名は必ず大文字で「ID」である必要があります。
Data/MyContext.cs を以下の内容で作成
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using 【アプリ名】.Models;
namespace 【アプリ名】.Data
{
public class MyContext : DbContext
{
public MyContext( DbContextOptions options ) : base( options )
{
}
public DbSet<Memo> Memo { get; set; }
}
}
Startup.cs に以下の行を追加
using Microsoft.EntityFrameworkCore; を追加
using Microsoft.EntityFrameworkCore;
public void ConfigureServices(IServiceCollection services)
{
// コンテキストクラスを追加ここから
services.AddDbContext<MyContext>( options => options.UseSqlServer(
Configuration.GetConnectionString( "DefaultConnection" )
) );
// コンテキストクラスを追加ここまで
(options.UseSqlServer)は MS SQL Server を使うときに記述します。
(データベースの種類によって書き換えること)
dotnet tool install --global dotnet-ef
dotnet tool install --global dotnet-ef --version 3.0.0
あと Microsoft.EntityFrameworkCore.SqlServer もインストールしておいてください。
dotnet ef migrations add ver1.0
複数コンテキストがある場合はコンテキストを指定する必要があります。
dotnet ef migrations add __My__Ver1.2__ --context MyContex
このとき Migrations ディレクトリ内に次のようなファイルが生成されます。
20180704061421___My__Ver1.2__.cs
20180704061421___My__Ver1.2__.Designer.cs
dotnet ef migrations add __ApplicationDb__Ver1.2__ --context ApplicationDbContext
dotnet ef database update
dotnet ef database update --context MyContext
データベース全体を Drop します
dotnet ef database drop
dotnet ef database drop -f
複数コンテキストがある場合はコンテキストを指定する必要があります。 (ただしDB全体がdropされるので注意)
dotnet ef database drop --context ApplicationDbContext -f
vagrant init centos/7
vagrant up
vagrant ssh
Centos7の仮想マシンにssh接続したらインストールをしていきます
su -
yum update -y
yum install -y libunwind libicu lsof
sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod.rpm
yum list | grep dotnet
インストールする dotnet のバージョンを確認します
yum install -y dotnet-sdk-2.1.4.x86_64
上記コマンドのリストの中からインストールするパッケージを指定します
dotnet --version
このようなに dotnetのバージョンが帰ってくればOK (例)
2.1.4
dotnet new console -o myApp
cd myApp
dotnet run
これで
Hello World!
が表示されればOKです。
dotnet new mvc -o testApp
cd testApp
dotnet publish -o ./published -r linux-x64
dotnet published/testApp.dll
(これで内蔵サーバが立ちあがります)
Content root path: /home/vagrant/dotnet/testApp
Now listening on: http://localhost:5000
curl で接続を確認する
curl http://localhost:5000
確認できたら firewalld を適切に設定してください。
systemctl stop firewalld
lsof -i:5000
Google Chromeなどのブラウザから
192.168.33.10:5000
を開きます。
vi /etc/yum.repos.d/nginx.repo
こちらの内容を保存する
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/7/$basearch/
gpgcheck=0
enabled=1
nginxのインストール
yum install -y nginx
systemctl enable nginx
systemctl start nginx
nginx -v
Google Chromeなどのブラウザから
192.168.33.10
を開きます。nginxの画面が出ればOK
cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.backup
vi /etc/nginx/conf.d/default.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
↓ このように書き換えます
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
nginxの再起動
sudo nginx -s reload
sudo cat /var/log/audit/audit.log | grep nginx | grep denied
setsebool httpd_can_network_connect on -P
https://stackoverflow.com/questions/23948527/13-permission-denied-while-connecting-to-upstreamnginx
Google Chromeなどのブラウザから
192.168.33.10
を開きます。.NET Core MVC アプリケーションの画面が出ればOKです。
dotnet publish -o ./published -r centos.7-x64
あとは published フォルダを vagrant のサーバにアップして
dotnet ./published/アプリ名.dll
で起動します。
Programs.cs
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
↓
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
// 追加ここから
.UseKestrel(options =>
{
options.Listen(System.Net.IPAddress.Any, 5000);
})
// 追加ここまで
.Build();
}
・「ソリューションエクスプローラー」からプロジェクトを右クリックして「エクスプローラーでフォルダーを開く」
・「 project名.csproj」ファイルをエディタで開く
・次のように修正する
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
↓
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<RuntimeIdentifiers>win10-x64</RuntimeIdentifiers>
</PropertyGroup>
この状態で発行すると自己完結型で発行されます。
この時の「win10-x64」は以下の RIDカタログ を参考にしてください。
https://docs.microsoft.com/ja-jp/dotnet/core/rid-catalog
https://docs.microsoft.com/ja-jp/dotnet/core/deploying/#self-contained-deployments-scd
Web.config
<configuration>
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
</configuration>
ちなみに Apache だと .htaccess で次のように記述します。 .htaccess の場合
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin: "*"
</IfModule>
ASP .NETアプリ の「発行」時に MyConfig.xml など、独自の設定ファイルを発行させないようにするには
<プロジェクトフォルダ>/Properties/PublishProfiles/Profile.pubxmlに以下を追加します
<PropertyGroup>
の下に次の項目を追加します。
<ExcludeFilesFromDeployment>MyConfig.xml</ExcludeFilesFromDeployment>
.NET Coreが Linuxや Macに対応したのに合わせてデータベースツールも LinuxやMac対応できるツールが新しく Microsoftから出ています
https://github.com/Microsoft/sqlopsstudio
Mac, Linux Windows対応です。
apacheでいう .htaccess にあたるのが IIS の Web.config です。
このファイルに次のように記述します。
例) test.txt を非表示にする
Web.config
<configuration>
<system.webServer>
<security>
<requestFiltering>
<denyUrlSequences>
<add sequence="test" />
</denyUrlSequences>
<fileExtensions>
<add fileExtension=".txt" allowed="false" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>
<configuration>
.NET WEBアプリでは XSS対策として HTMLタグらしきものを送信するとエラーとなります。 エラーになると次のようなエラーが表示されます
アプリケーションでサーバー エラーが発生しました。
YourController.cs
[ValidateInput( false )]
を加えます。 例 )
[ValidateInput( false )]
public ActionResult Index( Entry model )
{
.....
}
Web.config
<system.web>
<customErrors defaultRedirect="~/Error/DefaultError.cshtml" mode="RemoteOnly">
<error statusCode="404" redirect="~/Error/NotFound" />
</customErrors>
mode="RemoteOnly"
にするとリモートでのみカスタムエラー画面が表示されます。
ローカルとリモート両方でカスタムエラー画面を表示させるには
mode="On"
とします。
引用 : https://www.wareko.jp/blog/post-21910
your-view-file.cshtml
@{
var baseUrl = ""
+ Request.Url.Scheme + "://"
+ Request.Url.Authority
+ Request.ApplicationPath.TrimEnd('/');
}
@baseUrl/controller/method
で
http://localhost:49983/controller/method
と表示されます。
コントローラーから ViewData で渡す場合は
YourController.cs
string BASE_URL = Request.Url.Scheme + "://" + Request.Url.Authority + Request.ApplicationPath.TrimEnd( '/' );
ViewData["BASE_URL"] = BASE_URL;
your-view-file.cshtml
@ViewData["BASE_URL"]/controller/method
で渡します。
Razorテンプレート内では @Request.ApplicationPath のように直接記述することができます。
<table>
<tr><td>Request.ApplicationPath</td><td>@Request.ApplicationPath</td></tr>
<tr><td>Request.FilePath</td><td>@Request.FilePath</td></tr>
<tr><td>Request.Path</td><td>@Request.Path</td></tr>
<tr><td>Request.FilePath</td><td>@Request.FilePath</td></tr>
<tr><td>Request.PathInfo</td><td>@Request.PathInfo</td></tr>
<tr><td>Request.PhysicalApplicationPath</td><td>@Request.PhysicalApplicationPath</td></tr>
<tr><td>Request.PhysicalPath</td><td>@Request.PhysicalPath</td></tr>
<tr><td>Request.RawUrl</td><td>@Request.RawUrl</td></tr>
<tr><td>Request.Url</td><td>@Request.Url</td></tr>
</table>
例えば
http://localhost:49983/Debug/Url
へのアクセスは
Request.ApplicationPath | / |
Request.FilePath | /Debug/Url |
Request.Path | /Debug/Url |
Request.FilePath | /Debug/Url |
Request.PathInfo | |
Request.PhysicalApplicationPath | C:\my_dir\MY-PROJECT\PROJECT\ |
Request.PhysicalPath | C:\my_dir\MY-PROJECT\PROJECT\Debug\Url |
Request.RawUrl | /Debug/Url |
Request.Url | http://localhost:49983/Debug/Url |
のような表示になります。
.NET MVC ページで 独自の404ページを設置する
Web.config の「system.web」の下に 404 エラー時に /Error/NotFound へ移動するよう設定します
Web.config
<system.web>
<!--独自の404ページ-->
<customErrors defaultRedirect="~/Error/" mode="On">
<error statusCode="404" redirect="~/Error/NotFound"/>
</customErrors>
<!--独自の404ページ-->
ネームスペースの「MYAPP」のところは適宜書き換えてください。 NotFound のビューを返すようにしてあります
/Controllers/ErrorController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MYAPP.Controllers
{
public class ErrorController : Controller
{
// GET: Error
public ActionResult Index()
{
return View();
}
// GET: Error/NotFound
public ActionResult NotFound()
{
ViewBag.Title = "Error 404";
return View( "NotFound" );
}
}
}
お好きなhtmlを作成してください。
/Views/Error/NotFound.cshtml
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>404 Not Found.</h1>
</body>
</html>
Session["キー"] = 値;
Session["login_name"] = "HogeHoge";
Session["キー"]
Object nameObj = Session["login_name"];
string firstName = (string)(Session["First"]);
文字列でほしいときは string 型にキャストします
if ( Session["キー"] != null ){
// 存在します
}
Session["login_name"] = null;
Session.Remove("login_name");
Session.RemoveAll()
https://msdn.microsoft.com/ja-jp/library/cc338759.aspx
foreach (string key in Session.Keys)
{
Debug.WriteLine( key + " - " + Session[key].ToString() + "<br />" );
}
NLog.Configに以下のように設定します
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
internalLogFile="C:\<あなたのプロジェクトディレクトリ>\internal.log"
internalLogLevel="Trace"
internalLogToConsole="true"
internalLogToConsoleError="true"
internalLogToTrace="true" >
NuGetからインストールします。 Visual Studioなら「ソリューションエクスプローラー」を右クリックして「NuGetパッケージの管理」から「NLog」を検索してインストールします
NLogを使いたいクラスにプロパティ logger をセットします。
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
ログへ出力します
logger.Info( "情報ログ" );
logger.Debug( "デバッグログ" );
logger.Trace( "トレースログ" );
ログにはレベルが存在します。レベルによって処理を分けたりするためです。
(エラーの時は別ファイルに保存したり、エラーの時はメールを送信したりといった感じです。)
(NLogのログレベル。上から順に需要)
logger.Fatal("致命的レベル");
logger.Error("エラーレベル");
logger.Warn("警告レベル");
logger.Info("情報レベル");
logger.Debug("デバッグレベル");
logger.Trace("トレースレベル");
NLog.Config というファイルがインストール時に自動生成されます (自動生成されないこともあります。) その時は以下のようなファイル NLog.Config を プロジェクトのフォルダに作成します。
NLog.Config
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="normal"
xsi:type="File"
encoding="UTF-8"
lineEnding="LF"
fileName="${basedir}/logs/event.log"
layout="[${longdate}] [${uppercase:${level:padding=5}}] ${callsite}() [${message}] ${exception:format=tostring}"
archiveNumbering="Date"
archiveFileName="${basedir}/logs/archive/{#}-event.log"
archiveEvery="Day" archiveDateFormat="yyyyMMdd"
maxArchiveFiles="7" />
<target name="error"
xsi:type="File"
encoding="UTF-8"
lineEnding="LF"
layout="[${longdate}] [${uppercase:${level:padding=5}}] ${message} - ${callsite}() ${exception:format=tostring}"
fileName="${basedir}/logs/error.log"
archiveNumbering="Date"
archiveFileName="${basedir}/logs/archive/{#}-error.log"
archiveEvery="Day" archiveDateFormat="yyyyMMdd"
maxArchiveFiles="7"/>
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="normal" />
<logger name="*" minlevel="Trace" writeTo="normal" />
<logger name="*" levels="Error,Fatal" writeTo="error"/>
</rules>
</nlog>
${basedir} というのが出てきますが、これは AppDomain.CurrentDomain.BaseDirectory の事です。
場所がわからない場合は次のようにして確認してみてください。
Debug.WriteLine( AppDomain.CurrentDomain.BaseDirectory );
DB処理など try catch したい場合は次のように記述します
try
{
logger.Info( "DB処理 - 開始" );
// ここにDB処理
logger.Info( "DB処理 - 正常完了" );
}
catch (Exception ex)
{
logger.Error( ex );
throw;
}
.NET C# の try catch 例外エラー サンプル
スニペットとして登録しておいておくといいと思います。
try
{
// Your code here ...
}
catch (Exception ex)
{
logger.Error( ex );
Debug.WriteLine( "=======================================" );
Debug.WriteLine( ex.Message );
Debug.WriteLine( "=======================================" );
Debug.WriteLine( ex.StackTrace );
Debug.WriteLine( "=======================================" );
Debug.WriteLine( "エラーが発生しました" );
throw;
}
FORMAT関数のほうがCONVERT 関数より使いやすいです
SELECT FORMAT(GETDATE(),'yyyyMMdd')
,FORMAT(GETDATE(),'yyyy/MM/dd')
,FORMAT(GETDATE(),'yyyy/MM/dd HH:mm:ss')
-----------------------------------------------------
20180531
2018/05/31
2018/05/31 10:05:23
SELECT CONVERT (date, getdate())
,CONVERT(NVARCHAR, getdate(), 112)
-----------------------------------------------------
2018-05-31
20180531
非コミット読み取り(READ UNCOMMITTED)
コミット済み読み取り(READ COMMITTED)
再読み込み可能読み取り(REPEATABLE READ)
直列化(SERIALIZABLE)
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET TRANSACTION ISOLATION LEVEL READ COMMITTED
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
トランザクションの開始を宣言します(これがないとロックしません)
BEGIN TRANSACTION
COMMIT
ROLLBACK TRANSACTION
デフォルトのロックのタイムアウト時間を調べます
SELECT @@lock_timeout AS default_lock_timeout;
-1 の値が返ってきたときはタイムアウトしません(恐ろしい...)
ロックのタイムアウト時間を 30秒 に設定する
SET LOCK_TIMEOUT 30000
msec で指定するので30秒にセットするときは 30000 になります。
排他ロックは通常 INSERTやUPDATEなどの更新処理のタイミングでかかりはじめます。 SELECTをする時からロックを開始したいときは明示的にロックをかけます
select max(ID) AS maxid from MY_TABLE WITH(XLOCK);
WHERE句が来るときは位置に注意
select * FROM MY_TABLE WITH(XLOCK) WHERE ID = 5 ;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT * FROM EV100TL
ROLLBACK TRANSACTION
https://github.com/2mas/SelectNextOccurrence
インストール後に「ツール」→「オプション」→「キーボード」からショートカットを登録すれば使えるようになります。
https://marketplace.visualstudio.com/items?itemName=OmarRwemi.LinePress
using System.Text.RegularExpressions;
matchedObject.Success の true または false でマッチしたかどうかを判別し、
マッチした文字列は matchedObject.Groups 配列から取り出します
string Url = "http://google.co.jp/";
Match matchedObject = Regex.Match(Url, @"https?://google(.+)");
if ( matchedObject.Success)
{
var country = matchedObject.Groups[1].Value;
}
using System.Text.RegularExpressions;
if ( Regex.IsMatch("対象文字列", "正規表現") )
{
// マッチしたときの処理
}
.NET Core 2 でTwitter API を叩きたいときは Tweetinvi を使うといいでしょう。(CoreTweetではなく。)
Visual Studio からパッケージを「Tweetinvi」で検索してインストールするか
Install-Package TweetinviAPI
コマンドでインストールします。
Auth.SetUserCredentials("CONSUMER_KEY", "CONSUMER_SECRET", "ACCESS_TOKEN", "ACCESS_TOKEN_SECRET");
Tweet.PublishTweet("Hello World!");
(以降、Auth は省略します)
var status = Tweet.GetTweet(999226655250956288);
DateTime date = DateTime.Now;
DateTime dt = DateTime.Now;
var d1 = dt.ToString( "yyyyMMdd" );
var t1 = dt.ToString( "HHmmss" );
20180528
120559
var start_str = "20180215131723";
DateTime dt = DateTime.ParseExact(start_str, "yyyyMMddHHmmss", new CultureInfo("ja-JP"));
オブジェクト同士なら 比較演算子( > や = など)で比較できます
DateTime自体には、実際のタイムゾーン情報は含まれていません。
引用 : https://tinyurl.com/byza85nc
Kindは次の様にして表示します
dt1.Kind.ToString()
.NET Coreでは基本 Entity Framework を使用するので直接SQL文を実行する事はありませんが、たまにSQL文を実行したい時があります。 Entity Frameworkを使用するので簡単なSQL文を実行したいだけの時でも「モデル」と「コンテキスト」は定義しておく必要があります。
(DBコンテキスト : _context)(テーブル:MYTABLE) を操作します
string sql = "SELECT * FROM MYTABLE";
var result = _context.Mytable.FromSql(sql);
パラメータを渡したい場合は以下のように記述します
using System.Data.SqlClient;
var sp = new SqlParameter("nm", "tanaka");
var result = this.db.MYTABLE
.FromSql("SELECT TOP 1 * FROM MYTABLE WHERE NAME = @nm", sp);
非クエリ コマンドに対して Database.ExecuteSqlCommand を使用します。
DBにテーブルを構築後モデルファイルを自動で生成するにはプロジェクトフォルダ( .sln ファイルがあるディレクトリの1つ下の階層)から PowerShell を立ち上げ、次のようにコマンドを入力します
コマンド の書き方
dotnet ef dbcontext scaffold <connection_string> <provider>
dotnet ef dbcontext scaffold "Server=データベースサーバ名;Database=ScaffoldDB;Trusted_Connection=True" Microsoft.EntityFrameworkCore.SqlServer -o Models
例 :
DBサーバ : MYPC\SQLEXPRESS
データベース : MyDb
の場合
dotnet ef dbcontext scaffold "Server=MYPC\SQLEXPRESS;Database=MyDb;Trusted_Connection=True" Microsoft.EntityFrameworkCore.SqlServer -o Models
-f オプションで上書きします。(一番最後に -f をつけて実行します)
dotnet ef dbcontext scaffold "Server=データベースサーバ名;Database=ScaffoldDB;Trusted_Connection=True" Microsoft.EntityFrameworkCore.SqlServer -o Models -f
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
</ItemGroup>
dotnet restore
を実行すると dotnet ef コマンドが使用できるようになります。
HomeController.cs
using Microsoft.Extensions.Configuration;
public IConfiguration _configuration { get; }
public HomeController( IConfiguration Configuration )
{
_configuration = Configuration;
}
これで Startup.cs と同じように appsettings.json の値が使用できます。
_configuration.GetConnectionString("<設定名>")
appsettings.json
"MySettings": {
"KEY": "hogehoge",
"SECRET": "fugafuga",
}
「Models」フォルダを右クリックして新しいクラスを作成します
appsettings.json の中身をすべてコピーして「編集」→「形式を選択して貼り付け」→「JSONをクラスとして張り付ける」を実行すると時間が短縮できます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace <あなたのプロジェクト名>.Models
{
public class AppSettings
{
public Mysettings MySettings { get; set; }
public class Mysettings
{
public string KEY{ get; set; }
public string SECRET { get; set; }
}
}
}
using <あなたのプロジェクト名>.Models;
using Microsoft.Extensions.Options;
を先頭に追加し、次のメソッドを書き換え
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.Configure<AppSettings>(Configuration);
}
using <あなたのプロジェクト名>.Models;
using Microsoft.Extensions.Options;
を先頭に追加し、次のプライベート変数とコンストラクタを追加
private readonly AppSettings appSettings;
public HomeController(IOptions<AppSettings> optionsAccessor)
{
this.appSettings = optionsAccessor.Value;
}
以上でコントローラーの各メソッドで this.appSettings から appsettings.json の値が参照できます。
C#の命名規則について調べてみるとそこまで厳格には決められていないのですが、ざっくりいうと次のようになります。
・privateなものはcamelCase(先頭が小文字)
・publicなものはPascalCase(先頭が大文字)
・静的な定数はPascalCase(先頭が大文字)
・インターフェイスのプレフィックスとして[I(大文字のアイ)]を付ける
参考
https://docs.microsoft.com/ja-jp/dotnet/standard/design-guidelines/naming-guidelines
http://taka-say.hateblo.jp/entry/2014/05/26/005005
https://jikkenjo.net/309.html
HogeController.cs
public IActionResult Fuga()
{
ViewData["Message"] = "メッセージの表示テストです";
return View();
}
Fuga.cshtml
<h2>@ViewData["Title"]</h2>
デバッグを実行してブラウザのアドレス欄に http://localhost:50914/Hoge/Fuga と入力して移動すると
<h2>メッセージの表示テストです</h2>
が出力されます。
「Input」で渡した値を「Confirm」で受け取ってみます
Input.cshtml (入力画面)
<form asp-controller="Hoge" asp-action="Confirm" method="post">
@Html.AntiForgeryToken()
<input type="text" name="Email" >
<input type="text" name="Url" >
<input type="submit" value="送信する">
</form>
HogeController.cs (確認画面 - コントローラ)
// POST: Hoge/Confirm
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Confirm(string Email, string Url)
{
ViewData["Email"] = Email;
ViewData["Url"] = Url;
return View();
}
Confirm.cshtml(確認画面 - ビュー)
<table>
<tr>
<td>Email</td>
<td>@ViewData["Email"]</td>
</tr>
<tr>
<td>Url</td>
<td>@ViewData["Url"]</td>
</tr>
</table>
(1.)と同じく「Input」で渡した値を「Confirm」で受け取ってみます。
この時モデルを定義してモデルを受け渡します。
Input.cshtml (入力画面)
<form asp-controller="Toukous" asp-action="Confirm" method="post">
@Html.AntiForgeryToken()
<input type="text" name="Email" >
<input type="text" name="Url" >
<input type="submit" value="送信する">
</form>
Models/Hoge.cs(モデル)
namespace Hoge.Models
{
public class Toukou
{
public int ID { get; set; }
public string Email { get; set; }
public string Url { get; set; }
}
}
HogeController.cs (確認画面 - コントローラ) view()の引数で「テンプレートファイル」「モデル」を渡しています
// POST: Hoge/Confirm
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Confirm(Toukou model)
{
return View("Confirm", model);
}
Confirm.cshtml(確認画面 - ビュー) テンプレート cshtml の一番上でモデルのクラスを指定します。
@model <プロジェクト名>.Models.<モデルのクラス名>
例
@model Myapp.Models.Entry
<table>
<tr>
<th>@Html.DisplayNameFor(model => model.Email)</th>
<td>@Html.DisplayFor(model => model.Email)</td>
</tr>
<tr>
<th>@Html.DisplayNameFor(model => model.Url)</th>
<td>@Html.DisplayFor(model => model.Url)</td>
</tr>
</table>
デフォルトではレイアウト(継承元)のテンプレートファイルは
Views/Shared/_Layout.cshtml
にあります。
これは /Views/_ViewStart.cshtml に次のように定義されているので
@{
Layout = "_Layout";
}
レイアウトファイルを変えたい場合はここを変更します。
レイアウトを使用しない場合は null をセットします。
チルダ ~ でドキュメントルートを参照できます。
<img src="~/Content/hoge.gif" alt="サンプル画像" />
コードファーストでDBとコントローラーを作成します。
「ソリューションエクスプローラー」→「/Models」を右クリック → 追加 → 「クラス」(モデルの名前を入力して「追加」)
Movieクラスを作成した場合
/models/Movie.cs
public class Movie
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime ReleaseDate { get; set; }
public string Genre { get; set; }
public decimal Price { get; set; }
}
Visual Studioの「パッケージマネージャー コンソール」から
Add-Migration Initial
Update-Database
(または PowerShellから同様のコマンドを実行することができます。Mac、Unixの場合はこちら)
dotnet ef migrations add Initial
dotnet ef database update
「ソリューションエクスプローラー」→「/Controllers」を右クリック → 追加 → 「コントローラー」 →「Entity Frameworkを利用したビューがあるMVCコントローラー」(モデルクラスを選択して「追加」)
「f5」でアプリを実行し
http://localhost:50914/Movies
へ移動し動作を確認する。
SQL Serverへのログインはデフォルトでは Windows認証となっていますが、
ユーザーとパスワードを指定してログインする「SQL Server認証」でログインできるようにしてみます。
Microsoft SQL ServerManagement Studio を起動して次のようにします。
「セキュリティ」→「ログイン」を右クリックして「新しいログイン」を選択する
・「ログイン名」を入力する
・「SQL Server認証」を選択する
・「パスワード」「パスワードの確認入力」を入力する
・「パスワードポリシーを適用する」のチェックを外す(簡単なパスワードを許可したい場合)
・「既定のデータベース」、使用したいデータベースを選択
・「既定の言語」、 Japanese を選択
・「ユーザーマッピング」ページへ移動し操作したいデータベースの横にある「マップ」のチェックボックスのチェックをつける
・操作したいデータベースを選択し、下の画面の「db_owner」にチェックをつける
サーバー名を右クリック → プロパティ → 「セキュリティ」を選択 →「SQL Server認証モードとWindows認証モード」を選択 → OK
SQL Server 構成マネージャー から SQL Server を再起動する
Windows +「R」を押して次のコマンドを実行します。
SQL Server のバージョン | コマンド |
---|---|
SQL Server 2012 | SQLServerManager11.msc |
SQL Server 2014 | SQLServerManager12.msc |
SQL Server 2016 | SQLServerManager13.msc |
SQL Server 2017 | SQLServerManager14.msc |
SQL Server 2019 | SQLServerManager15.msc |
Microsoft SQL ServerManagement Studio を起動して 「SQL Server認証」 を選択し先ほど入力したIDとパスワードでログインできることを確認する。
cmd からのログイン確認
sqlcmd -S localhost -U test_db -P test_db
SQLサーバ名 : WINSERVER2016\\SQLEXPRESS
データベース名 : testdb
ID : hogehoge
PASS : mypass
で接続するには appsettings.json に次のように記述します。
"ConnectionStrings": {
"DefaultConnection": "Server=WINSERVER2016\\SQLEXPRESS;Initial Catalog=testdb;MultipleActiveResultSets=true;User ID=hogehoge;Password=mypass"
},
web.config を次のように書き換えます
<aspNetCore processPath="dotnet" arguments=".\TestLoginApp5.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
<aspNetCore processPath="dotnet" arguments=".\TestLoginApp5.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout">
<environmentVariables>
<environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" />
</environmentVariables>
</aspNetCore>
# CLI版を使う際には追加パッケージをインストールします。
dotnet add package Microsoft.EntityFrameworkCore.Tools.DotNet
# Add-Migration 適当な名前
dotnet ef migrations add 適当な名前
# Remove-Migration
dotnet ef migrations remove
# Update-Database
dotnet ef database update
# Drop-Database
dotnet ef database drop
引用: EntityFrameworkCoreを.NET Core コンソールアプリでCodeFirstに使う - Qiita
その際以下の認証機能を追加します
・メニューの「新規作成」→「プロジェクト」→「ASP .Net CORE MVCアプリケーション」で【OK】を押す。
・「Webアプリケーション(モデル ビューコントローラー)」「認証の変更」「個別のユーザーアカウント」を選択して【OK】を押す。
これでプロジェクトファイルとソースコード一式が生成されます。
appsettings.json の DB接続の項目を変更します。
appsettings.json
"ConnectionStrings": {
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-TestLogin4-3FFC9AB5-5122-4BFD-9097-4F6113EE0EA3;Trusted_Connection=True;MultipleActiveResultSets=true"
},
これの
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;
DefaultConnectionを ローカルDBからSQL Server に変更します ↓
PCの名前が MYPCの場合
"DefaultConnection": "Server=MYPC\\SQLEXPRESS;
またデータベース名はデフォルトでは
aspnet-TestLogin4-3FFC9AB5-5122-4BFD-9097-4F6113EE0EA3 といった長い名前がつけられます。
これも好きな名前に変えておきます。
Database=aspnet-TestLogin4-3FFC9AB5-5122-4BFD-9097-4F6113EE0EA3;
↓ (データベース名を mydb に変更します)
Database=mydb;
パッケージマネージャーコンソールから
Update-Database
と入力します。
PowerShellを開き、プロジェクトがあるディレクトリに移動してから
dotnet ef database update
と入力します。
以上です。
ローカルで動作することを確認します
(10GBまで無料の SQL Server 2017 Express をインストールします) https://www.microsoft.com/ja-jp/sql-server/sql-server-editions-express
https://go.microsoft.com/fwlink/?linkid=870039
せっかく マルチプラットフォーム対応の .NET Core なのでデータベースをMS以外のものに変更してみます。
– Microsoft.EntityFrameworkCore.SQLite
– Microsoft.EntityFrameworkCore.SQLite.Desgin
Startup.cs の以下を書き換えます
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
↓ 「UseSqlServer」を「UseSqlite」に変更する
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));
}
SQLServerの場合は接続文字列がセットされていますが、そこを ファイル名に変更します。
"ConnectionStrings": {
"DefaultConnection": "Server=MYPC\\SQLEXPRESS;Database=test_user_auth_db;Trusted_Connection=True;MultipleActiveResultSets=true"
},
↓
"ConnectionStrings": {
"DefaultConnection": "Filename=./mydata.db"
},
Update-Database
これでアプリを実行すると SQLiteを使ってユーザー認証アプリを作成することができます。
https://docs.microsoft.com/ja-jp/ef/core/providers/sqlite/limitations
指定したディレクトリに .zip ファイルが生成されます。
https://www.microsoft.com/net/download/windows
.zip ファイルや 発行先ディレクトリの入力を求められるので入力します。
PowerShellを立ち上げて、該当ディレクトリに移動した後で次のコマンドを入力 (例: アプリ名が HelloWorld01 の場合)
dotnet HelloWorld01.dll
組み込みサーバが立ち上がるので表示されるアドレスを入力して動作を確認します。 (確認後 Press Ctrl+C でサーバを終了。)
以上です。 手動のデプロイも簡単です。
Explorer で該当ディレクトリに移動しアドレス欄に powershell と入力して実行すると、該当ディレクトリをカレントディレクトリとして立ち上がります
Set-ExecutionPolicy RemoteSigned
New-item –type file –force $profile
notepad $profile
ファイルが開くのでエイリアスを追加して保存する
Set-Alias g git
Set-Alias l Get-ChildItem
PowerShell を再起動するとエイリアスが使えるようになっています。
https://github.com/PowerShell/Win32-OpenSSH/releases
(64bit版、32bit版どちらもあるのでお使いのサーバ用の zip ファイルをダウンロード)
c:\openssh\
に置きます。
・「Windowsアイコンを右クリック」→「システム」をクリック
・「システムの詳細設定」→「環境変数」をクリック
・「システム環境変数」の 「Path」 を選択して「編集」をクリック。
・「追加」を押して「C:\openssh」を追加
Power Shellを起動して以下を実行します
cd \openssh
.\install-sshd.ps1
New-NetFirewallRule -Protocol TCP -LocalPort 22 -Direction Inbound -Action Allow -DisplayName SSH
Power Shellを起動して以下を実行します
Set-Service sshd -StartupType Automatic
Set-Service ssh-agent -StartupType Automatic
再起動後に他のマシンからssh接続を確認します。