Как я могу получить propertyName ContainerMetadata при попытке навигации по ModelMetadata с помощью C #?

#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 значение of Type , которое всегда имеет PropertyName значение null .

4. Но в приведенном выше случае ContainerModelMetadata является свойством. Каков правильный способ получить префикс выражения для родительского элемента?

5. не уверен, зачем вам это нужно, но в узле ContainerMetadata (for ContainerType ) ModelMetadataKind is Type и PropertyName is null (не null, только если ModelMetadataKind is Property , но Property не может быть контейнером). Другими словами, это похоже на тупик (больше никакой информации для перехода от этого).