興味深い質問 (+1)。目的は、デフォルトのモデル バインダーを使用してクエリ文字列パラメーターをパラメーターにバインドすることであると想定していAction
ます。
箱から出してすぐに、ActionLink
メソッドがこれを行うとは思いません(もちろん、独自のロールを作成することを妨げるものは何もありません)。リフレクターを見ると、object
が に追加されるとRouteValueDictionary
、キーと値のペアのみが追加されることがわかります。これはキーと値のペアを追加するコードであり、ご覧のとおり、オブジェクト プロパティをトラバースしていません。
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
{
object obj2 = descriptor.GetValue(values);
this.Add(descriptor.Name, obj2);
}
だからあなたのオブジェクトのために
var values = new { Filter = new Filter { MessageFilter = item.Message } }
追加されるキーはFilter
で、値はFilter
オブジェクト タイプの完全修飾名に評価されるオブジェクトです。
この結果は ですFilter=Youre.Namespace.Filter
。
正確なニーズに応じて可能なソリューションを編集します
拡張メソッド は機能します
静的フレームワーク メソッドExpressionHelper
とModelMetadata
(既存のヘルパーでも使用されます) を使用して、既定のモデル バインダーが理解する適切な名前とプロパティの値をそれぞれ決定することに注意してください。
public static class ExtentionMethods
{
public static MvcHtmlString ActionLink<TModel, TProperty>(
this HtmlHelper<TModel> helper,
string linkText,
string actionName,
string controllerName,
params Expression<Func<TModel, TProperty>>[] expressions)
{
var urlHelper = new UrlHelper(helper.ViewContext.HttpContext.Request.RequestContext);
var url = urlHelper.Action(actionName, controllerName);
if (expressions.Any())
{
url += "?";
foreach (var expression in expressions)
{
var result = ExpressionHelper.GetExpressionText(expression);
var metadata = ModelMetadata.FromLambdaExpression<TModel, TProperty>(expression, helper.ViewData);
url = string.Concat(url, result, "=", metadata.SimpleDisplayText, "&");
}
url = url.TrimEnd('&');
}
return new MvcHtmlString(string.Format("<a href='{0}'>{1}</a>", url, linkText));
}
}
サンプルモデル
public class MyViewModel
{
public string SomeProperty { get; set; }
public FilterViewModel Filter { get; set; }
}
public class FilterViewModel
{
public string MessageFilter { get; set; }
}
アクション
public ActionResult YourAction(MyViewModel model)
{
return this.View(
new MyViewModel
{
SomeProperty = "property value",
Filter = new FilterViewModel
{
MessageFilter = "stuff"
}
});
}
使用法
params
メソッドの最後のパラメーターを使用して、任意の数のビュー モデル プロパティをクエリ文字列に追加できます。
@this.Html.ActionLink(
"Your Link Text",
"YourAction",
"YourController",
x => x.SomeProperty,
x => x.Filter.MessageFilter)
マークアップ
<a href='/YourAction/YourController?SomeProperty=some property value&Filter.MessageFilter=stuff'>Your Link Text</a>
string.Format
を使用する代わりにTagBuilder
、URL で安全に渡されるようにクエリ文字列をエンコードする必要があります。この拡張メソッドには追加の検証が必要ですが、役立つと思います。また、この拡張メソッドは MVC 4 用に作成されていますが、以前のバージョン用に簡単に変更できることにも注意してください。MVC タグの 1 つがバージョン 3 用であることに今まで気づきませんでした。