내 페이지 중 하나에 대해 상당히 복잡한 모델이 있습니다. 여러 개의 중첩 된 모델 객체로 구성됩니다. 자식 컬렉션 자식 객체를 사용하여 하나 개의 섹션에서, 내가 지금처럼 EditorFor
도우미를 사용MVC3 : 그래프에서 모델 속성의 위치를 도우미로 알리기.
@Html.EditorFor(m => m.CAS.LERoles[i].LE, "TinyText")
, 나는 같은 것을 끝낼 것이다
<input id="CAS_LERoles_0__LE" class="tinyText" type="text" value="0" name="CAS.LERoles[0].LE" data-val-required="The Legal Entity field is required." data-val-number="The field Legal Entity must be a number." data-val="true">
...이 중대하다 . 하지만 다음과 같이 목록을 선택하는 열거 형을 변환하는 내 자신의 도우미를 썼다 :
public static HtmlString EnumSelectListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> forExpression,
object htmlAttributes,
bool blankFirstLine)
where TModel : class
where TProperty : struct
{
//MS, it its infinite wisdom, does not allow enums as a generic constraint, so we have to check here.
if (!typeof(TProperty).IsEnum) throw new ArgumentException("This helper method requires the specified model property to be an enum type.");
//initialize values
var metaData = ModelMetadata.FromLambdaExpression(forExpression, htmlHelper.ViewData);
var propertyName = metaData.PropertyName;
var propertyValue = htmlHelper.ViewData.Eval(propertyName).ToStringOrEmpty();
//build the select tag
var returnText = string.Format("<select id=\"{0}\" name=\"{0}\"", HttpUtility.HtmlEncode(propertyName));
if (htmlAttributes != null)
{
foreach (var kvp in htmlAttributes.GetType().GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(htmlAttributes, null)))
{
returnText += string.Format(" {0}=\"{1}\"", HttpUtility.HtmlEncode(kvp.Key),
HttpUtility.HtmlEncode(kvp.Value.ToStringOrEmpty()));
}
}
returnText += ">\n";
if (blankFirstLine)
{
returnText += "<option value=\"\"></option>";
}
//build the options tags
foreach (var enumName in Enum.GetNames(typeof(TProperty)))
{
var idValue = ((int)Enum.Parse(typeof(TProperty), enumName, true)).ToString();
var displayValue = enumName;
// get the corresponding enum field using reflection
var field = typeof(TProperty).GetField(enumName);
var display = ((DisplayAttribute[])field.GetCustomAttributes(typeof(DisplayAttribute), false)).FirstOrDefault();
var titleValue = string.Empty;
if (display != null)
{
// The enum field is decorated with the DisplayAttribute =>
// use its value
displayValue = display.Name;
titleValue = display.Description.ToStringOrEmpty();
}
returnText += string.Format("\t<option value=\"{0}\" title=\"{1}\"",
HttpUtility.HtmlEncode(idValue), HttpUtility.HtmlEncode(titleValue));
if (enumName == propertyValue)
{
returnText += " selected=\"selected\"";
}
returnText += string.Format(">{0}</option>\n", HttpUtility.HtmlEncode(displayValue));
}
//close the select tag
returnText += "</select>\n";
return new HtmlString(returnText);
}
을하고 내가 그렇게처럼 내 페이지에서 이것을 사용할 때 :
@Html.EnumSelectListFor(m => m.CAS.LERoles[i].APMasterRole)
나는이와 끝까지 :
<select name="APMasterRole" id="APMasterRole">
(stuff)
</select>
나는 회상하면 적절하게 번역 될 것이라고 생각하고 이제는 조금 천진난하다는 것을 알았습니다. 적절한 이름과 ID를 생성하는 데 사용할 수있는 MVC 프레임 워크에 내장 된 메커니즘이 정말로 필요합니다. 그렇지 않으면 이것이 반성의 미로처럼 보입니다.
그래서이 질문과 같은 복잡한 모델 객체의 이름과 ID 문자열을 만들 수있는 메커니즘이 있습니까? 그렇다면 어떻게 사용됩니까? 그렇지 않다면 폼 데이터를 객체 모델에 다시 바인딩 할 수 있도록 비교적 간단한 이름과 ID 생성 방법이 있습니까?
감사합니다.
... 나는 MVC 프레임 워크의 소스 코드를 읽는 것에 대해 농담을하고 있다고 생각합니다. 'TagBuilder'는 내가 조사 할 어떤 것입니다. 그러나 내 방어에서 인코딩해야 할 모든 것이 인코딩됩니다. 선택 상자의 실제 크기 제한을 고려해 볼 때, 나는'+ = '연산이 반드시 큰 문제는 아니지만 그렇다고 더 좋을 수 있다고 생각합니다. –
아니, 물론 나는 소스 코드를 읽는 것에 대해 농담하지 않는다. 나는이 프레임 워크가 어떻게 만들어지고 작동하는지 모른 채 사람들이 어떤 프레임 워크로 고급 어플리케이션을 개발할 수있는 방법을 상상조차 할 수 없다. 나는 당신이 모든 것을 인코딩한다는 것에 동의하지만, 왜 수동으로해야 하는가? 이 측면에서 당신을 도울 프레임 워크에 이미 존재하는 메커니즘이있을 때 바퀴를 다시 발명해야하는 이유는 무엇입니까? –
솔직히 말해서 나는 그와 같은 메커니즘이 있다는 것을 몰랐다. 그것은 질문의 이유이다. 나는 항상 코드를 개선 할 방법을 찾고 있지만, 프레임 워크의 소스 코드를 읽는 것은 다소 어려울 것 같다. –