#c# #asp.net-core #razor #razorengine #asp.net-core-5.0
#c# #asp.net-core #razor #razorengine #asp.net-core-5.0
Вопрос:
У меня есть проект, написанный с использованием C#
поверх ASP.NET Основа ядра 5.
Я пытаюсь использовать Razor engine для ручной визуализации ModelMetadata
содержимого. Это ModelMetadata
дает мне свойство, ContainerMetadata
которое сообщает мне о родительском ModelMetadata
объекте в случае свойства сложного типа, найденного в родительском ModelMetadata.
Однако PropertyName
свойство для ContinerMetadata
всегда равно null.
У меня есть следующая модель представления. MainViewModel
Нижеприведенное передается от контроллера к представлению с помощью View()
метода.
public class MainViewModel
{
public int ID { get; set; }
public class CellViewModel { get; set; }
}
public class CellViewModel
{
public string Name { get; set; }
}
Теперь в режиме razor я получаю доступ ModelMetadata
к переданной модели с помощью Html.ViewData.ModelMetadata
Моя цель — иметь возможность отображать HTML вручную, используя метод расширения. Чтобы получить ModelMetadata
для каждого свойства, которое я хочу отобразить, я использую следующую функцию
public static IHtmlContent GetHtml(this IHtmlHelper html, ModelMetadata metadata)
{
HtmlContentBuilder code = new HtmlContentBuilder();
IEnumerable<ModelMetadata> elements = metadata.Properties.Where(metadata => metadata.ShowForDisplay);
foreach(ModelMetadata element in elements)
{
if(element.IsClass)
{
// When this code is called, each proeprty on the element.ModelType has ContainerModelmetadata which is element
// However, when I access ContainerModelmetadata.PropertyName I get null.
var subCode = html.GetHtml(element);
code.AppendHtml(subCode);
continue;
}
code.AppendHtml(html.Editor(element.propertyName));
}
return code;
}
Как вы можете видеть в комментарии выше, я не могу получить доступ к имени свойства родительского элемента.
Итак, решите эту проблему, я могу передавать родительский элемент каждый раз следующим образом
public static IHtmlContent GetHtml(this IHtmlHelper html, ModelMetadata metadata, string parentName = null)
{
HtmlContentBuilder code = new HtmlContentBuilder();
IEnumerable<ModelMetadata> elements = metadata.Properties.Where(metadata => metadata.ShowForDisplay);
foreach(ModelMetadata element in elements)
{
if(element.IsClass)
{
// When this code is called, each proeprty on the element.ModelType has ContainerModelmetadata which is element
// However, when I access ContainerModelmetadata.PropertyName I get null.
var subCode = html.GetHtml(element, element.Name);
code.AppendHtml(subCode);
continue;
}
string expression = element.propertyName;
if(!string.IsNullOrEmpty(parentName))
{
expression = $"{parentName}.{element.PropertyName}";
}
code.AppendHtml(html.Editor(expression));
}
return code;
}
Как вы можете видеть выше, я должен передавать parentName
на каждый уровень, чтобы я мог получить правильное выражение. Проблема здесь в том, что в моем коде у меня есть более глубокие уровни, и для этого мне требовалось передавать родительское имя каждой функции. Я надеюсь избежать необходимости передавать как Modelmetadata свойства, так и ParentName. Я надеюсь, что смогу получить родительское имя из данного Modelmetadata
, поскольку у меня уже есть ContainerModelmetadata
.
Как я могу правильно получить доступ к значению PropertyName
из ContinerMetadata
when ContinerMetadata
не равно null?
Комментарии:
1. считаете ли вы, что этого достаточно, чтобы незнакомый человек понял проблему, поиграл с ней, прежде чем смог решить ее с помощью какого-то конкретного кода?
2. @KingKing Я обновил вопрос, надеясь, что это даст вам и другим всю информацию.
3. как вы думаете, почему
PropertyName
он должен быть изContainerModelMetadata
? это неправильно. На самом деле это от токаModelMetadata
, смотрите это docs.microsoft.com/en-us/dotnet/api /… — Существует 4 типаModelMetadataKind
, в том числеConstructor
,Property
,Parameter
иType
. ЗначениеPropertyName
равно null, если этот вид НЕProperty
является. ТакжеContainerModelMetadata
обычно имеетModelMetadataKind
значение ofType
, которое всегда имеетPropertyName
значение null .4. Но в приведенном выше случае ContainerModelMetadata является свойством. Каков правильный способ получить префикс выражения для родительского элемента?
5. не уверен, зачем вам это нужно, но в узле
ContainerMetadata
(forContainerType
)ModelMetadataKind
isType
иPropertyName
is null (не null, только еслиModelMetadataKind
isProperty
, ноProperty
не может быть контейнером). Другими словами, это похоже на тупик (больше никакой информации для перехода от этого).