私の目標は、MVC.Net ビューでコマンドの連鎖を可能にするオブジェクトを作成することです。
この概念を使用して作成したメニューのビューでの使用例を次に示します。
<nav class="navigation">
<%: Html
.menu()
.item("Introduction", "Introduction", "Home")
.item("About", "About", "Home")
.item("Systems", "Index", "Systems")
/*.item("Categories", "Categories", "Health")*/
.item("Test Cases", "TestCases", "Testing")
.category("Logging")
.item("UniMon Events", "UniMonEvents", "Logging")
.end()
.end() %>
</nav>
ご覧のとおり、さまざまなパーツ間の相互依存性を備えた多層メニューをすばやく構築できます。
ラムダ式を使用してフォームに対してこれと同じ効果を実現したいと思います。
理想的な構文は次のようになります。
<%: Html
.form()
.hidden(m=>m.property1)
.hidden(m=>m.property2)
.end() %>
問題が発生しているのは、隠しメソッドです。メソッドhiddenに渡さずにコンパイラにmを推論させる方法はないようです。
この構文を実現できます:
<%: Html
.form()
.hidden(Html, m=>m.property1)
.hidden(Html, m=>m.property2)
.end() %>
このクラスと拡張メソッドを使用する (表示されていません):
public class RouteForm
{
public HtmlHelper HtmlHelper { get; private set; }
public Dictionary<string, string> PostData { get; private set; }
public RouteForm(HtmlHelper htmlHelper)
{
HtmlHelper = htmlHelper;
PostData = new Dictionary<string, string>();
}
public RouteForm hidden<TModel, TValue>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression)
{
string name = ExpressionHelper.GetExpressionText(expression);
string value = GetFieldValue(htmlHelper, expression);
PostData.Add(name, value);
return this;
}
private static string GetFieldValue<TModel, TValue>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression)
{
object oValue = expression.Compile()(htmlHelper.ViewData.Model);
string value = (oValue is Enum) ? ((int)oValue).ToString() : oValue.ToString();
return value; ;
}
public MvcHtmlString end()
{
//TODO: render form with post data
return MvcHtmlString.Empty;
}
}
おそらくジェネリック型を持つクラスが探しているものかもしれないと思ったので、これを試しました:
public class RouteForm<TModel>
{
public HtmlHelper<TModel> HtmlHelper { get; private set; }
public Dictionary<string, string> PostData { get; private set; }
public RouteForm(HtmlHelper<TModel> htmlHelper)
{
HtmlHelper = htmlHelper;
PostData = new Dictionary<string, string>();
}
public RouteForm<TModel> hidden<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
{
string name = ExpressionHelper.GetExpressionText(expression);
string value = GetFieldValue(expression);
PostData.Add(name, value);
return this;//ERRORS: TModel is TModel
}
private string GetFieldValue<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
{
object oValue = expression.Compile()(
(TModel)HtmlHelper.ViewData.Model //ERRORS: Cannot convert type TModel to TModel
);
string value = (oValue is Enum) ? ((int)oValue).ToString() : oValue.ToString();
return value; ;
}
public MvcHtmlString end()
{
//TODO: render form with post data
return MvcHtmlString.Empty;
}
}
コメントを使用して上記のコードにエラーを入れました。
ありがとう!