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="&amp;#39;Date&amp;#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="&amp;#39;Date&amp;#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" })%>
这将做的伎俩