EditorFor()和html属性
Asp.Net MVC 2.0预览版本提供了像helpers一样的帮助
Html.EditorFor(c => c.propertyname)
如果属性名称是string,上面的代码呈现一个texbox。
如果我想将MaxLength和Size属性传递给文本框或我自己的css类属性呢?
我是否需要为应用程序中的每个大小和长度组合创build一个模板? 如果是这样,那不会使可用的默认模板。
在MVC3中,你可以设置宽度如下:
@Html.TextBoxFor(c => c.PropertyName, new { style = "width: 500px;" })
我通过在我的/ Views / Shared / EditorTemplates文件夹中创build一个名为String.ascx的EditorTemplate来解决这个问题:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %> <% int size = 10; int maxLength = 100; if (ViewData["size"] != null) { size = (int)ViewData["size"]; } if (ViewData["maxLength"] != null) { maxLength = (int)ViewData["maxLength"]; } %> <%= Html.TextBox("", Model, new { Size=size, MaxLength=maxLength }) %>
在我看来,我使用
<%= Html.EditorFor(model => model.SomeStringToBeEdited, new { size = 15, maxLength = 10 }) %>
对我来说就像一个魅力!
在这个或任何其他线程中为@ Html.EditorFor设置HTML属性的答案都不是很有帮助。 不过,我在那find了一个很好的答案
造型@ Html.EditorFor帮手
我使用了相同的方法,它没有写很多额外的代码,它工作得很漂亮。 请注意,Html.EditorFor的html输出的id属性被设置。 查看代码
<style type="text/css"> #dob { width:6em; } </style> @using (Html.BeginForm()) { Enter date: @Html.EditorFor(m => m.DateOfBirth, null, "dob", null) }
数据注解和date格式为“dd MMM yyyy”的模型属性
[Required(ErrorMessage= "Date of birth is required")] [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd MMM yyyy}")] public DateTime DateOfBirth { get; set; }
像一个魅力工作,没有写很多额外的代码。 这个答案使用ASP.NET MVC 3 Razor C#。
可能要查看Kiran Chand的博文 ,他在视图模型上使用自定义元数据,例如:
[HtmlProperties(Size = 5, MaxLength = 10)] public string Title { get; set; }
这与使用元数据的自定义模板相结合。 我认为一个干净而简单的方法,但我希望看到这个常见的用例内置到mvc。
我很惊讶没有人提到在“additionalViewData”中传递它,并在另一边阅读它。
查看 (为了清晰起见,换行符):
<%= Html.EditorFor(c => c.propertyname, new { htmlAttributes = new { @class = "myClass" } } )%>
编辑模板:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %> <%= Html.TextBox("", Model, ViewData["htmlAttributes"])) %>
问题是,你的模板可以包含几个HTML元素,所以MVC将不知道应用你的大小/类的哪一个。 你必须自己定义它。
让你的模板派生自你自己的类TextBoxViewModel:
public class TextBoxViewModel { public string Value { get; set; } IDictionary<string, object> moreAttributes; public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes) { // set class properties here } public string GetAttributesString() { return string.Join(" ", moreAttributes.Select(x => x.Key + "='" + x.Value + "'").ToArray()); // don't forget to encode }
}
在模板中,你可以这样做:
<input value="<%= Model.Value %>" <%= Model.GetAttributesString() %> />
在你看来,你做到了:
<%= Html.EditorFor(x => x.StringValue) %> or <%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue, new IDictionary<string, object> { {'class', 'myclass'}, {'size', 15}}) %>
第一种forms将呈现string的默认模板。 第二种forms将呈现自定义模板。
可选语法使用stream利的界面:
public class TextBoxViewModel { public string Value { get; set; } IDictionary<string, object> moreAttributes; public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes) { // set class properties here moreAttributes = new Dictionary<string, object>(); } public TextBoxViewModel Attr(string name, object value) { moreAttributes[name] = value; return this; }
}
// and in the view <%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) %>
注意,不是在视图中这样做,你也可以在控制器中做到这一点,或者在ViewModel中做得更好:
public ActionResult Action() { // now you can Html.EditorFor(x => x.StringValue) and it will pick attributes return View(new { StringValue = new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) }); }
另外请注意,您可以创build基本TemplateViewModel类 – 所有视图模板的共同点 – 它将包含对属性/等的基本支持。
但总的来说,我认为MVC v2需要一个更好的解决scheme。 它仍然是Beta – 去问问它;-)
我认为使用CSS是要走的路。 我希望我可以做更多与.NET编码,如在XAML,但在浏览器中CSS是王道。
的site.css
#account-note-input { width:1000px; height:100px; }
.cshtml
<div class="editor-label"> @Html.LabelFor(model => model.Note) </div> <div class="editor-field"> @Html.EditorFor(model => model.Note, null, "account-note-input", null) @Html.ValidationMessageFor(model => model.Note) </div>
乔
您可以为属性定义属性。
[StringLength(100)] public string Body { get; set; }
这被称为System.ComponentModel.DataAnnotations
。 如果找不到所需的ValidationAttribute
,则可以通过定义自定义属性。
最好的问候,卡洛斯
这可能不是最简单的解决scheme,但它很简单。 你可以写一个扩展到HtmlHelper.EditorFor类。 在该扩展中,您可以提供一个选项参数,将选项写入帮助程序的ViewData中。 这是一些代码:
一,扩展方法:
public static MvcHtmlString EditorFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, TemplateOptions options) { return helper.EditorFor(expression, options.TemplateName, new { cssClass = options.CssClass }); }
接下来,选项对象:
public class TemplateOptions { public string TemplateName { get; set; } public string CssClass { get; set; } // other properties for info you'd like to pass to your templates, // and by using an options object, you avoid method overload bloat. }
最后,这里是String.ascx模板的一行:
<%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = ViewData["cssClass"] ?? "" }) %>
坦率地说,我认为这对于那些不得不维护你的代码的穷人来说是简单明了的。 而且很容易扩展你希望传递给你的模板的其他各种信息。 目前为止,我在一个项目中工作得很好,在这个项目中,我尽可能地在一组模板中包装,以帮助标准化周围的HTML, http : //bradwilson.typepad.com/blog/2009/ 10 / aspnet-mvc-2-templates-part-5-master-page-templates.html 。
我写了一篇博客回答我自己的问题
为模板添加html属性支持 – ASP.Net MVC 2.0 Beta
我不知道为什么它不适用于Html.EditorFor,但我试过TextBoxFor,它为我工作。
@Html.TextBoxFor(m => m.Name, new { Class = "className", Size = "40"})
…还有validation工作。
在MVC 5中,如果你想添加任何属性,你可以简单的做
@Html.EditorFor(m => m.Name, new { htmlAttributes = new { @required = "true", @anotherAttribute = "whatever" } })
从这个博客find的信息
在我的实践中,我发现最好使用EditorTemplates,只有一个HtmlHelper – 大多数情况下是TextBox。 如果我想要一个更复杂的html结构的模板,我会写一个单独的HtmlHelper。
鉴于我们可以将整个ViewData对象代替TextBox的htmlAttributes。 另外,如果需要特殊处理,我们可以为ViewData的某些属性编写一些自定义代码:
@model DateTime?
@* 1) applies class datepicker to the input; 2) applies additionalViewData object to the attributes of the input 3) applies property "format" to the format of the input date. *@
@{ if (ViewData["class"] != null) { ViewData["class"] += " datepicker"; } else { ViewData["class"] = " datepicker"; } string format = "MM/dd/yyyy"; if (ViewData["format"] != null) { format = ViewData["format"].ToString(); ViewData.Remove("format"); } } @Html.TextBox("", (Model.HasValue ? Model.Value.ToString(format) : string.Empty), ViewData)
下面是视图和输出的html语法的例子:
@Html.EditorFor(m => m.Date)
<input class="datepicker" data-val="true" data-val-required="&#39;Date&#39; must not be empty." id="Date" name="Date" type="text" value="01/08/2012">
@Html.EditorFor(m => m.Date, new { @class = "myClass", @format = "M/dd" })
<input class="myClass datepicker" data-val="true" data-val-required="&#39;Date&#39; must not be empty." id="Date" name="Date" type="text" value="1/08">
因为问题是为EditorFor不TextBoxFor WEFX的build议不起作用。
要更改单个input框,可以处理EditorFor方法的输出:
<%: new HtmlString(Html.EditorFor(m=>m.propertyname).ToString().Replace("class=\"text-box single-line\"", "class=\"text-box single-line my500pxWideClass\"")) %>
也可以更改所有的EditorFors,因为MVC用.text-box设置了EditorFor文本框的类,因此您可以在样式表或页面上覆盖此样式。
.text-box { width: 80em; }
另外,你可以设置风格
input[type="text"] { width: 200px; }
- 这将覆盖.text-box,并将更改所有input文本框,EditorFor或其他。
我也有问题设置TextBox在MVC3中的宽度,同时设置Clsss属性为TextArea控件工作,但不为TextBoxFor控件或EditorFor控件:
我尝试了下面这个为我工作:
@ Html.TextBoxFor(model => model.Title,new {Class =“textBox”,style =“width:90%;”})
在这种情况下,validation也是完美的。
有一种方法可以让视图模型的代表处理打印出像这样的特殊渲染。 我已经为分页类做了这个,我暴露了模型Func<int, string> RenderUrl
上的公共属性来处理它。
所以定义如何写入自定义位:
Model.Paging.RenderUrl = (page) => { return string.Concat(@"/foo/", page); };
输出Paging
类的视图:
@Html.DisplayFor(m => m.Paging)
…和实际的Paging
视图:
@model Paging @if (Model.Pages > 1) { <ul class="paging"> @for (int page = 1; page <= Model.Pages; page++) { <li><a href="@Model.RenderUrl(page)">@page</a></li> } </ul> }
这可能被视为过度复杂的事情,但我使用这些传呼机无处不在,看不到相同的样板代码来渲染。
更新:嗯,显然这不会工作,因为模型是通过值传递,所以不保留属性; 但我留下这个答案是一个想法。
另一个解决scheme,我认为,将是添加自己的TextBox / etc的助手,这将检查您自己的模型属性。
public class ViewModel { [MyAddAttribute("class", "myclass")] public string StringValue { get; set; } } public class MyExtensions { public static IDictionary<string, object> GetMyAttributes(object model) { // kind of prototype code... return model.GetType().GetCustomAttributes(typeof(MyAddAttribute)).OfType<MyAddAttribute>().ToDictionary( x => x.Name, x => x.Value); } } <!-- in the template --> <%= Html.TextBox("Name", Model, MyExtensions.GetMyAttributes(Model)) %>
这一个更容易,但不够方便/灵活。
这是在这里得到解决scheme最清洁,最优雅/简单的方法。
精彩的博客文章,并没有在编写自定义扩展/帮手方法像疯狂教授杂乱矫枉过正。
http://geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx
我真的很喜欢@tjeerdans的答案,它利用了/ Views / Shared / EditorTemplates文件夹中名为String.ascx的EditorTemplate。 这似乎是对这个问题最直接的回答。 不过,我想要一个使用Razor语法的模板。 此外,似乎MVC3使用string模板作为默认值(请参阅StackOverflow问题“ string的mvc显示模板用于整数 ”),因此您需要将模型设置为对象而不是string。 我的模板似乎工作到目前为止:
@model object @{ int size = 10; int maxLength = 100; } @if (ViewData["size"] != null) { Int32.TryParse((string)ViewData["size"], out size); } @if (ViewData["maxLength"] != null) { Int32.TryParse((string)ViewData["maxLength"], out maxLength); } @Html.TextBox("", Model, new { Size = size, MaxLength = maxLength})
我解决了它!
对于Razor来说,语法是:
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" })
将文本区宽度调整为我在style参数中定义的宽度。
对于ASPx,语法是:
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
这将做的伎俩