2011年5月6日金曜日

@RenderPageとHtml.RenderPartial

いや~、連休ももうすぐ終わってしまうと思うと、ちょっぴりアンニュイな気持ちになってしまいます。アンニュイってララバイくらい意味がよくわからない。

Razor使ってますか?使ってますよね。お腹すいたらRazorだし、テレビ見ながらRazorですよ!

疲れてるのかな...。

~/Views/Shared/_Partial.cshtml

@{
    var message = Model ?? (PageData.Any() ? PageData.First().Value : null);
}
ゴールデン @message

↑こんな部分ビューを用意しました。

~/Views/Home/Index.cshtml

@{Layout = null;}
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8" />
    <title>連休</title>
</head>
<body>
<p>@@RenderPage - 
  @RenderPage("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>
<p>Html.RenderPartial - 
  @{Html.RenderPartial("~/Views/Shared/_Partial.cshtml", "ウィーク");}</p>
<p>Html.Partial - 
  @Html.Partial("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>
</body>
</html>

↑そしてそれを利用するビューも用意しました。

ここで問題です!このページ(Index.cshtml)を表示するとどういう表示になるでしょーか?

答え

partial1

ビックリした?ねーねー、ビックリした?オレ、すげービックリした。

なんでHtml.RenderPartialだと”ゴールデン ウィーク”と表示されないんでしょうね。ソース追っかけたりしてスゴイ悩んだんですよ。そもそもRazorではストリームに直接出力うするHtml.RenderPartial使えないのか!?とか仕様を疑ったり(RenderPartialの実装がMVC3になってTextWriter渡す実装に変わってるから関係ないのにね)。

うーん、煮詰まった。ふと、順番入れ替えたらどうなるのか試してみたんす。

<p>Html.RenderPartial - 
  @{Html.RenderPartial("~/Views/Shared/_Partial.cshtml", "ウィーク");}</p>
<p>Html.Partial - 
  @Html.Partial("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>
<p>@@RenderPage - 
  @RenderPage("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>

@RenderPageを最後に移動。

partial2

おや~?ちゃんと出た。あれ~。この際Html.Partialは無視して試しに親戚のHtml.RenderActionはどうなるのか試してみたっす。

HomeControllerに以下を追加。

[ChildActionOnly]
public ActionResult Week()
{
    return Content("ウィーク");
}

Index.cshtmlを以下のように変更(@RenderPageを最初に持って来てHtml.RenderAction追加)。

<p>@@RenderPage - 
  @RenderPage("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>
<p>Html.RenderPartial - 
  @{Html.RenderPartial("~/Views/Shared/_Partial.cshtml", "ウィーク");}</p>
<p>Html.RenderAction - 
  ゴールデン @{Html.RenderAction("Week");}</p>

partial3

Html.RenderActionは平気みたい。このまま@RenderPageを最後に移動。

<p>Html.RenderPartial - 
  @{Html.RenderPartial("~/Views/Shared/_Partial.cshtml", "ウィーク");}</p>
<p>Html.RenderAction - 
  ゴールデン @{Html.RenderAction("Week");}</p>
<p>@@RenderPage - 
  @RenderPage("~/Views/Shared/_Partial.cshtml", "ウィーク")</p>

 

partial4

ちゃんと出ますね。ということはですよ、同じWebPage中では@RenderPageした後はHtml.RenderPartialが正しく動かないということですよ。これってもしかして...。あ、いや、仕様かもしれないし。どういう事?教えてWebMatrixMan~!

※@RenderPage自体がRazor構文なのでWeb Formsでは関係ない問題です。

2011年5月4日水曜日

ぷっすぷすにしてやんよ、Glimpseで。

Glimpse - A client side look at whats going on in your server

なんと素敵なツールでしょうね!

glimpse1

↑ChromeでGlimpseをオンにしたうえに、デベロッパーツールもオンにした状態。かぶせまくり。

これ何?っていうのは上記Glimpseサイトのビデオか、MIX11でのHanselmanさんのセッションビデオ見れば一発でわかります。と言ってしまうとブログに書く必要が無くなってしまうので、少し説明すると、Trace.axdやelmah.axd、RouteDebuggerを全部ひっくるめて組み合わせてさらにサーバーサイドの情報をひと通り参照できるようにするツールデス。分かりにくいっすね。

とにかく、NuGetでInstall-Package Glimpseと入力してプロジェクトに入れて見ましょう。

その状態でデバッグを開始すると、おや?ナニも変化ないですね。なので、URLに/Glimpse/ConfigといれてGlimpse機能をOnにしまいしょう。Onにした後はURLをもとのページに自分で戻すことを忘れずに。

glimpse2

そうすると画面右下に変な目玉アイコン(Glimpseアイコンね)が表示されるのでそこをクリック!

glimpse3

そうすると出てきます。

glimpse4

すごいねー。ちなみにブラウザに表示されてるのはプラグインとかじゃなくて100%JavaScriptだけで作られたものです。

glimpse5 glimpse6

ソース表示すると</html>の後にデータがレンダリングされて、最後にglimpseClinet.jsがロードされてるのが確認できます。

あとは、見たまんまです。各タブにそれぞれ情報が表示されます。

  • Binding
    まだ開発中~。Binderの情報がでる予定(だと思います)
  • Config
    Web.Configの設定内容をセクション別に表示
    config
  • Environment
    サーバーの実行環境の情報
    Application Assemblies/System Assembliesが見れるのは嬉しいですね
    emvironment
  • Execution
    ActionInvokderの実行内容を表示(だと思う)
    Filterの実行も見れるよ!
    execution
  • Glimpse Warnings
    Glimpseの何か
  • MetaData
    どこぞのMetadata
  • Remote
    リクエスト履歴っぽい
  • Request
    HttpRequestBaseの中身からCookie,Form,QueryStringを表示
    request
  • Routes
    表示内容(アクション)に到達するルーティングの解決順とマッチしたルート
    route
  • Server
    ServerValiablesの内容
  • Session
    Sessionの内容
  • Trace
    System.Diagnostics.Traceに出力した内容
  • Views
    表示内容(View)の解決に至る過程
    view
  • XHRequest
    まだっぽい

全部スクリーンショットをとるのが面倒だったから動かして確認してみてね!

んじゃ、そもそもGlimpseの仕組みはどうなってるの?って気になるよね。NuGetからインストールすると使うのは楽チンだけどソースが確認できないから、改めてソースをダウンロードしましょう。

Glimpse/Glimpse - GitHub

真っ先に気になるのが、PreApplicationStartCode。当たり前のようにスタートアップコードが書かれてる。んで、その中身はMicrosoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModuleを使ったカスタムIHttpModuleの動的登録。その中で各種プラグイン(タブで表示する情報を取得したりするもの)をMEFで登録。

Moduleでハンドリングするタイミングは以下の4つ。

context.BeginRequest += BeginRequest;
context.EndRequest += EndRequest;
context.PostRequestHandlerExecute += PostRequestHandlerExecute;
context.PreSendRequestHeaders += PreSendRequestHeaders;

ここから結構気になってるExecutionで表示してるのがホントにActionInvokerに介入した結果なのかチェックしてみよう。

ExecutionプラグインのSetupInitでいろいろ仕込んでますね。ControllerFactoryとDependencyResolverをGlimpseのものに置き換えてます。GlimpseControllerFactory.CreateControllerでIControllerExtentions.TrySetActionInvokerを呼んでCastleのInterceptorを利用して、プロキシを生成しそれをActionInvokerにセットしてました。これでプロキシが必ず呼び出されるから、実行をインターセプトして実行情報を取得できるということですね。うほ。

DependencyResolverを利用した場合にも大丈夫なようにGlimpseDependencyResolverが用意されてて、こっちでも同じくProxyを生成するように抜かりなし。

他のプラグインもIGlimpsePlugin実装になってて、SetupInitしてGetDataを呼ぶことで各種データをHttpContext.Itemsに入れることで、最終的にGlimpseRespondersがJsonにシリアライズ。まるっとApplication編集に保存してGlimpseResponders.StandardResponseがResponse.Writeしてる。

Glimpseの仕組み

MEFを使ったプラグイン構造でContext.ItemsからApplication変数にデータを保持(configのsaveRequestCountはこの履歴保持数ということみたい)し、それをレスポンス(リクエスト毎にGuidを発行してコンテキストがきちんと判定できるよう保持)。各種情報はプラグインが自立して取得するけど、実行状態のインターセプトはCastleがProxyを生成して介入。

イロイロなプラグインを作っていけば、データの取得と表示はベースの機能でまかなえる素敵設計であるのと、.NET4、MVC3の機能もめいいっぱい利用したお洒落実装。これは萌える。萌え萌え。ぷっすぷすにされちまったぜ!

2011年5月3日火曜日

Dapper.NET

dapper-dot-net - Simple SQL object mapper for SQL Server - Google Project Hosting

これ。Massiveと同じくらい短いコードのORM。WebMatrix.Data.Databaseみたいなものですね。

オープンソースとしてたくさん存在する軽量ORMのなかでもDapperがスゴイところがパフォーマンス。どのくらい早いのかは上記サイトを確認してみると各種ORMとの速度比較が出てます。

A day in the life of a slow page at Stack Overflow

ASP.NET MVC & SQLServer & LINQ to SQLのスタックで有名な大規模サイトといえばStackoverflow.comですね。なんとそのStackoverflow.comでパフォーマンスに問題が出てきたので解決するために、このDapperを利用したというじゃないですか。

そもそもORMでN+1問題が出やすいので、LINQならjoin使ってたくさんのSQLを発行しないようにするとか、DBとのあいだのやりとりもちゃんと確認する(パフォーマンスに問題があると認識したならの話です。問題になってないなら気にしなくていいですよ)必要がありましょう。その辺はちゃんと実装したとしてもDapperが早いということです。Emitしちゃってるし。

使い方も簡単でIDbConnectionの拡張メソッドとして実装してるので、DBコネクションさえあれば簡単に導入できます。もちろんモデルクラスをPOCOで定義しておくことが最速を維持する秘訣。

AdventureWorksLT2008R2をDBに利用するためのサンプル。

public class Product
{
  public int ProductId { get; set; }
  public string Name { get; set; }
  public string ProductNumber { get; set; }
}

using (var connection = connectionFactory())
{
  var result = connection.Query<int>("select count(*) from Product").Single();
  Console.WriteLine(result + " products.");
}

// 1テーブルを1クラスにマッピング
using (var connection = connectionFactory())
{
  var result =
      connection.Query<Product>(
          "select * from Product where ListPrice between @low and @high",
          new { low = 10.0, high = 100.0 });
  Console.WriteLine("-- simple mapping:" + result.Count());
  foreach (var p in result)
  {
      Console.WriteLine(string.Format("ID:{0},Name:{1}", p.ProductId, p.Name));
  }
}

// ジェネリック指定しないで1テーブルをマッピング
using (var connection = connectionFactory())
{
  var result =
      connection.Query(
          "select * from Product where ListPrice between @low and @high",
          new { low = 10.0, high = 100.0 });
  Console.WriteLine("-- dynamic mapping:" + result.Count());
  foreach (var p in result)
  {
      Console.WriteLine(string.Format("ID:{0},Name:{1},Price:{2}", p.ProductID, p.Name, p.ListPrice));
  }
}

dapper2

ここで、実際にテーブルにはたくさん項目あるけど、モデルには省略しちゃってるんですけど、このままSQLにjoin含めた場合、ちゃんとモデルにはマッピングできませんでした。dynamicだとうまくいくんだけど、その辺の整合性はちゃんととっておかないとダメなわけですね。でもdynamicな戻り値なら早いわけではない。

dapper1

var stopwatch = new Stopwatch();
stopwatch.Start();
for (var i = 0; i < 100; i++)
{
  using (var connection = connectionFactory())
  {
    var result =
        connection.Query(
            @"select p.*, c.ProductCategoryId as CategoryId, c.Name as CategoryName
          from Product as p 
            inner join ProductCategory as c on 
              p.ProductCategoryID = c.ProductCategoryID 
          where p.ListPrice between @low and @high",
            new { low = 10.0, high = 100.0 });
    foreach (var p in result){}
  }
}
stopwatch.Stop();
Console.WriteLine("dapper time:" + stopwatch.ElapsedMilliseconds + " ms");

stopwatch.Reset();
stopwatch.Start();
for (var i = 0; i < 100; i++)
{
  using (var l2s = new AwDataContext(connectionFactory()))
  {
    var result = from p in l2s.Product
                 join c in l2s.ProductCategory on p.ProductCategoryID equals c.ProductCategoryID
                 select
                     new
                         {
                             ProductId = p.ProductID,
                             p.Name,
                             Category = c.Name
                         };
    foreach (var p in result) {}
  }
}
stopwatch.Stop();
Console.WriteLine("linq2sql time:" + stopwatch.ElapsedMilliseconds + " ms");

大きなサイトへ導入されてるというのは、興味深いじゃないですか。それだけの負荷で問題が起きないように丁寧な実装がされてるわけで(どっちもだけど)。

今後、より使いやすくなることを期待しつつ見守っていきたいプロジェクトです。

2011年4月24日日曜日

IIS ExpressでSSLを有効にしてデバッグ

Working with SSL at Development Time is easier with IISExpress - Scott Hanselman

Hanselmanさんのエントリに書かれてる通りデス!

IIS ExpressでSSLを有効にしたデバッグだと無効な証明書だと警告はでるけど、HTTPSでのテストはコレでできますよね。

だけど、名前はlocalhostに限定です。これはまぁ、そういうバインドしかapplicationHost.configに登録してないからなのと、アクセス許可をしてなからなんですが(詳しくはmvcConf 2 - Vaidy Gopalakrishnan: IIS Express | mvcConf | Channel 9)、その辺をちゃんと登録して気持ちよく使いましょうという内容ですね。途中URLRewriteでAccountControllerへのアクセスをHTTPSに書き換えるというのが挟まってるけど、コードで対応するならここは飛ばしてもOKです。

netshへのcerthashの登録、信頼されたルート証明機関の証明書として証明書を登録、最終的にIisExpressAdminCmdでACLの許可登録で気持よく、マシン名でもSSL有効な状態でアクセスできます。

というのを、自分の環境でも確認してみましょう。

1.ASP.NET MVCサイトを作成

もちろんVS2010で行うのが簡単ぽんなんですが、VS2008でも同じようにできるので(applicationHost.configとnetshなので)、そっちしかない場合はそっちで。プロジェクトの設定で、外部プログラムを起動するを利用しましょう(IIS ExpressのVS2008/VS2010利用)。

今回は簡単なVS2010で新しくなったMVC3 Toolsで作ります。

ssl1

いい感じにHTML5ですね!

2.プロジェクトのプロパティでSSL有効化

ssl2

trueにするだけの簡単な作業です。これでSSL URLが入ります。この例だと https://localhost:44301/ ですね。

この状態でまずは実行してみましょう。

ssl3

文句は言われるけど、普通に問題なくアクセスできますね。楽チンデス。IIS Express最高!

3.localhostじゃなく好きな名前でアクセス

マシン名でもいいんですが、そこはほら、恥ずかしい名前付けてる場合もあるじゃないですか。そんな状態で表示するのもどうかと思うわけですよ。なので、今回は完全カスタムな名前にしてしまいます。

takepara-local

という名前にします。これが恥ずかしい名前じゃないかと言われると、まぁ微妙ですが。あ、ちなみに自分のマシン名はそんなに恥ずかしい名前じゃないですよ。

IisExpressAdminCmdでアクセスできるようにしましょう。

※”.”でドメインな感じのマシン名だとsetupFriendlyHostnameUrlに失敗します。

ssl6

これでブラウザからアクセスしてみましょう!

ssl7-2

残念。エラーです。何か忘れてますね。そうですね、applocationHost.configにバインド登録してなかったですね。

<site name="SslTest" id="15">
    <application path="/" applicationPool="Clr4IntegratedAppPool">
        <virtualDirectory path="/" physicalPath="..." />
    </application>
    <bindings>
        <binding protocol="http" bindingInformation="*:51578:localhost" />
        <binding protocol="https" bindingInformation="*:44301:localhost" />
        <binding protocol="http" bindingInformation="*:80:takepara-local" />
        <binding protocol="https" bindingInformation="*:443:takepara-local" />
    </bindings>
</site>

ssl7

グレートですね。ちなみにhostsにtakepara-local登録して、netshでurlacl登録しても一緒です。

このまま、調子にのってHTTPSにしてみる。

ssl8

残念。ダメでした。

4.証明書を作成

takepara-localの証明書を作成してませんでしたね。hanselmanさんのエントリに書かれてるとおりです。makecertしましょう。CNだけ変えて後はそのままで。

ssl9

makecert -r -pe -n "CN=TAKEPARA-LOCAL" -b 01/01/2000 -e 01/01/2036 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12

VSコマンドプロンプトから実行しましょう。パス通ってて確実。

ssl10

証明書をnetshで登録。

netsh http add sslcert ipport=0.0.0.0:443 appid={214124cd-d05b-4309-9af9-9caa44b2b74a} certhash=864759f75a04d030e243ecf1cfe19ce336653374

ssl11ssl12

警告でるけど、気にせず表示。

5.証明書を信頼

このままでもいいんですが、やっぱり気持よく。

ssl13

信頼しちゃいましょう。自分のマシンで、自分で作った証明書。信頼しちゃえばいいじゃないか!

ssl14

Chrome厳しす。まぁ、いいか。警告でなくなったしね!

6.Accountコントローラを厳しく

URLRewriteで同じようになってもいいんですが、あえてコードで対応しましょう。と、言っても難しいことはなく、AccountControllerにRequireHttps属性を付けるだけ。

ssl15

これで、AccountControllerへのアクセスがHTTPSになってなければ、リダイレクトされます。リダイレクトされるということはHTTPでのPOSTは無視される(リダイレクトはGETデス)ので、気をつけましょう。

ssl16

この動きが気持ち悪いときはViewでURLを埋め込むときにHTTPSにしてあげる必要があるので、修正箇所が随分増えちゃいますが、通常の開発であればViewでもちゃんと書いて、ControllerへのRequireHttpsも付ける2段構えになるのが王道でしょう。抜け道なし。ViewのURLなんて嘘つくからね。

例えば、_LogOnPartial.cshtmlを以下のようにする。

@if(Request.IsAuthenticated) {
    <text>Welcome <strong>@User.Identity.Name</strong>!
    [ @Html.ActionLink("Log Off", "LogOff", "Account", "https", "takepara-local", "", null, null) ]</text>
}
else {
    @:[ @Html.ActionLink("Log On", "LogOn", "Account", "https", "takepara-local", "", null, null) ]
}

これで、必ずHTTPSのURLが生成されます。

画像てんこ盛りですが、手順通りやればうまくいくので、HTTPSでのテストをやりたい場合は是非どうぞ。

なんか、うまくできない!という場合はタスクトレイのIIS Expressを終了させてやり直してみるといいかも。applicationHost.config書き換えしたときなんかは特に。

2011年4月17日日曜日

MIX11をChannel9からまとめどり

更新:2011年4月19日 4:07

残念なお知らせと、うれしいお知らせがあります。

Mix 11 Videos - Download them all with RSS - Scott Hanselman

残念なのからいくと、このエントリは用なしになりました。嬉しいのは公式にMP4 Highが配信されました。

ダウンロードしなおすぜ!頑張れオレ!

MIX11 | Channel 9

いっぱいですね~。120個くらいですかね。MP4だけダウンロードしてiPadに入れて通勤時に全部目を通しておくのが、ラスベガスに行けなかったマニアのおつな楽しみ方というものでしょう。

http://channel9.msdn.com/Events/MIX/MIX11/RSS

とはいえ、Feedから取り出せたりするほど、便利なわけでもなく。やり方あるのかな?

でもそんなこと気にしない。ListタブをクリックすればすべてのMP4動画へのリンクがありますね。ということは、HTMLにはちゃんと動画のURLが埋まってるわけですね。となれば、スクレイピング!

なんてね。今回はちょっと趣向を変えてIE9のコンソールでJavaScriptを実行して取り出してしまいましょう!と、思ったけど、なんかちょっと思ったような出力が得られなかったので、Chromeで取り出してしまいましょう!てへ。

まずはChromeでページにアクセス。

http://channel9.msdn.com/Events/MIX/MIX11?sort=status&direction=asc#tab_sortBy_status

mix11-1

Shift+Ctrl+iでコンソールをひらきましょう。

mix11-2

MIX11のページにはjQueryが読み込まれてるので、やりたい放題ですよ。まずは変数の初期化。

var list=[];

と入れて改行。

続いて、listにエレメントから取り出したMP4一覧をタイトル込みで入れる。

$(".entry-meta > .downloads a[href*='.mp4']").each(function(i,v){list.push("wget -O \""+$(v).parents(".entry-meta").find(".title").text().replace(":","-").replace("?","?") +".mp4\" "+ $(v).attr("href"));});

↑これをコピペして改行すると、ぞろぞろ表示されます。

mix11-3

が、結果はlistに格納されてるので、続けて

list

と、入力して改行。

mix11-4

あとはコレをさらにコピペして、都合のいいように編集してコンソールからwget!curlでもいいっす。ちなみに複数の解像度のファイルがあるので、タイトルだけでファイル名にすると重複しちゃうので、その辺は目視で変更。さらにファイルとして使えない文字もあったりするので、ちょこっと修正。お好みに合わせて、どーぞー。ただいまダウンロード中の図。

mix11-6

※パスは都合のいいように書き換えてね!

ちなみにIEで実行したのが↓こちら。

mix11-5

ちょっとコピペしにくい。というかできない。

これで見放題ですな。ぐへへ、ぐへへへ~。たまりませんな~。あ、でも解像度低いとiPadでちょっと見づらい。文字潰れ気味。スライドはギリセーフだけど、コードが見れるかどうかが大事なので、ダウンロード後にちょっと確認しないとね。

2011年4月9日土曜日

Heroku for .NET

昨年末でしたね。SalesforceがHerokuを買収しました。

セールスフォース・ドットコム、Heroku社買収の最終合意に署名 - salesforce.com 日本

Heroku自体興味はあったけど、Rubyistじゃないからな~。AppEngineもな~。とかとか。あ、Herokuってあれっす。あれあれ。Rubyのホスティング。PaaS。いいよね~。

来週からMIX11が始まるっていうのに、まだmvcConfのビデオを見てるのんびり屋さんですが、面白いのありました。

mvcConf 2 - Troels Thomsen: Deploy ASP.NET MVC with No Effort | mvcConf | Channel 9

EC2をプラットフォームにした.NET向けのPaaS「AppHarbor」。スゴイんすよ。リポジトリにgit使うんですけど(初めてのgit読まねば)、commitすると向こうでビルドが走って、テスト実行して、デプロイまでやってくれるんすよ。とにかく無料で1アプリ公開できるから試してみた。あ、アプリは作ってないです。MVCのテンプレートそのままです。

AppHarbor - AppHarbor

手順はナニも難しいことはなくてですね、AppHarborにアカウント作って、アプリ作ると最初の画面に「これで出来るぜ」っていうコマンドが一覧で表示されるから、そのまま入力するだけです。

準備としてはGit使えるようにmsysGitいれとくだけです!

Help.GitHub - Set Up Git (Windows)

それも、ダウンロードして後はデフォルトのままクリッククリック。Git Bashってなんかカッコイイ。ハッカーな雰囲気を味わえる。そんな雰囲気を味わいたいからTortoiseGitを使わないオレ。まさに海賊王にふさわしい男気を感じる。ちっちぇ。

ah

git push(知ったかぶりだぜ!)するとAppHarborの管理画面に状況が表示されます。.gitignoreはつくっといたほうがいいです。

ah2

プロジェクトじゃなくてソリューションを追加して、標準のテストプロジェクトも入ってるんだけど、そのテストも実行されて、OKだったらデプロイ。試しにテスト失敗させるためにテストに以下のコードを追加。

using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace AppHarbor.Takepara.Tests
{
    [TestClass]
    public class SomeTest
    {
        [TestMethod]
        public void TestMethod1()
        {
            Assert.AreEqual(0, 1);
        }
    }
}

ah4

身も蓋もない...。

んで、push(そのまえにadd,commitも忘れずに)!

ah5

ビルド中~。

ah6

テスト失敗!

ah7

詳細見てみると確かにテスト失敗。コレを直して、再度push。

ah8

ちゃんと成功すればデプロイまで行ってアプリケーションが動作します。

動いてるのも見たいよね。どうぞ、こちらです。

ah9

http://takepara.apphb.com/

dyno(Herokuのコンピューティングパワーの単位)の追加とかどうするのかよくわかってないけど、そもそもそういう概念がないのかも?

Pricing – AppHarbor

Load barancingもサービス範囲内。今回DB使ってないけど、せっかくなので後で無料の20MB枠を使ってAccountコントローラも動作するようにしてみようかな。どうしようかな。環境設定を書き換えてくれる特殊なconfig変換があるので、connectionStringなんかはデプロイ時によしなになるようです。

パッと見ですよ、アプリケーション領域としての容量制限とか特に書かれてないわけですよ。DBは無料20MBだとしても。

ということはですね、あれです、単純にサイトを公開したいだけなら無料ですよ!gitとかVS2010でのプロジェクト形式というハードルがあるとはいえ、無料ですよ。後はAppHarborさんたちが頑張ってくれるんですよ。このエントリは中身が薄いけど、AppHarborは凄まじく濃くて、魅力的なサービスです。

AppHarbor(Azure以外の.NET PaaS、AppEngine for .NETでもよろし)がどこまで行けるのか目が離せないですね!

調子にのってvimで.gitignoreやろうとして全くコマンドが分からなかったのは恥ずかしくて言えね。

2011年4月7日木曜日

VS2010のCSSエディタでCSS3スキーマ対応

ASP.NET Wiki: Adding CSS 3.0 support to Visual Studio 2010

  1. スキーマをダウンロードしてインストール
    CSS 3 Intellisense Schema
    ↑ここからCSS3Setup.msiをダウンロードしてインストールしましょう。
  2. レジストリをいじる
    レジストリエディタをひらいて以下に移動してキーと文字列値を追加。
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Packages\{4A0C6509-BF90-43DA-ABEE-0ABA3A8527F1}
    Schemasキーを作成。その中に文字列値の”File”を作って”css30.xml”と入れる。さらに文字列値として”Friendly Name”を作って”CSS 3.0”と入れる。
    場所が9.0なのは間違いじゃないので気にしないでね!
  3. ファイルをコピーする
    1でインストールしたファイルが
    C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Packages\1033\schemas\CSS
    に作成されてるので、日本語版で使うためにコピーして1041のフォルダにも作っておきましょう。
    C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\Packages\1041\schemas\CSS

    file

こうしておけば、VS2010でCSS3のスキーマが有効になるよ!スゴイね!

css21

CSS 2.1を指定したままだと”box-shadow”はウニョウニョが出るよね。

css3

でも、CSS 3.0を選んでおくとValidですよ!

is

Intellisenceもほらー。transitionとか~。ね~。

dotnetConf2015 Japan

https://github.com/takepara/MvcVpl ↑こちらにいろいろ置いときました。 参加してくださった方々の温かい対応に感謝感謝です。