ITKeyword,专注技术干货聚合推荐

注册 | 登录

c# - ASP MVC 5.2 using nested dictionaries for htmlAttributes in EditorFor

itPublisher 分享于

2021腾讯云限时秒杀,爆款1核2G云服务器298元/3年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2021阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

推荐:asp.net mvc源码分析-EditorFor

在我们的mvc日常开发会经常遇到什么LabelFor、EditorFor、Editor等等,这个扩展方法有很多是相似的。这里我们以EditorFor来说说吧,我觉得这个相对要复杂一点。

up vote 0 down vote favorite I want to pass a nested Dictionary into the EditorFor viewData. @{

var viewData = new RouteValueDictionary();

var htmlAttributes = new RouteValueDictionary();

htmlAttributes.Add("title", "foo");

viewData["htmlAttributes"] = htmlAttributes;

}

Html.EditorFor(model => model.SomeProperty, viewData);

The problem is that the tile="foo" does not get rendered. When I'm using var htmlAttributes = new {title = "foo"};

everything is working as expected. I need htmlAttributes to be a Dictionary, because in my application it is dynamically generated. So how can I pass a Dictionary in there. I already tried to pass in thmlAttributes as an ExpandoObject, but that does not work either. c# asp.net asp.net-mvc editorfor asp.net-mvc-5.2
  |
  this question asked Dec 9 '14 at 13:51 wertzui 1,495 12 25



 |  2 Answers

up vote 0 down vote I am afraid it not possible to do, at least not the easy way cuz the EditorFor creates many html elements and therefor it's not clear on which element the htmlAttributes should apply. However, the hard way is to implement your own Object.cshtml in Views/Shared/EditorTemplates/Object.cshtml. Following is an example of custom Object.cshtml (bootstrap specific) where you can grab values from ViewData and construct the output Html anyway you like. @using MvcApplication1.Utility

@if (ViewData.TemplateInfo.TemplateDepth > 1) {

@ViewData.ModelMetadata.SimpleDisplayText

} else {

foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForDisplay && !ViewData.TemplateInfo.Visited(pm))) {

var htmlString = prop.IsReadOnly ? Html.Display(prop.PropertyName) : Html.Editor(prop.PropertyName);

if (prop.HideSurroundingHtml) {

@htmlString

}

else

{

var errors = Html.ValidationErrors(prop);

<div class="form-group @(prop.IsReadOnly ? "form-group-readonly" : "") @(errors.Any() ? "has-error has-feedback" : "")">

<label class="control-label" for="@ViewData.TemplateInfo.GetFullHtmlFieldId(prop.PropertyName)">@prop.GetDisplayName()</label>

@htmlString

@foreach (var err in errors)

{

<div class="field-validation-error">@err.ErrorMessage</div>

}

</div>

}

}

}

and the utility functions

public static IEnumerable<ModelError> ValidationErrors<TModel>(this HtmlHelper<TModel> htmlHelper, ModelMetadata modelMetadata)

{

推荐:ASP.NET MVC概览(C#)

Model-View-Controller(MVC) 架构模式将一个应用程序分为三个组成部分:模型,视图与控制器。ASP.NET MVC框架为创建基于MVC的Web应用程序提供了一种替代方案。ASP

string modelName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(modelMetadata.PropertyName);

return ValidationErrors(htmlHelper, modelName);

}

public static IEnumerable<ModelError> ValidationErrors<TModel>(this HtmlHelper<TModel> htmlHelper)

{

return ValidationErrors(htmlHelper, String.Empty);

}

private static IEnumerable<ModelError> ValidationErrors(this HtmlHelper htmlHelper, String modelName)

{

FormContext formContext = htmlHelper.ViewContext.FormContext;

if (formContext == null)

yield break;

if (!htmlHelper.ViewData.ModelState.ContainsKey(modelName))

yield break;

ModelState modelState = htmlHelper.ViewData.ModelState[modelName];

if (modelState == null)

yield break;

ModelErrorCollection modelErrors = modelState.Errors;

if (modelErrors == null)

yield break;

foreach(var err in modelErrors)

yield return err;

}


  |
  this answer answered Dec 9 '14 at 14:21 Ibrahim ben Salah 568 2 10      In this case I'm using it for a simple string property which should render as Textbox. And since MVC 5.1 it is possible to add a Property "htmlAttributes" to the additionalViewData param which gets rendered as html attributes. So this should not be the problem. –  wertzui Dec 9 '14 at 15:33      In that case use Html.TextBoxFor instead –  Ibrahim ben Salah Dec 9 '14 at 15:39      But I would like to use it on EditorFor, because that way i can also use my own Template which might contain of 2 TextBoxes. When using EditorFor, that "htmlAttributes" will be written into the ViewData and automatically be picked up by all Textboxes on that custom template. –  wertzui Dec 10 '14 at 7:41      It just doesnt work that way it you are using EditorFor, please read my answer carefully –  Ibrahim ben Salah Dec 10 '14 at 23:04



 |  up vote 0 down vote ---Accepted---Accepted---Accepted---

It is currently not possible (MVC 5.2) see this Bug: https://aspnetwebstack.codeplex.com/workitem/1736
  |
  this answer answered Dec 15 '14 at 13:04 wertzui 1,495 12 25



 | 

推荐:ASP.NET MVC (一)

从零开始学习ASP.NET MVC:开天辟地入门篇(一) 2009-2-27 20:11:26 已被阅读:1151 发表评论 一.摘要 和自身水平有关, 我总喜欢写入门级别的文章.比如虽然做项目

up vote 0 down vote favorite I want to pass a nested Dictionary into the EditorFor viewData. @{

var viewData = new RouteValueDictionary();

var htmlAttributes = new Rout


相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。