2011年1月10日月曜日

新横浜公園

新横浜公園ガイドブック

ホッケーを始める前スラロームをやってたとき、日産スタジアムが横浜国際競技場だったころにはちょくちょくスケートの練習に行ってたんだけど、めっきり行かなくなって何年立つんだろう。

土曜に久しぶりにテニスをしたんだけど、あまりにもまともにできなくてショック。どうやら新横浜公園にはテニスの壁打ちをするスペースがあるらしいと聞いたので行ってみた次第です。

IMG_0118

IMG_0119

凄いね!こんなに綺麗に公園出来てるとは思ってもなかった。

SPORTSよこはまVol.3:特集(1/4)

数名の人たちがポコポコ壁打ちをしているところに乗り込んでやってみたデス。残念なことにボール持ってないから朝から買いに行って来たデス。

壁打ち難しいね~。でもスゴク楽しかった。ひとりで2時間。寂しさに負けそうになったけど、先に順番待ちの人のプレッシャーに負けた。みんなで仲良く使わないとね!

その後、いつ買ったのか覚えてないくらい前のサロモンの安物フィットネススケートを持って来てたので、ふらふらと公園内を滑ってみた。

IMG_0115

素敵なテニスコート10面。ひとりじゃできない。

IMG_0116

綺麗に舗装された道。

IMG_0120 IMG_0121

スケボーとかの専用スペース。バスケやってる人たちもたくさんいた。

IMG_0123

スラローム!子供たちがにょろにょろ滑ってたよ~。みんな上手だね~。スラロームなんてホッケー始めてから全くやってないけど、いまどきのスケートはシャーシも短いし、ウィールもちっちゃいのかな?

IMG_0122

1周2キロの周回コースがあって2周半滑って強風に心が折れたっす。

しばらくホッケーコートが使えないから、この公園でいろいろ遊んでみようかな。

そういえば、車で行ったけどスケート行くのもいいかもね。鶴見川沿いのサイクリングコースで行けそう。往復で15kmくらいみたいだし、ちょうどいい感じかも~。

2011年1月9日日曜日

zenbackをBloggerとTumblrで

年末年始いろんなサイトで関連記事やら関連リンクが全く同じデザインで表示されてるのを見て、なんだろな~、と。

どうもzenbackというブログパーツのサービスみたいで(ちゃんとpowered by zenbackって書いてるのに、気づかずにHTMLソースから追いかけちまった、てへ)。

zb1

zenbackであなたのブログに全てのフィードバックを。

運営は大御所シックス・アパート。エンジンはログリー株式会社のnewziaコネクト。

newziaコネクト | コンテキストマッチサービス

凄いね。こんなスゴイサービスが半年も前からベータテスト始まってたのを全然しらなかった。アルゴリズムは「当社独自の連想検索技術および行動履歴解析技術」ってことで、連想検索というのが気になる(TF/IDF的なことも計算してるんだろうけど、その辺はちょっと不明)。

コンテキストマッチ自体面白い領域なので、そろそろ真面目に取り組まないとな~とは思ってるんだけど、以前作ったものをもっとちゃんとzenbackみたいにエンジン化していきたいなと思ってる次第です。

はい、んで、こんな面白いサービスは早速自分のブログにも導入したくなるじゃないですか。仕込む時点ではBloggerとTumblrではうまく貼り付けられない的な事が書かれてた。

要するにアーカイブページ(一覧ページ)とエントリーページ(個別Permalink)の判定がごにょごにょと。そうかもね、分かりにくいよね。なので、やり方。

Tumblr

TumblrのDashboardからAccountのPreference

zb2

Customize your Blog

zb3

Themeメニューをクリックして以下の部分にzenbackのスクリプトを貼りつけ。

zb4

{block:Permalink}~{/block:Permalink}のあいだです。↑この画像だと同じ場所にTypePad Connectのコメント欄もだしてます。

Blogger

Bloggerもスクリプトを入れる場所が分かりにくいんだけど、それだけじゃなくてXML的にValidじゃないとダメだから、zenbackのサイトで出力されるscriptそのままじゃダメで、ちゃんとCDATAにしてあげないとエラーになります。

これもダッシュボードからデザイン→HTMLの編集へ進んで"ウィジェットのテンプレートを展開"にチェックを入れる。

zb5

<b:if cond='data:post.allowComments'>~<b:else>~</b:if>のelse以降のブロックにスクリプトを書きましょう。

zb6

ちょっと大きなXMLなのでエレメントブロックが分り易見れるようにVS2010で。編集はテキストエディタで十分。

zenbackのダッシュボードからCODEを取得すると

<!-- X:S ZenBackWidget -->
<script type="text/javascript">
document.write(unescape("%3Cscript")+" src='http://widget.zenback.jp/?base_uri=http%3A//takepara.blogspot.com&nsid=93212648191094697%3A%3A93212656780978809&rand="+Math.ceil((new Date()*1)*Math.random())+"' type='text/javascript'"+unescape("%3E%3C/script%3E")); </script> <!-- X:E ZenBackWidget -->

↑こうなので、ちゃんとCDATAにしましょう。

<!-- X:S ZenBackWidget -->
<script type="text/javascript">

//<![CDATA[
document.write(unescape("%3Cscript")+" src='http://widget.zenback.jp/?base_uri=http%3A//takepara.blogspot.com&nsid=93212648191094697%3A%3A93212656780978809&rand="+Math.ceil((new Date()*1)*Math.random())+"' type='text/javascript'"+unescape("%3E%3C/script%3E"));
//]]>
</script> <!-- X:E ZenBackWidget -->

これで関連記事やらなにやらいろいろ表示されますね!リコメンド素敵。

2011年1月3日月曜日

Razor Hosting

Hosting the Razor Engine for Templating in Non-Web Applications - Rick Strahl's Web Log

いや~、参っちゃった。年末にRazor Templating Engine出てたじゃないですか。で、Instapaper見てみたらこっちも”後で読む”扱いになってたので、そろそろ読むかと読んでみたわけですよ。

そしたらこっちはハナからAppDomainを別にしてコンパイルするのを前提に作られてるじゃない。もちろんプロセスのAppDomainと同じところでコンパイルも出来ますよ。その辺はぬかりないデスヨ。同じ目的でもこんなにも設計が違うんだね~、っていう感じです。ちなみにRickさんのRazor HostingではVB.NETコンパイラは入ってないです。

はい、Hello World!

var engine = new RazorEngine<RazorTemplateBase>();
dynamic context = new ExpandoObject();
context.Name = "World!";
var result = engine.RenderTemplate("Hello @Context.Name", new string[] { }, context);

匿名クラスじゃダメだったからdynamicなExpandoObjectで。まぁ、その辺は適当でね。

続いて、HtmlHelperを使うようにして見ましょう!RTE(Razor Templating Engine)にはちゃんとサンプルがあったからそのまま簡単にできたけど、今回は無いのでしょうがないから自分で書く。と、言ってもRTEのをままもってきて、RazorEngineのジェネリックに基底クラスとして指定です。この辺ちょっとあれっすね。まぁ、いいや。

internal class HtmlHelperFactory
{
    #region Methods
    /// <summary>
    /// Creates a <see cref="HtmlHelper{T}"/> for the specified model.
    /// </summary>
    /// <typeparam name="T">The model type.</typeparam>
    /// <param name="model">The model to create a helper for.</param>
    /// <param name="writer">The writer used to output html.</param>
    /// <returns>An instance of <see cref="HtmlHelper{T}"/>.</returns>
    public HtmlHelper<T> CreateHtmlHelper<T>(T model, TextWriter writer)
    {
        var container = new InternalViewDataContainer<T>(model);
        var context = new ViewContext(
            new ControllerContext(),
            new InternalView(),
            container.ViewData,
            new TempDataDictionary(),
            writer);

        return new HtmlHelper<T>(context, container);
    }
    #endregion

    #region Types
    /// <summary>
    /// Defines an internal view.
    /// </summary>
    private class InternalView : IView
    {
        #region Methods
        /// <summary>
        /// Renders the contents of the view to the specified writer.
        /// </summary>
        /// <param name="context">The current View context.</param>
        /// <param name="writer">The writer used to generate the output.</param>
        public void Render(ViewContext context, TextWriter writer) { }
        #endregion
    }

    /// <summary>
    /// Defines an internal view data container.
    /// </summary>
    private class InternalViewDataContainer<T> : IViewDataContainer
    {
        #region Methods
        /// <summary>
        /// Initialises a new instance of <see cref="InternalViewDataContainer{T}"/>.
        /// </summary>
        public InternalViewDataContainer(T model)
        {
            ViewData = new ViewDataDictionary<T>(model);
        }
        #endregion

        #region Properties
        /// <summary>
        /// Gets or sets the view data dictionary.
        /// </summary>
        public ViewDataDictionary ViewData { get; set; }
        #endregion
    }
    #endregion
}

/// <summary>
/// Provides a base implementation of a template base that supports <see cref="HtmlHelper{T}"/>s.
/// </summary>
/// <typeparam name="T">The model type.</typeparam>
[RequireNamespaces("System.Web.Mvc.Html")]
public class HtmlRazorTemplateBase<T> : RazorTemplateBase
{
    private readonly HtmlHelperFactory factory = new HtmlHelperFactory();

    /// <summary>
    /// Initialises a new instance of <see cref="HtmlTemplateBase{T}"/>.
    /// </summary>
    public HtmlRazorTemplateBase()
    {
        CreateHelper(Context);
    }
    /// <summary>
    /// Gets the <see cref="HtmlHelper{T}"/> for this template.
    /// </summary>
    public HtmlHelper<T> Html { get; private set; }

    private void CreateHelper(T model)
    {
        Html = factory.CreateHtmlHelper(model, Response.Writer);
    }
}

そのままですみませんね!

後は、テンプレートを書いてテイッ!と実行。

static string Template =
@"
@using System.Web.Mvc
@using System.Web.Mvc.Html
Hello @Context.Name
@AppDomain.CurrentDomain.FriendlyName
Email: @Html.TextBoxFor(m => m.Email)";

public void ExecuteParse()
{
    ExecuteParse(-1);
}

public void ExecuteParse(int counter)
{
    var model = new PageModel
                    {
                        Name = "World", 
                        Email = "someone@somewhere.com"
                    };
    var asms = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic ).Select(a=>a.Location);
    asms = asms.Concat(typeof(System.Web.Mvc.HtmlHelper)
                        .Assembly
                        .GetReferencedAssemblies().Select(an => Assembly.Load(an.FullName).Location)).Distinct();
    var refs = asms.Where(a => !a.EndsWith("System.dll")
                    && !a.EndsWith("System.Core.dll")
                    && !a.EndsWith("Microsoft.CSharp.dll")).ToArray();

    for (var i = 0; i < (counter != -1 ? 1 : Repeat); i++)
    {
        var sw = new Stopwatch();
        sw.Start();
        var engine = new RazorEngine<HtmlRazorTemplateBase<PageModel>>();
        var result = engine.RenderTemplate(Template, refs, model);

        sw.Stop();

        Console.WriteLine(result);
        Console.WriteLine(
            "{0} - {1} {2} ms {3:0,###} bytes",
            AppDomain.CurrentDomain.FriendlyName,
            counter != -1 ? counter : i,
            sw.ElapsedMilliseconds,
            Process.GetCurrentProcess().PrivateMemorySize64);
    }
}

なんですが、ここでかなりはまりました。

Template Execution Error: Security Transparent メソッド 'System.Web.Mvc.TypeDescriptorHelper.Get(System.Type)' がセキュリティ上重要なメソッド 'System.ComponentModel.DataAnnotations.AssociatedMetadataTypeTypeDescriptionProvider..ctor(System.Type)' にアクセスしようとして失敗しました。

アセンブリ 'System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' は条件付きの APTCA アセンブリであり、現在の AppDomain では有効化されていません。このアセンブリを有効化して部分信頼コードまたは Security Transparent コードで使用できるようにするには、AppDomain の作成時に、アセンブリ名 'System.ComponentModel.DataAnnotations, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9' を PartialTrustVisibleAssemblies リストに追加してください。

なんすかこのエラー。コエー。入っちゃいけない領域に入っちゃった系のエラーなんじゃ...。

ASP.NET アプリケーションでコード アクセス セキュリティを使用します。

なんかDataAnnotationsも含まれてるね~。透過的モデルに移行したアセンブリ。

だいたいが

[assembly: System.Security.AllowPartiallyTrustedCallers()]

これ書けって書いてるんだけど、これ何さ。ってなもんで、いろいろよくわかんない。そもそもRTEでは動くんだから何か違いが有るんだろうと、参照アセンブリとかいろいろ比較してみたわけですよ。

そしたらですね、ちゃんと違いがありました。

Razor Templating Engine

↑ここに行って、RazorEngine.Templates.csprojを見てみてください。

rh1

衝撃!分かります?普通さ~、Razorっつったら、MVC3を想定するじゃないっすか。だから、HtmlHelper使うために参照するアセンブリもMVC3のものにしちゃうじゃないっすか。そこだった...。ショック。MVC2で動かしてやがった。なんか意味があるんだろうね。いつかちゃんと調べるとしてですね、とりあえずRazor Hostingの場合もMVC2のアセンブリを参照してHtmlHelperを呼び出すとちゃんとできた。

rh2

はぁ...。ぜんぜんわかんなかった。いや、今でも理由はよく分からない。ATPCAってなにさ。部分信頼ってなんだね。AllowPartiallyTrustedCallersつけたら↓こう。

rh3

型 'ConsoleApplication1.HtmlRazorTemplateBase`1<T>' で継承セキュリティ ルールの違反が発生しました。派生型は、基本型のセキュリティ アクセシビリティと一致するか、それより低いアクセスが設定されている必要があります。

CASが廃止。.NET 4のセキュリティはどうなるのか? - @IT

ふんふん、そっか!なるほど!

...

よし、がんばろう。

で、コンパイル済みのものを呼び出すときは

var engine = new RazorEngine<HtmlRazorTemplateBase<PageModel>>();
var compiledId = engine.ParseAndCompileTemplate(refs, new StringReader(Template));

var result = engine.RenderTemplateFromAssembly(compiledId, model);

こうね。はいはい。

続いて、違うAppDomainで実行するときはこう。

var host = new RazorStringHostContainer<HtmlRazorTemplateBase<PageModel>>
{
    UseAppDomain = true,
    ReferencedAssemblies = refs.ToList()
};

host.Start();
var result = host.RenderTemplate(Template, model);
host.Stop();

ちゃんとHost.Start()とStop()しようね。これがCreateAppDomainとUnload。

ちなみにこのコードはこのままじゃRazor Hostingでは動きません。何でかというと、RazirStringHostContainerはジェネリックじゃないから。基底クラスの指定方法がHost派生しかなかったから、それじゃ面倒なので、RazorStringHostContainer自体を書き換えてます。

といっても、定義だけ。

    public class RazorStringHostContainer<T> : RazorBaseHostContainer<T>
        where T : RazorTemplateBase, new()
    {        

rh4

ちょいちょいAppDomainを生成するのはやっぱり遅すぎ。もうちょっと賢くやんないとね。

と、言うわけでRazorのテンプレートエンジン2作品を取り上げてみたけど、HtmlHelperを使ったりするようにWebで使う場合はAPTCAのところをちゃんとクリアしてからじゃないとダメですね。

ここまで書いてて気がついたんだけど、MVC3ってどうやってるのか見るといいのかな。BuildManagerだと違ったりするのかな。うぬ~。なぞは深まるばかり。

2026年06月09日の記事一覧

(全 21 件) Classic Pro プレミアム4芯マイクケーブルレビュー|NEUTRIK REANコネクタで確実な接続&ノイズにも強い | ギターいじリストのおうち RØDE ソナウラ | RØDE (JP) 「AIバブルは2030年に崩壊する」—...