aspNetCore mvc superPad 備忘録編

プロジェクトの作成

yo aspnet

? What type of application do you want to create? Empty Web Application

https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app-xplat/start-mvc

csproj プロジェクト作成。認証とか、高尚なテクノロジーは考慮しない
dotnet new mvc
実行まで
dotnet restore
dotnet build
dotnet run

Npgsql

インストール
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
および
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL.Design
csproj に追加↓
  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.1" PrivateAssets="All" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="1.0.0" />
  </ItemGroup>
お忘れなく↓
dotnet restore
DBFirst で DbContext を構築したい。
dotnet ef dbcontext scaffold "Host=xxx;Database=xxx;Username=xxx;Password=xxx;Port=xxx" Npgsql.EntityFrameworkCore.PostgreSQL -o Models

* dotnet ef コマンドは、プロジェクトのビルドが通らないと使えないので、注意。
* 何度もお世話になるはずなので、 バッチファイル化すればいいと思います。

静的ファイルのサポート
dotnet add package Microsoft.AspNetCore.StaticFiles
https://docs.microsoft.com/ja-jp/dotnet/csharp/tutorials/console-webapiclient
[DataMember(Name="pushed_at")]
[IgnoreDataMember] 

FromSql を使うには

https://docs.microsoft.com/en-us/ef/core/querying/raw-sql
https://stackoverflow.com/a/35305900
dotnet add package Microsoft.EntityFrameworkCore.Relational
using Microsoft.EntityFrameworkCore;
var blogs = context.Blogs
    .FromSql("EXECUTE dbo.GetMostPopularBlogsForUser {0}", user)
実体は RelationalQueryableExtensions Class です。

NotMapped (未確認)

using System.ComponentModel.DataAnnotations.Schema;
[NotMapped]
しかし NotMapped は通用しない模様。
https://stackoverflow.com/a/27552032

Tabulator をつかう

bower install tabulator --save
Shared/_Layout.cshtml に追記
<link rel="stylesheet" href="~/lib/tabulator/dist/css/tabulator_simple.css" />
<script src="~/lib/tabulator/dist/js/tabulator.js"></script>

moment をつかう

bower install moment --save
Shared/_Layout.cshtml に追記
<script src="~/lib/moment/min/moment-with-locales.js"></script>

URL を動的に指定&変換

Url.Content("~/123")
利用例:
$("#salesTable").tabulator("setData", '@Url.Content("~/Sales/List?")');

https://msdn.microsoft.com/en-us/library/system.web.mvc.urlhelper.content(v=vs.118).aspx

Cookie を使いたい

razor へ突っ込みます:
@inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
Startup.cs の ConfigureServices に
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
実装例:
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddMvc();

            // https://stackoverflow.com/a/37373557
            services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
        }

https://stackoverflow.com/a/37373557 

Templated url for css and script

じつは、こういうことがしたかった:

    @inject Microsoft.AspNetCore.Http.IHttpContextAccessor HttpContextAccessor
    @functions {
        String resolveTheme(String template) {
            return System.Text.RegularExpressions.Regex.Replace(
                template,
                "\\{([^\\}]+)\\}",
                (match) => {
                    // jQueryUITheme:base
                    String[] pair = match.Groups[1].Value.Split(':');
                    String replacement = HttpContextAccessor.HttpContext.Request.Cookies[pair[0]];
                    if (String.IsNullOrEmpty(replacement)) {
                        if (pair.Length == 2) {
                            replacement = pair[1];
                        }
                        else {
                            replacement = "???";
                        }
                    }
                    return replacement;
                }
            );
        }
    }
    <environment names="Development">
        <link rel="stylesheet" href='@Url.Content(resolveTheme("~/lib/jquery-ui/themes/{jQueryUITheme:base}/jquery-ui.css"))' />
        <link rel="stylesheet" href="~/lib/tether/dist/css/tether.css" />
        <link rel="stylesheet" href='@Url.Content(resolveTheme("~/lib/{bootstrapTheme:bootstrap}/dist/css/bootstrap.css"))' />
        <link rel="stylesheet" href="~/lib/jQuery-contextMenu/dist/jquery.contextMenu.css" />
        <link rel="stylesheet" href='@Url.Content(resolveTheme("~/lib/tabulator/dist/css/tabulator_{tabulatorTheme:simple}.css"))' />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href='@Url.Content(resolveTheme("~/lib/jquery-ui/themes/{jQueryUITheme:base}/jquery-ui.min.css"))' />
        <link rel="stylesheet" href="~/lib/tether/dist/css/tether.min.css" />
        <link rel="stylesheet" href='@Url.Content(resolveTheme("~/lib/{bootstrapTheme:bootstrap}/dist/css/bootstrap.min.css"))' />
        <link rel="stylesheet" href="~/lib/jQuery-contextMenu/dist/jquery.contextMenu.min.css" />
        <link rel="stylesheet" href='@Url.Content(resolveTheme("~/lib/tabulator/dist/css/tabulator_{tabulatorTheme:simple}.min.css"))' />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>

View() 以外のレスポンス 

色々ありました:
Ok()
Content(...)
NotFound()
new EmptyResult()
ControllerBase Class を参照。

public ActionResult SomeActionMethod() {
    return Content("hello world!");
}
https://stackoverflow.com/a/227638
return new EmptyResult();
https://stackoverflow.com/a/6857674
return NotFound();
https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/crud

Database.ExecuteSqlCommand パラメータ

String.Format と同じく {0} からか:
int cnt = dbcontext.Database.ExecuteSqlCommand("delete tablename where id ={0}",id);


http://haronoid.hatenablog.com/entry/2016/08/03/133352

@model @Model

@model IEnumerable<MvcMovie.Models.Movie>
@foreach (var item in Model) {
@Html.DisplayFor(modelItem => item.Title) 

しかしながら @variable でそのままいけました。

https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/adding-model

Raw 生データ

@Raw(Model.EmailContent)
https://stackoverflow.com/a/9671120

AspNetCore Mvc はこっち↓
@Html.Raw(Markdig.Markdown.ToHtml(item.What))

Bootstrap テーマ Nico を追加

bower install --save Nico#3.3.7-1.2.1

Bootstrap,Honoka,Umi,Nico,Frandre,Chen は 80px

テーマ切り替えを実装する場合は、対策が必要。 wwwroot/css/site.css にて
body {
    padding-top: 50px;
    padding-bottom: 20px;
}
body.for_Nico, body.for_Umi, body.for_Honoka, body.for_Frandre, body.for_Chen {
    padding-top: 80px;
}
Shared/_Layout.cshtml に細工しております。
<body class='@resolveTheme("for_{bootstrapTheme:} no-thank-yu")'>

wwwroot/css/site.min.css は手動更新!?

これで dotnet build で自動更新!
dotnet add package BuildBundlerMinifier
https://docs.microsoft.com/ja-jp/aspnet/core/client-side/bundling-and-minification?tabs=netcore-cli%2Caspnetcore2x

dotnet bundle で minify しないといけない模様。

csproj に追加↓
<ItemGroup>
  <DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.4.337" />
</ItemGroup>
dotnet restore
dotnet bundle
https://dotnetthoughts.net/bundling-and-minification-in-aspnet-core/

しかしながら、dotnet add package と相性不具合があるそうな…
そのときだけ <DotNetCliToolReference ... /> をコメントアウトしたい。

Razor で、JSON を書き出し

var text = @Html.Raw(Json.Serialize("a"));
https://stackoverflow.com/a/30927285

$.ajaxGET

  var productsList = [];
  $.getJSON('@Url.Content("~/Products/List")', function (data) {
      productsList = data;
  });

コントローラーから JSON を返す


  public IActionResult List(String keywords)
  {
      ModelContext context = new ModelContext();
      return Json(context.Products.ToArray());
  }

HttpGet/HttpPost

TryUpdateModelAsync を使う場合、同じ引数にすることがありますので。
[HttpGet]
public IActionResult Edit(int id)
[HttpPost]
[ActionName("Edit")]
public async Task<IActionResult> EditPost(int id)
https://stackoverflow.com/a/11767953

validation 

なんかもうタグだけで完結しますね…
    <div class="form-group">
        <label asp-for="製品名" class="control-label"></label>
        <input asp-for="製品名" type="text" class="form-control" />
        <span asp-validation-for="製品名" class="text-danger"></span>
    </div>
https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/validation

通らない↓ OLD notWorkable!
<div class="form-group">
  @Html.LabelFor(model => model.区分, new { @class = "control-label" })
  @Html.ValidationMessageFor(model => model.区分, "*")
  @Html.TextBoxFor(model => model.区分, new { @class = "form-control" })
</div>

bower ローカルからインストール

bower install C:\Git\Kanata#3.3.6b-0

プロジェクト内のファイルを参照したい

IHostingEnvironment.ContentRootPath
https://stackoverflow.com/a/37298622

プロジェクト内のファイルがコピーされない!

 どうもコピーされません。手動で追加:
  <Target Name="PrepublishScript" BeforeTargets="PrepareForPublish">
    <ItemGroup>
      <AppFiles Include="Excel.xlsx" />
    </ItemGroup>
    <Copy SourceFiles="@(AppFiles)" DestinationFolder="$(PublishDir)" SkipUnchangedFiles="true" />
  </Target>
https://github.com/dotnet/sdk/issues/795#issuecomment-289778744

VSCode snippets for cshtml

cshtml は HTML ではなく、Razor らしい。
https://github.com/Microsoft/vscode/issues/14629#issuecomment-256887283

bootstrap modal dialog

https://www.w3schools.com/bootstrap/bootstrap_modal.asp

bootstrap modal multi column

<div class="col-md-6">
https://stackoverflow.com/a/23134853

.ttf .woff .woff2 → 404?

プロジェクトの web.config へ追加:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <staticContent>
        <mimeMap fileExtension=".ttf" mimeType="application/octet-stream" />
        <mimeMap fileExtension=".woff" mimeType="application/font-woff" />
        <mimeMap fileExtension=".woff2" mimeType="application/font-woff2" />
    </staticContent>
  </system.webServer>
</configuration>

Npgsql serial

クラスに書く場合:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int 顧客ID { get; set; }
https://stackoverflow.com/questions/15585330/calculated-column-in-ef-code-first

ASP.NET MVC 従来の

@Html.ActionLink
@Html.Raw
@Html.DisplayFor

~~~ ASP.NET Core 2.0 Razor Pages ~~~

  • form タグの asp-route-XXX="" で、クエリー文字列を設定できる。
  • asp-for="@Model.Problem.ID" にすると、
    input name="Problem.ID" となるらしい。
    TryUpdateModelAsync で、"Problem" を指定したい。
  • textarea にも asp-for を使用できる。

<form method="POST" asp-route-serial="@Model.Problem.シリアル">

<div class="form-group">
<label class="control-label" for="ID">ID</label>
<input class="form-control" id="ID" type="text" asp-for="@Model.Problem.ID" />
</div>

<div class="form-group">
<label class="control-label" for="図面番号">図面番号</label>
<input class="form-control" id="図面番号" type="text" asp-for="@Model.Problem.図面番号" />
</div>

<div class="form-group">
<label class="control-label" for="工程ID">工程ID</label>
<input class="form-control" id="工程ID" type="text" asp-for="@Model.Problem.工程ID" />
</div>

<div class="form-group">
<label class="control-label" for="内容">内容</label>
<textarea class="form-control" id="内容" type="text" rows="10" asp-for="@Model.Problem.内容"></textarea>
</div>

<button type="submit" class="btn btn-primary">保存</button>

</form>
 
public async Task<IActionResult> OnPostAsync(int serial)
{
if (!ModelState.IsValid)
{
return Page();
}

var context = new Kana10Context();
Problem = context.工程不適合マスタ.Single(m => m.シリアル == serial);
if (await TryUpdateModelAsync(Problem, "Problem"))
{
context.SaveChanges();
}
return Page();
}


DbContext のコンストラクタ インジェクションをしたい。
public ProblemsModel(Kana10Context db)
{
this.db = db;
}

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();
services.AddDbContext<Kana10Context>();
}


コメント

このブログの人気の投稿

gulpfile.ts (122,1): Expected 1-2 arguments, but got 3. (2554)

Error in plugin 'gulp-gm' Error: write EOF