que*_*en3 119 asp.net-mvc spark-view-engine mvccontrib
假设我有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; }
}
Run Code Online (Sandbox Code Playgroud)
在视图中,我可以渲染部分
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
Run Code Online (Sandbox Code Playgroud)
在部分我会做
<%= Html.TextBox("Name", Model.Name) %>
or
<%= Html.TextBoxFor(x => x.Name) %>
Run Code Online (Sandbox Code Playgroud)
但是,问题是两者都将呈现name ="Name",而我需要name ="Child.Name"才能使模型绑定器正常工作.或者,当我使用相同的局部视图渲染第二个属性时,name ="Child2.Name".
如何使我的局部视图自动识别所需的前缀?我可以将它作为参数传递,但这太不方便了.当我想要例如以递归方式呈现它时,情况会更糟.有没有办法用前缀渲染部分视图,或者更好的是,通过自动重新调用lambda表达式来实现
<% Html.RenderPartial("AnotherViewModelControl", Model.Child) %>
Run Code Online (Sandbox Code Playgroud)
会自动添加正确的"孩子".生成的名称/ id字符串的前缀?
我可以接受任何解决方案,包括第三方视图引擎和库 - 我实际上使用Spark View引擎(我使用它的"解决"问题)和MvcContrib,但没有在那里找到解决方案.XForms,InputBuilder,MVC v2 - 提供此功能的任何工具/洞察都会很棒.
目前我考虑自己编码,但这似乎是浪费时间,我不敢相信这些琐碎的东西还没有实现.
可能存在许多手动解决方案,欢迎所有这些解决方案.例如,我可以强制我的部分基于IPartialViewModel <T> {public string Prefix; T模型; }.但我宁愿选择一些现有/已批准的解决方案.
更新:有没有回答类似的问题在这里.
Mah*_*vej 109
您可以通过以下方式扩展Html帮助程序类:
using System.Web.Mvc.Html
public static MvcHtmlString PartialFor<TModel, TProperty>(this HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression, string partialViewName)
{
string name = ExpressionHelper.GetExpressionText(expression);
object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model;
var viewData = new ViewDataDictionary(helper.ViewData)
{
TemplateInfo = new System.Web.Mvc.TemplateInfo
{
HtmlFieldPrefix = name
}
};
return helper.Partial(partialViewName, model, viewData);
}
Run Code Online (Sandbox Code Playgroud)
并在这样的视图中使用它:
<%= Html.PartialFor(model => model.Child, "_AnotherViewModelControl") %>
Run Code Online (Sandbox Code Playgroud)
你会看到一切都好!
Jok*_*kin 93
到目前为止,我正在寻找我最近发现这篇文章的相同内容:
http://davybrion.com/blog/2011/01/prefixing-input-elements-of-partial-views-with-asp-net-mvc/
<% Html.RenderPartial("AnotherViewModelControl", Model.Child, new ViewDataDictionary
{
TemplateInfo = new System.Web.Mvc.TemplateInfo { HtmlFieldPrefix = "Child1" }
})
%>
Run Code Online (Sandbox Code Playgroud)
aso*_*879 12
我的回答是基于Mahmoud Moravej的回答,包括Ivan Zlatev的评论.
public static MvcHtmlString PartialFor<TModel, TProperty>(this HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel, TProperty>> expression, string partialViewName)
{
string name = ExpressionHelper.GetExpressionText(expression);
object model = ModelMetadata.FromLambdaExpression(expression, helper.ViewData).Model;
StringBuilder htmlFieldPrefix = new StringBuilder();
if (helper.ViewData.TemplateInfo.HtmlFieldPrefix != "")
{
htmlFieldPrefix.Append(helper.ViewData.TemplateInfo.HtmlFieldPrefix);
htmlFieldPrefix.Append(name == "" ? "" : "." + name);
}
else
htmlFieldPrefix.Append(name);
var viewData = new ViewDataDictionary(helper.ViewData)
{
TemplateInfo = new System.Web.Mvc.TemplateInfo
{
HtmlFieldPrefix = htmlFieldPrefix.ToString()
}
};
return helper.Partial(partialViewName, model, viewData);
}
Run Code Online (Sandbox Code Playgroud)
编辑:对于嵌套的部分渲染,穆罕默德的答案是不正确的.只有在必要时才需要将新前缀附加到旧前缀.这在最新的答案中并不清楚(:
使用MVC2可以实现这一目标.
这是强类型视图:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MvcLearner.Models.Person>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Create
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create</h2>
<% using (Html.BeginForm()) { %>
<%= Html.LabelFor(person => person.Name) %><br />
<%= Html.EditorFor(person => person.Name) %><br />
<%= Html.LabelFor(person => person.Age) %><br />
<%= Html.EditorFor(person => person.Age) %><br />
<% foreach (String FavoriteFoods in Model.FavoriteFoods) { %>
<%= Html.LabelFor(food => FavoriteFoods) %><br />
<%= Html.EditorFor(food => FavoriteFoods)%><br />
<% } %>
<%= Html.EditorFor(person => person.Birthday, "TwoPart") %>
<input type="submit" value="Submit" />
<% } %>
</asp:Content>
Run Code Online (Sandbox Code Playgroud)
这是子类的强类型视图(必须存储在名为EditorTemplates的视图目录的子文件夹中):
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcLearner.Models.TwoPart>" %>
<%= Html.LabelFor(birthday => birthday.Day) %><br />
<%= Html.EditorFor(birthday => birthday.Day) %><br />
<%= Html.LabelFor(birthday => birthday.Month) %><br />
<%= Html.EditorFor(birthday => birthday.Month) %><br />
Run Code Online (Sandbox Code Playgroud)
这是控制器:
public class PersonController : Controller
{
//
// GET: /Person/
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Index()
{
return View();
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Create()
{
Person person = new Person();
person.FavoriteFoods.Add("Sushi");
return View(person);
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Person person)
{
return View(person);
}
}
Run Code Online (Sandbox Code Playgroud)
以下是自定义类:
public class Person
{
public String Name { get; set; }
public Int32 Age { get; set; }
public List<String> FavoriteFoods { get; set; }
public TwoPart Birthday { get; set; }
public Person()
{
this.FavoriteFoods = new List<String>();
this.Birthday = new TwoPart();
}
}
public class TwoPart
{
public Int32 Day { get; set; }
public Int32 Month { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
和输出源:
<form action="/Person/Create" method="post"><label for="Name">Name</label><br />
<input class="text-box single-line" id="Name" name="Name" type="text" value="" /><br />
<label for="Age">Age</label><br />
<input class="text-box single-line" id="Age" name="Age" type="text" value="0" /><br />
<label for="FavoriteFoods">FavoriteFoods</label><br />
<input class="text-box single-line" id="FavoriteFoods" name="FavoriteFoods" type="text" value="Sushi" /><br />
<label for="Birthday_Day">Day</label><br />
<input class="text-box single-line" id="Birthday_Day" name="Birthday.Day" type="text" value="0" /><br />
<label for="Birthday_Month">Month</label><br />
<input class="text-box single-line" id="Birthday_Month" name="Birthday.Month" type="text" value="0" /><br />
<input type="submit" value="Submit" />
</form>
Run Code Online (Sandbox Code Playgroud)
现在这已经完成了.在Create Post控制器操作中设置断点以进行验证.不要将它与列表一起使用,因为它不起作用.有关更多信息,请参阅我使用带有IEnumerable的EditorTemplates的问题.
这是一个老问题,但对于到此处寻找解决方案的任何人来说,请考虑使用EditorFor
,如/sf/answers/2086693521/中的评论所示.要从部分视图移动到编辑器模板,请按照下列步骤操作.
验证您的局部视图是否绑定到ComplexType.
将局部视图移动到当前视图文件夹的子文件夹EditorTemplates或Shared文件夹.现在,它是一个编辑器模板.
更改@Html.Partial("_PartialViewName", Model.ComplexType)
到@Html.EditorFor(m => m.ComplexType, "_EditorTemplateName")
.如果编辑器模板是复杂类型的唯一模板,则该模板是可选的.
Html输入元素将自动命名ComplexType.Fieldname
.
PartailFor for asp.net Core 2以防有人需要它.
public static ModelExplorer GetModelExplorer<TModel, TResult>(this IHtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TResult>> expression)
{
if (expression == null)
throw new ArgumentNullException(nameof(expression));
return ExpressionMetadataProvider.FromLambdaExpression(expression, htmlHelper.ViewData, htmlHelper.MetadataProvider);
}
public static IHtmlContent PartialFor<TModel, TResult>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TResult>> expression, string partialViewName, string prefix = "")
{
var modelExplorer = helper.GetModelExplorer(expression);
var viewData = new ViewDataDictionary(helper.ViewData);
viewData.TemplateInfo.HtmlFieldPrefix += prefix;
return helper.Partial(partialViewName, modelExplorer.Model, viewData);
}
Run Code Online (Sandbox Code Playgroud)
如此处所述: https: //stackoverflow.com/a/58943378/3901618 - 对于 ASP.NET Core - 您可以使用部分标记帮助器。
<partial name="AnotherViewModelControl" for="Child" />
<partial name="AnotherViewModelControl" for="Child2" />
Run Code Online (Sandbox Code Playgroud)
它生成所有必需的名称前缀。
归档时间: |
|
查看次数: |
50165 次 |
最近记录: |