ASP.NET MVC 部分视图:输入名称前缀
假设我有 ViewModel 就像
public class AnotherViewModel
{
public string Name { get; set; }
}
public class MyViewModel
{
public string Name { get; set; }
public AnotherViewModel Child { get; set; }
public AnotherViewModel Child2 { get; set; }
}
在视图中我可以渲染一个部分在
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
部分我会做
<%= Html.TextBox("Name", Model.Name) %>
or
<%= Html.TextBoxFor(x => x.Name) %>
但是,问题是两者都会渲染 name="Name" 而我需要有 name="Child.Name" 以便模型活页夹才能正常工作。或者,当我使用相同的部分视图渲染第二个属性时, name="Child2.Name" 。
如何使我的部分视图自动识别所需的前缀?我可以将它作为参数传递,但这太不方便了。例如,当我想要递归渲染它时,情况会更糟。有没有一种方法可以使用前缀来渲染部分视图,或者更好的是,通过自动重新调整调用 lambda 表达式,以便
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
自动添加正确的“Child”。生成的名称/ID 字符串的前缀?
我可以接受任何解决方案,包括第 3 方视图引擎和库 - 我实际上使用 Spark View Engine(我使用其宏“解决”问题)和 MvcContrib,但在那里没有找到解决方案。 XForms、InputBuilder、MVC v2 - 任何提供此功能的工具/见解都会很棒。
目前我正在考虑自己编码,但这似乎是浪费时间,我不敢相信这个琐碎的事情还没有实现。
可能存在很多手动解决方案,并且欢迎所有这些解决方案。例如,我可以强制我的部分基于 IPartialViewModel
更新:此处有一个类似的问题,但没有答案。
Suppose I have ViewModel like
public class AnotherViewModel
{
public string Name { get; set; }
}
public class MyViewModel
{
public string Name { get; set; }
public AnotherViewModel Child { get; set; }
public AnotherViewModel Child2 { get; set; }
}
In the view I can render a partial with
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
In the partial I'll do
<%= Html.TextBox("Name", Model.Name) %>
or
<%= Html.TextBoxFor(x => x.Name) %>
However, the problem is that both will render name="Name" while I need to have name="Child.Name" in order for model binder to work properly. Or, name="Child2.Name" when I render the second property using the same partial view.
How do I make my partial view automatically recognize the required prefix? I can pass it as a parameter but this is too inconvenient. This is even worse when I want for example to render it recursively. Is there a way to render partial views with a prefix, or, even better, with automatic reconition of the calling lambda expression so that
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
will automatically add correct "Child." prefix to the generated name/id strings?
I can accept any solution, including 3-rd party view engines and libraries - I actually use Spark View Engine (I "solve" the problem using its macros) and MvcContrib, but did not find a solution there. XForms, InputBuilder, MVC v2 - any tool/insight that provide this functionality will be great.
Currently I think about coding this myself but it seems like a waste of time, I can't believe this trivial stuff is not implemented already.
A lot of manual solutions may exists, and all of them are welcome. For example, I can force my partials to be based off IPartialViewModel<T> { public string Prefix; T Model; }. But I'd rather prefer some existing/approved solution.
UPDATE: there's a similar question with no answer here.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(11)
您可以通过以下方式扩展 Html 帮助器类:
并在您的视图中简单地使用它,如下所示:
您将看到一切都正常!
You can extend Html helper class by this :
and simply use it in your views like this :
and you will see everything is ok!
到目前为止,我正在寻找同样的东西,我发现了最近的帖子:
http://davybrion.com/blog/2011/01/prefixing-input-elements-of-partial-views-with-asp-net-mvc/
so far, i was searching for the same thing I have found this recent post:
http://davybrion.com/blog/2011/01/prefixing-input-elements-of-partial-views-with-asp-net-mvc/
我的回答基于 Mahmoud Moravej 的回答,包括 Ivan Zlatev 的评论。
编辑:
对于嵌套部分渲染,Mohamoud 的答案是不正确的。仅在必要时才需要将新前缀附加到旧前缀。最新答案中并没有明确这一点(:
My answer, based on the answer of Mahmoud Moravej including the comment of Ivan Zlatev.
Edit:
The Mohamoud's answer is incorrect for nested partial rendering. You need to append the new prefix to the old prefix, only if it is necessary. This was not clear in the latest answers (:
使用 MVC2 您可以实现这一点。
这是强类型视图:
这是子类的强类型视图(必须存储在名为 EditorTemplates 的视图目录的子文件夹中):
这是控制器:
这是自定义类:
以及输出源:
现在这就完成了。在 Create Post 控制器操作中设置断点以进行验证。但是,不要将其与列表一起使用,因为它不起作用。有关更多信息,请参阅我关于将 EditorTemplates 与 IEnumerable 一起使用的问题。
Using MVC2 you can achieve this.
Here is the strongly typed view:
Here is the strongly typed view for the child class (which must be stored in a subfolder of the view directory called EditorTemplates):
Here is the controller:
Here are the custom classes:
And the output source:
Now this is complete. Set a breakpoint in the Create Post controller action to verify. Don't use this with lists however because it wont work. See my question on using EditorTemplates with IEnumerable for more on that.
这是一个老问题,但对于来到这里寻找解决方案的任何人,请考虑使用
EditorFor
,如 https://stackoverflow.com/a/29809907/456456。要从局部视图移动到编辑器模板,请按照以下步骤操作。验证您的分部视图是否已绑定到ComplexType。
将部分视图移至当前视图文件夹的子文件夹EditorTemplates,或文件夹Shared。现在,它是一个编辑器模板。
将
@Html.Partial("_PartialViewName", Model.ComplexType)
更改为@Html.EditorFor(m => m.ComplexType, "_EditorTemplateName")
。如果编辑器模板是复杂类型的唯一模板,则它是可选的。Html 输入元素将自动命名为
ComplexType.Fieldname
。This is an old question, but for anyone arriving here looking for a solution, consider using
EditorFor
, as suggested in a comment in https://stackoverflow.com/a/29809907/456456. To move from a partial view to an editor template, follow these steps.Verify that your partial view is bound to ComplexType.
Move your partial view to a subfolder EditorTemplates of the current view folder, or to the folder Shared. Now, it is an editor template.
Change
@Html.Partial("_PartialViewName", Model.ComplexType)
to@Html.EditorFor(m => m.ComplexType, "_EditorTemplateName")
. The editor template is optional if it's the only template for the complex type.Html Input elements will automatically be named
ComplexType.Fieldname
.PartailFor 用于 asp.net Core 2,以防有人需要。
PartailFor for asp.net Core 2 in case someone needs it.
如此处所述: https://stackoverflow.com/a/58943378/3901618 - 对于 ASP.NET Core - 您可以使用部分标签助手。
它生成所有必需的名称前缀。
As stated here: https://stackoverflow.com/a/58943378/3901618 - for ASP.NET Core - you can use the partial tag helper.
It generates all required name prefixes.
我也遇到了这个问题,经过一番痛苦之后,我发现重新设计我的界面更容易,这样我就不需要回发嵌套模型对象。这迫使我改变我的界面工作流程:当然,我现在要求用户分两步完成我梦想在一个步骤上做的事情,但新方法的可用性和代码可维护性现在对我来说具有更大的价值。
希望这对一些人有帮助。
I came across this issue also and after much pain i found it was easier to redesign my interfaces such that i didn't need to post back nested model objects. This forced me to change my interface workflows: sure i now require the user to do in two steps what i dreamed of doing on one, but the usability and code maintainability of the new approach is of greater value to me now.
Hope this helps some.
您可以为 RenderPartial 添加一个助手,它采用前缀并将其弹出到 ViewData 中。
然后是另一个助手,它连接 ViewData 值
,因此在视图中......
在部分......
You could add a helper for the RenderPartial which takes the prefix and pops it in the ViewData.
Then a further helper which concatenates the ViewData value
and so in the view ...
in the partial ...
和您一样,我将 Prefix 属性(字符串)添加到我的 ViewModel 中,并将其附加在模型绑定输入名称之前。 (YAGNI 阻止了下面的内容)
一个更优雅的解决方案可能是具有此属性的基本视图模型和一些 HtmlHelpers,它们检查视图模型是否派生自此基础,如果是,则将前缀附加到输入名称。
希望有帮助,
丹
Like you, I add Prefix property (a string) to my ViewModels which I append before my model bound input names. (YAGNI preventing the below)
A more elegant solution might be a base view model that has this property and some HtmlHelpers that check if the view model derives from this base and if so append the prefix to the input name.
Hope that helps,
Dan
在你调用 RenderPartial 之前怎么样
然后在你的部分中你有
How about just before you call RenderPartial you do
Then in your partial you have