Невозможно указать EOF через клавиатуру в Windows (Netbeans), в программе C [дублировать]

Вы можете настроить валидаторы и метаданные из своего конкретного класса, но в решении есть несколько движущихся частей, в том числе два пользовательских поставщика метаданных.

Сначала создайте пользовательский Attribute, чтобы украсить каждый свойство базового класса. Это необходимо как флаг для наших заказных поставщиков, чтобы указать, когда необходим дальнейший анализ. Это атрибут:

[AttributeUsage(AttributeTargets.All, Inherited = true, AllowMultiple = true)]
public class BaseTypeAttribute : Attribute { }

Затем создайте пользовательский ModelMetadataProvider, наследующий от DataAnnotationsModelMetadataProvider:

public class MyModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
    protected override ModelMetadata CreateMetadata(
        IEnumerable<Attribute> attributes,
        Type containerType,
        Func<object> modelAccessor,
        Type modelType,
        string propertyName)
    {
        var attribute = attributes.FirstOrDefault(a => a.GetType().Equals(typeof(BaseTypeAttribute))) as BaseTypeAttribute;
        if (attribute != null && modelAccessor != null)
        {
            var target = modelAccessor.Target;
            var containerField = target.GetType().GetField("container");
            if (containerField == null)
            {
                var vdi = target.GetType().GetField("vdi").GetValue(target) as ViewDataInfo;
                var concreteType = vdi.Container.GetType();
                return base.CreateMetadata(attributes, concreteType, modelAccessor, modelType, propertyName);
            }
            else
            {
                var container = containerField.GetValue(target);
                var concreteType = container.GetType();
                var propertyField = target.GetType().GetField("property");
                if (propertyField == null)
                {
                    concreteType = base.GetMetadataForProperties(container, containerType)
                        .FirstOrDefault(p => p.PropertyName == "ConcreteType").Model as System.Type;
                    if (concreteType != null)
                        return base.GetMetadataForProperties(container, concreteType)
                            .FirstOrDefault(pr => pr.PropertyName == propertyName);
                }
                return base.CreateMetadata(attributes, concreteType, modelAccessor, modelType, propertyName);
            }
        }
        return base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
    }
}

Затем создайте пользовательский ModelValidatorProvider, наследующий от DataAnnotationsModelValidatorProvider:

public class MyModelMetadataValidatorProvider : DataAnnotationsModelValidatorProvider
{
    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        List<ModelValidator> vals = base.GetValidators(metadata, context, attributes).ToList();

        var baseTypeAttribute = attributes.FirstOrDefault(a => a.GetType().Equals(typeof(BaseTypeAttribute))) 
            as BaseTypeAttribute;

        if (baseTypeAttribute != null)
        {
            // get our parent model
            var parentMetaData = ModelMetadataProviders.Current.GetMetadataForProperties(context.Controller.ViewData.Model,
                metadata.ContainerType);

            // get the concrete type
            var concreteType = parentMetaData.FirstOrDefault(p => p.PropertyName == "ConcreteType").Model;
            if (concreteType != null)
            {
                var concreteMetadata = ModelMetadataProviders.Current.GetMetadataForProperties(context.Controller.ViewData.Model,
                    Type.GetType(concreteType.ToString()));

                var concretePropertyMetadata = concreteMetadata.FirstOrDefault(p => p.PropertyName == metadata.PropertyName);

                vals = base.GetValidators(concretePropertyMetadata, context, attributes).ToList();
            }
        }
        return vals.AsEnumerable();
    }
}

После этого зарегистрируйте оба пользовательских поставщика в Application_Start в Global.asax.cs:

ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new MvcApplication8.Controllers.MyModelMetadataValidatorProvider());
ModelMetadataProviders.Current = new MvcApplication8.Controllers.MyModelMetadataProvider();

Теперь измените свои модели следующим образом:

public class Person
{
    public Type ConcreteType { get; set; }

    [Required]
    [Display(Name = "Full name")]
    [BaseType]
    public string FullName { get; set; }

    [Display(Name = "Address Line 1")]
    [BaseType]
    public virtual string Address1 { get; set; }
}

public class Sender : Person
{
    public Sender()
    {
        this.ConcreteType = typeof(Sender);
    }

    [Required]
    [Display(Name = "Address Line One")]
    public override string Address1 { get; set; }
}

public class Receiver : Person
{
}

Обратите внимание, что базовый класс имеет новое свойство, ConcreteType. Это будет использоваться для указания того, какой класс наследования создавал этот базовый класс. Всякий раз, когда наследующий класс имеет метаданные, которые переопределяют метаданные в базовом классе, конструктор наследующего класса должен установить свойство ConcreteType базового класса.

Теперь, даже если ваше представление использует базовый класс, атрибуты, специфичные для любой конкретный класс наследования появится в вашем представлении и повлияет на валидацию модели.

Кроме того, вы должны иметь возможность превратить View в шаблон для типа Person и использовать шаблон для любой экземпляр, использующий базовый класс или наследующий его.

2
задан chqrlie 17 March 2016 в 08:28
поделиться

2 ответа

Только для Windows

Версия продукта: IDE NetBeans 8.2 (Build 201609300101)

Обновления: среда IDE NetBeans обновлена ​​до версии NetBeans 8.2 Патч 2

Выполнить> Задайте конфигурацию проекта> Настроить ...

Категория = Запустить

Тип консоли = Внешний терминал

Внешний тип терминала = Окно команд

Нажмите «Применить», затем «OK»

Запустить проект

Для отправки EOF нажмите ENTER, затем CTRL + D или Нажмите CTRL + D дважды

1
ответ дан Orthogod 16 August 2018 в 02:16
поделиться

getchar() хранит символы в буфере, пока вы не нажмете клавишу ввода. После нажатия клавиши ввода первый символ берется из буфера, если последующая переменная не назначается. Если вы использовали цикл while, это займет до \r\n. Если вы должны нажать enter key + ctrl+z, чтобы достичь EOF .

1
ответ дан Tavij 16 August 2018 в 02:16
поделиться
  • 1
    ну да это работает в cmd. Я попробовал метод, и он кажется идеальным. См. Редактирование, которое я сделал для вопроса. Он не работает на консоли NetBeans. – Siddharth Venu 17 March 2016 в 07:49
Другие вопросы по тегам:

Похожие вопросы: