强类型 T4MVC Action/ActionLink
我已经使用 T4MVC (仅供参考:v2.6.62)有一段时间了,我已经正在慢慢地将我们的代码转向这种工作方式(减少对 魔术字符串 的依赖)。
但我不得不停下来,因为出于某种原因,T4MVC 无法将对象转换为 url,并且似乎只能在原始类型(int/string/等)上工作。
这是一个示例:
路线细分:
/MyController/MyAction/{Number}/{SomeText}
类:
namespace MyNamespace
{
public class MyClass
{
public int Number { get; set; }
public string SomeText { get; set; }
}
}
控制器:
public class MyController
{
public virtual ActionResult MyAction(MyClass myClass)
{
return View();
}
}
视图:
<%= Html.Action(
T4MVC.MyController.Actions.MyAction(
new MyClass()
{
Number = 1,
SomeText = "ABC"
}
) %>
最终结果是这样的:
/MyController/MyAction?myClass=MyNamespace.MyClass
而不是
/MyController/MyAction/1/ABC
还有其他人有这个问题吗?像这样的 T4MVC url 可用吗?
ASP.NET 论坛也提出了这个问题。
I've been using T4MVC (FYI: v2.6.62) for quite some time, and I've been slowly moving over our code to this way of working (less reliance on magic strings).
But I've had to stop because, for some reason, T4MVC is unable to translate objects into urls, and only seems to be able to work on primitive types (int/string/etc).
Here is an example:
Route breakdown:
/MyController/MyAction/{Number}/{SomeText}
Class:
namespace MyNamespace
{
public class MyClass
{
public int Number { get; set; }
public string SomeText { get; set; }
}
}
Controller:
public class MyController
{
public virtual ActionResult MyAction(MyClass myClass)
{
return View();
}
}
View:
<%= Html.Action(
T4MVC.MyController.Actions.MyAction(
new MyClass()
{
Number = 1,
SomeText = "ABC"
}
) %>
The end result is this:
/MyController/MyAction?myClass=MyNamespace.MyClass
and not
/MyController/MyAction/1/ABC
Does anyone else have this problem? Are T4MVC urls like this available?
Question also asked at the ASP.NET Forum.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更新 (10/11/2012):最近添加了对 Model Unbinders 的支持(请参阅 doc)有望涵盖很多此类案例。
原始答案:
复制我在论坛帖子中的回复:
嗯,我认为这个还没有出现。也许在大多数情况下,人们都有接受对象的 Action 方法,对象的值来自发布的表单数据,而不是通过 URL 传递?在这种情况下,这个问题就不会出现。
我认为理论上可以更改 T4MVC 以支持这一点。它只需要将对象的所有顶级属性提升为路由值,而不是尝试使用对象本身(显然,当前的行为是伪造的,并且是盲目调用 ToString() 的结果)。
其他人是否遇到过这个问题并认为值得解决?
Update (10/11/2012): the recently added support for Model Unbinders (see section 3.1 in the doc) should hopefully cover a lot of these cases.
Original answer:
Copying my reply from the forum thread:
Hmmm, I don't think this has come up yet. Maybe in most cases that people have Action methods that take an object, the object's values come from posted form data, rather than being passed on the URL? In such scenario, the question doesn't arise.
I think in theory T4MVC could be changed to support this. It would just need to promote all the object's top level properties as route values rather than try to use the object itself (obviously, the current behavior is bogus, and is a result of just calling ToString() blindly).
Have others run into this and think it's worth addressing?
如果我正确理解了这个问题,那么以下语法应该可以让您解决这个问题。
我认为使语法更好的答案是将每个非值类型参数包装在每个生成的操作结果方法中的 RouteValueDictionary 中
编辑:(响应注释为字符不足)
啊好吧,我设法使用此重新创建上面的简单示例方法给出:
/MyController/MyAction/5/Hello
作为url。我不太确定嵌套的复杂类型在实践中会如何发挥作用。您可以使用一些递归深入到顶级对象并反映值以添加它们,但随后您会遇到一系列新问题,例如如何处理与父级相同的子属性名称属性名称。
这似乎是一个需要以适合每个人的方式解决的复杂问题。
也许某种适配器模式对于将复杂对象转换为路由值最有用。在最简单的情况下,这可能是声明一个扩展方法 ToRouteDictionary,该方法作用于您的复杂类型,并使用您对其工作方式的了解对其进行转换。只是大声思考,因为我显然不知道你的用例
If I've understood the problem correctly then the following syntax should allow you to work around the problem.
I think the answer to make the syntax nicer would be to wrap each non value type parameter in a RouteValueDictionary in each generated action result method
Edit: (Response to comment as not enough chars)
Ah ok I managed to recreate the simple example above using this method to give:
/MyController/MyAction/5/Hello
as the url.I'm not quite sure how nested complex types would pan out in practice. You could use some recursion to dive down the into the top-level object and reflect over the values to add them but then you open up a new set of issues, such as how to cope with a child property name that is identical to the parent property name.
This seems like it could be a complex problem to solve, in a manner that would work for everyone.
Perhaps some kind of adapter pattern would be most useful to transform a complex object into route values. In the simplest case this might be to declare an extension method ToRouteDictionary that acts on your complex type and transforms it using your knowledge of how it should work. Just thinking out loud as I'm obviously not aware of your use cases