2

さまざまな言語で記述された実装を備えた Web アプリケーションで使用されるカスタム テンプレート フレームワークがあり、Razor View エンジンを使用する ASP.NET MVC アプリケーションでこれを使用できるかどうかを調査しています。Web フォーム ビュー エンジンを使用する実装は既にありますが、Razor も使用できるようにしたいと考えています。

テンプレートは、実行時に解釈され、適切な html に置き換えられるマクロ タグを含む html ファイルで定義されます。以下は、このファイルの非常に簡略化されたバージョンです:-

[doctype]
<html>
  <head>
    [HeadScript]
    [HeadSectionText]
  </head>
  <body id="[if Home][Home][else]body[end if]">
    [form]
      [Content]
    [end form] 
    [EndBodyScript]
  </body>
</html>

ご覧のとおり、ドキュメントのさまざまなセクションに html を挿入する機会があり、その一部は単純な条件付きロジックの実装によって処理されます。これを Razor で使用するには、レンダリングされる Razor ビューからの HTML の挿入を含め、テンプレート内のすべてのマクロ タグを処理し、この操作の出力を最終的に送信される HTML として使用できる必要があります。クライアントに。

私は MVC 開発に関してはかなりグリーンですが、カスタムの ViewEngine と IView の実装を作成できることは知っています。おそらく、これを使用して、RazorView クラスを使用するカスタム エンジンを使用して、テンプレートに挿入される実際のコンテンツをレンダリングすることで、目的を達成できます。これは実行可能な解決策のように聞こえますか? もしそうなら、誰かが私を始めるためのヒントを持っていますか?

現在、ASP.NET WebForms エンジンを使用して部分的な Razor ビューをレンダリングするという厄介なソリューションがありますが、長期的には、WebForms エンジンを方程式から完全に除外できるソリューションが必要です。

正しい方向への押し込みは大歓迎です。

4

1 に答える 1

1

私はなんとか何かを理解することができました。私の問題はあなたが持っているものとまったく同じではありませんが、確かにあなたを助けることができます. しかし、まず最初に。

問題

いくつかのコントロールがあります (私の場合は部分ビューです)。例えば:

Views/Shared/EditName.cshtml
Views/Shared/EditAddress.cshtml
Views/Shared/EditEmail.cshtml
Views/Shared/EditFavoriteColour.cshtml

これらのコントロールのグループを (データベースまたは web.config で) 定義したいと考えています。たとえば、次のようになります。

SimpleEditGroup:
    EditName
ExtendedEditGroup:
    EditName
    EditEmail
FullEditGroup:
    EditName
    EditAddress
    EditEmail
    EditFavoriteColour

次に、特定のグループに基づいてビューをレンダリングしたいと考えています。次の構文で十分だと思っていました。

@Html.Partial("ControlGroup:ExtendedEditGroup", Model)

ソリューションのドラフト

私は、次のことを行う独自のレンダリング エンジンを作成したいと考えていました。

  1. ビューの名前が「ControlGroup:」で始まる場合は、以前に定義したグループを使用してページをレンダリングします。各コントロールは、RazorViewEngine によってレンダリングされる必要があります。
  2. ビューの名前が "ControlGroup:" で始まらない場合は、RazorViewEngine に任せてください。

リサーチ

次のリソースを見つけました。

  1. CodeProject に関する記事 - ASP.NET MVC3 のカスタム ViewEngine
  2. StackOverflow の質問に基づく記事 - ASP.NET MVC 3 でのウィジェット システムの作成
  3. 本Pro ASP.NET MVC 3 Frameworkをお勧めします。ASP.NET MVC 3 でカスタマイズできる項目の数がわかります。
  4. もちろん、ASP.NET MVC 3 RTMのソース コードは非常に役に立ちました。

最終的解決

MyViewEngine:

public class MyViewEngine : RazorViewEngine
{
  IDictionary<string, List<string>> groups = new Dictionary<string, List<string>>();

  public MyViewEngine()
  {
    // Temporary data source
    groups["SimpleEditGroup"] = new List<string>() { "EditName"};
    groups["ExtendedEditGroup"] = new List<string>() { "EditName", "EditEmail"};
  }

  public override ViewEngineResult FindView(ControllerContext controllerContext,
           string viewName, string masterName, bool useCache)
  {
    if (viewName.StartsWith("ControlGroup"))
    {
      var groupName = viewName.Split(':')[1];
      var controls = new List<ViewEngineResult>();

      foreach (var controlName in groups[groupName])
      {
        // Find each control using Razor magic
        var control = base.FindPartialView(controllerContext, controlName, useCache);
        if (control.View != null)
        {
          controls.Add(control);
        }
      }

      if(controls.Count > 0)
        return new ViewEngineResult(new MyView(controls), this);
    }

    return base.FindView(controllerContext, viewName, masterName, useCache);
  }
}

MyView.cs:

public class MyView : IView
{
  IList<ViewEngineResult> controls;

  public MyView(IList<ViewEngineResult> _controls)
  {
    controls = _controls;
  }

  public void Render(ViewContext viewContext, TextWriter textWriter)
  {
    // For simplicity I used table for layout
    textWriter.Write("<table border='1'>");

    foreach (var ctrl in controls)
    {
      textWriter.Write("<tr><td>");

      // Render control using Razor
      ctrl.View.Render(viewContext, textWriter);

      textWriter.Write("</td></tr>");
    }

    textWriter.Write("</table>");
  }
}

新しいエンジンを Global.asax に登録することを忘れないでくださいViewEngines.Engines.Add(new MyViewEngine());

ハッピーエンド

これは 2 つの方法で使用できます。コントローラーを使用してビューに埋め込むか、コントローラーからRender.Partial単に返すことです。PartialView

それがあなたを助けるかどうか私に知らせてください。また、ソリューションを共有することもできます。

于 2013-03-07T02:31:54.687 に答える