【发布时间】:2015-09-30 15:14:11
【问题描述】:
我有一个基本请求对象RequestBase 定义如下:
public abstract class RequestBase
{
public abstract string Area { get; }
public abstract string ActionName { get; }
public abstract string LinkName { get; }
public abstract string ControllerName { get; }
}
还有一个这样的子类:
public class RequestTest : RequestBase
{
public Guid Id { get; set; }
public RequestTest()
{
Id = Guid.Empty;
}
#region implementation of RequestBase
public override string Area
{
get { return "MyArea"; }
}
public override string ActionName
{
get { return "Overview"; }
}
public override string ControllerName
{
get { return "Test"; }
}
public override string LinkName
{
get { return "Click me for awesome"; }
}
#endregion
}
问题。我想用这种方式编写一个帮助程序来建立链接:
@Html.ActionLinkByRequest(new RequestTest{Id = Guid.Empty})
我目前已经实现了
public static MvcHtmlString ActionLinkByRequest(this HtmlHelper helper, RequestBase request, object htmlAttributes = null)
{
return helper.ActionLink(request.LinkName, request.ActionName, request.ControllerName, request, htmlAttributes);
}
不幸的是,它呈现给:
<a href="/MyArea/Test/Overview?EventId=00000000-0000-0000-0000-000000000000&ActionName=Overview&LinkName=Click%20me%20for%20awesome&ControllerName=Test">Click me for awesome</a>
但我只想拥有一个
<a href="/MyArea/Test/Overview?EventId=00000000-0000-0000-0000-000000000000">Click me for awesome</a>
没有只读字段。因为它们是只读的,所以从我的Action 开始,我不需要它们在查询字符串中明确地等待具体实现RequestTest 并且无论如何都会拥有它们:
public ActionResult Overview(RequestTest request)
{
// do things here
return View();
}
有什么想法可以跳过为操作链接生成只读字段吗?也许通过某种方式使用反射?
由 cmets 编辑
这行得通吗?
public static MvcHtmlString ActionLinkByRequest(this HtmlHelper helper, RequestBase request, object htmlAttributes = null)
{
var rvd = new RouteValueDictionary();
foreach(var prop in request.GetType().GetProperties().Where(p => p.CanRead && p.CanWrite))
{
// add the property by name and the value
// rvd.Add(prop.Name, prop.GetValue());
}
// add the area (check if not already existing)
if(!rvd.ContainsKey("Area"))
rvd.Add("Area", request.AreaName);
return helper.ActionLink(request.LinkName, request.ActionName, request.ControllerName, request, htmlAttributes);
}
【问题讨论】:
-
为什么要将整个请求对象作为助手中的第四个参数传递?
-
应该传递什么?
-
只有你需要路由的值,我猜它更像
new {Id=request.id} -
但我不知道每个实现所需的值都可以拥有自己的值。或者我可以创建一个新的
RouteValueDictionary仅具有具体请求实现的属性并通过“手动”添加该区域? -
因此您将扩展 RequestBase 以包含更多属性。我懂了。我看不到您将任何属性定义为只读的位置,因此我看不到如何以编程方式将它们过滤掉。您也可以通过路由来处理其中的一些问题。
标签: c# .net asp.net-mvc reflection extension-methods