Câu hỏi thú vị (+1). Tôi giả định rằng mục đích là sử dụng trình kết nối mô hình mặc định để ràng buộc các tham số chuỗi truy vấn tới các tham số Action
của bạn.
Hết hộp Tôi không tin rằng phương pháp ActionLink
sẽ làm điều này cho bạn (tất nhiên không có gì ngăn cản bạn tự mình lăn). Nhìn vào phản xạ, chúng ta có thể thấy rằng khi object
được thêm vào RouteValueDictionary
, thì chỉ có cặp giá trị khóa mới được thêm vào. Đây là mã bổ sung các cặp giá trị khóa và bạn có thể thấy không có sự vượt qua các thuộc tính đối tượng.
foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values))
{
object obj2 = descriptor.GetValue(values);
this.Add(descriptor.Name, obj2);
}
Vì vậy, đối tượng của bạn
var values = new { Filter = new Filter { MessageFilter = item.Message } }
phím được bổ sung là Filter
và giá trị là đối tượng Filter
của bạn mà sẽ đánh giá vào tên đầy đủ của các loại đối tượng của bạn.
Kết quả của việc này là Filter=Youre.Namespace.Filter
.
Sửagiải pháp khả thi tùy theo nhu cầu chính xác của bạn
Extension Methodlàm công việc
Lưu ý rằng nó sử dụng phương pháp khung tĩnh ExpressionHelper
và ModelMetadata
(mà cũng được sử dụng bởi những người trợ giúp hiện có) để xác định tên thích hợp mà Trình mô hình hóa mặc định sẽ hiểu và giá trị của thuộc tính tương ứng.
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));
}
}
mẫu Models
public class MyViewModel
{
public string SomeProperty { get; set; }
public FilterViewModel Filter { get; set; }
}
public class FilterViewModel
{
public string MessageFilter { get; set; }
}
Action
public ActionResult YourAction(MyViewModel model)
{
return this.View(
new MyViewModel
{
SomeProperty = "property value",
Filter = new FilterViewModel
{
MessageFilter = "stuff"
}
});
}
Cách sử dụng
Bất kỳ số thuộc tính mô hình chế độ xem nào của bạn có thể được thêm vào chuỗi truy vấn thông qua thông số params
cuối cùng của phương thức.
@this.Html.ActionLink(
"Your Link Text",
"YourAction",
"YourController",
x => x.SomeProperty,
x => x.Filter.MessageFilter)
Markup
<a href='/YourAction/YourController?SomeProperty=some property value&Filter.MessageFilter=stuff'>Your Link Text</a>
Thay vì sử dụng string.Format
bạn có thể sử dụng TagBuilder
, querystring nên được mã hóa để được thông qua một cách an toàn trong một URL và phương pháp mở rộng này sẽ cần một số xác nhận thêm nhưng Tôi nghĩ nó có thể hữu ích. Cũng lưu ý rằng, mặc dù phương pháp mở rộng này được xây dựng cho MVC 4, nó có thể dễ dàng sửa đổi cho các phiên bản trước. Tôi đã không nhận ra rằng một trong những thẻ MVC đã được cho phiên bản 3 cho đến bây giờ.
+1 câu hỏi hay –
cảm ơn chỉnh sửa; Tôi refactored câu trả lời và thay thế quên thêm 'tiền tố'! –
@AndrasZoltan Không có vấn đề gì. – DaveShaw