C# EditorFor() 和 html 属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1625327/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
EditorFor() and html properties
提问by chandmk
Asp.Net MVC 2.0 preview builds provide helpers like
Asp.Net MVC 2.0 预览版提供了像
Html.EditorFor(c => c.propertyname)
If the property name is string, the above code renders a texbox.
如果属性名称是字符串,则上面的代码呈现一个文本框。
What if I want to pass in MaxLength and Size properties to the text box or my own css class property?
如果我想将 MaxLength 和 Size 属性传递给文本框或我自己的 css 类属性怎么办?
Do I need to create one template for each size and length combinations in my application? If so, that doesn't make the default templates that usable.
我是否需要为应用程序中的每种尺寸和长度组合创建一个模板?如果是这样,那不会使默认模板可用。
采纳答案by chandmk
I wrote a blog entry to answer my own question
我写了一篇博文来回答我自己的问题
Adding html attributes support for Templates - ASP.Net MVC 2.0 Beta
回答by Carlos Fernandes
You can define attributes for your properties.
您可以为您的属性定义属性。
[StringLength(100)]
public string Body { get; set; }
This is known as System.ComponentModel.DataAnnotations
.
If you can't find the ValidationAttribute
that you need you can allways define custom attributes.
这被称为System.ComponentModel.DataAnnotations
。如果你找不到ValidationAttribute
你需要的,你总是可以定义自定义属性。
Best Regards, Carlos
最好的问候,卡洛斯
回答by queen3
The problem is, your template can contain several HTML elements, so MVC won't know to which one to apply your size/class. You'll have to define it yourself.
问题是,您的模板可以包含多个 HTML 元素,因此 MVC 不知道将您的大小/类应用于哪一个。你必须自己定义它。
Make your template derive from your own class called TextBoxViewModel:
使您的模板派生自您自己的名为 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
}
}
}
In the template you can do this:
在模板中,您可以执行以下操作:
<input value="<%= Model.Value %>" <%= Model.GetAttributesString() %> />
In your view you do:
在您看来,您这样做:
<%= Html.EditorFor(x => x.StringValue) %>
or
<%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue, new IDictionary<string, object> { {'class', 'myclass'}, {'size', 15}}) %>
The first form will render default template for string. The second form will render the custom template.
第一个表单将为字符串呈现默认模板。第二个表单将呈现自定义模板。
Alternative syntax use fluent interface:
替代语法使用流畅的界面:
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) %>
Notice that instead of doing this in the view, you may also do this in controller, or much better in the ViewModel:
请注意,不是在视图中执行此操作,您也可以在控制器中执行此操作,或者在 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) });
}
Also notice that you can make base TemplateViewModel class - a common ground for all your view templates - which will contain basic support for attributes/etc.
另请注意,您可以创建基础 TemplateViewModel 类 - 所有视图模板的共同基础 - 它将包含对属性/等的基本支持。
But in general I think MVC v2 needs a better solution. It's still Beta - go ask for it ;-)
但总的来说,我认为 MVC v2 需要更好的解决方案。它仍然是测试版 - 去询问它;-)
回答by queen3
UPDATE: hm, obviously this won't work because model is passed by value so attributes are not preserved; but I leave this answer as an idea.
更新:嗯,显然这是行不通的,因为模型是按值传递的,因此不会保留属性;但我把这个答案作为一个想法。
Another solution, I think, would be to add your own TextBox/etc helpers, that will check for your own attributes on model.
我认为,另一种解决方案是添加您自己的 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)) %>
This one is easier but not as convinient/flexible.
这个更容易,但不那么方便/灵活。
回答by tj.
May want to look at Kiran Chand's Blog post, he uses custom metadata on the view model such as:
可能想看看Kiran Chand 的博客文章,他在视图模型上使用自定义元数据,例如:
[HtmlProperties(Size = 5, MaxLength = 10)]
public string Title { get; set; }
This is combined with custom templates that make use of the metadata. A clean and simple approach in my opinion but I would like to see this common use case built-in to mvc.
这与使用元数据的自定义模板相结合。在我看来,这是一种干净而简单的方法,但我希望看到这个内置于 mvc 的常见用例。
回答by spot
This may not be the slickest solution, but it is straightforward. You can write an extension to the HtmlHelper.EditorFor class. In that extension, you can supply an options parameter that will write the options to the ViewData for the helper. Here's some code:
这可能不是最巧妙的解决方案,但它很简单。您可以为 HtmlHelper.EditorFor 类编写扩展。在该扩展中,您可以提供一个选项参数,该参数将选项写入助手的 ViewData。这是一些代码:
First, the extension method:
一、扩展方法:
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
});
}
Next, the options object:
接下来,选项对象:
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.
}
And finally, here's the line from the String.ascx template:
最后,这是 String.ascx 模板中的一行:
<%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = ViewData["cssClass"] ?? "" }) %>
Frankly, I think this is straightforward and clear to the poor soul who has to maintain your code down the road. And it is easy to extend for various other bits of info you'd like to pass to your templates. It's working well so far for me in a project where I'm trying to wrap as much as I can in a set of template to help standardize the surrounding html, a la http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-5-master-page-templates.html.
坦率地说,我认为这对于必须在路上维护您的代码的可怜人来说是直截了当的。并且很容易扩展您想要传递给模板的各种其他信息。到目前为止,我在一个项目中运行良好,我试图在一组模板中尽可能多地包装以帮助标准化周围的 html,例如http://bradwilson.typepad.com/blog/2009/ 10/aspnet-mvc-2-templates-part-5-master-page-templates.html。
回答by tjeerdhans
I solved this by creating an EditorTemplate named String.ascx in my /Views/Shared/EditorTemplates folder:
我通过在我的 /Views/Shared/EditorTemplates 文件夹中创建一个名为 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 }) %>
In my view, I use
在我看来,我使用
<%= Html.EditorFor(model => model.SomeStringToBeEdited, new { size = 15, maxLength = 10 }) %>
Works like a charm for me!
对我来说就像一个魅力!
回答by Aaron
This is the cleanest and most elegant/simple way to get a solution here.
这是在此处获得解决方案的最干净,最优雅/最简单的方法。
Brilliant blog post and no messy overkill in writing custom extension/helper methods like a mad professor.
精彩的博客文章,在编写自定义扩展/帮助方法时没有像疯教授一样乱七八糟的矫枉过正。
http://geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx
http://geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx
回答by WEFX
In MVC3, you can set width as follows:
在MVC3中,您可以按如下方式设置宽度:
@Html.TextBoxFor(c => c.PropertyName, new { style = "width: 500px;" })
回答by Piotr Czy?
I don't know why it does not work for Html.EditorFor but I tried TextBoxFor and it worked for me.
我不知道为什么它不适用于 Html.EditorFor 但我尝试了 TextBoxFor 并且它对我有用。
@Html.TextBoxFor(m => m.Name, new { Class = "className", Size = "40"})
...and also validation works.
...还有验证工作。