Базовые идентификаторы модели ASP.Net Core API привязывают к пользовательским идентификаторам - PullRequest
0 голосов
/ 30 октября 2019

У меня есть структуры, которые представляют идентификаторы для разных типов. Эти структуры имеют свойство int "Id", открытый конструктор с параметром (int id) и реализуют интерфейс IEquatable. Я хочу, чтобы мое приложение ASP.Net Core WebAPI каким-то образом связывало эти структуры с входящими целыми идентификаторами в запросе. Я знаю, что существуют настраиваемые привязки моделей, но для их использования мне нужно реализовать настраиваемые привязки моделей для всех моделей запросов, потому что маркировки каждого свойства структуры ключа с помощью настраиваемого связывателя модели недостаточно - мне нужно зарегистрировать провайдера настраиваемого связывания модели, гдепереключите ModelType и верните привязку одной модели, например:

    public class CustomModelBinderProvider : IModelBinderProvider
    {
        public IModelBinder GetBinder(ModelBinderProviderContext context)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (context.Metadata.ModelType == typeof(DogQueryModel))
            {
                return new BinderTypeModelBinder(typeof(DogQueryModelBinder));
            }

Поэтому я не могу создать только одну привязку модели для каждой структуры Id - необходимо создать ее для каждой модели запроса.

Чтобы прояснить ситуацию, я приведу пример кода этой структуры, модели запроса и действия:

    public struct DogKey : IEquatable<DogKey>
    {
        public DogKey(int id)
        {
            Id = id;
        }

        public int Id { get; }

        #region IEquatable implementation
        #endregion IEquatable implementation
    }

    public class DogQueryModel
    {
        public DogKey Id { get; set; }
        public SomeOtherKey OtherId { get; set; }
        public string Name { get; set; }
    }

    [HttpGet("dog")]
    public async Task<ActionResult<IList<DogResultModel>>> GetDogs([FromQuery]DogQueryModel dogQueryModel)
    {
        //use dogQueryModel.Id as DogKey struct
    }

Я хочу запросить его следующим образом: https://localhost/api/v1/dogs/dog?id=1&otherId=2&Name=dogname

1 Ответ

1 голос
/ 31 октября 2019

Вы можете сделать это, применив конвертер типа , это упомянуто в документации , но, к сожалению, без примера. Я реализовал необходимые биты, чтобы ваш пример работал.

Я добавил некоторые общие ограничения в классе KeyConverter, которые, кажется, соответствуют вашим потребностям, хотя они и не нужны.

public class KeyConverter<T> : TypeConverter
    where T : struct, IEquatable<T>
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        if (sourceType == typeof(string))
        {
            return true;
        }

        return base.CanConvertFrom(context, sourceType);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        var stringValue = value as string;
        if (!string.IsNullOrWhiteSpace(stringValue))
        {
            if(int.TryParse(stringValue, out int parsed))
            {
                return Activator.CreateInstance(typeof(T), new object[] { parsed });
            }
        }
        return base.ConvertFrom(context, culture, value);
    }
}

Затем украсьте ваши ключевые классы атрибутом TypeConverter.

[TypeConverter(typeof(KeyConverter<DogKey>))]
public struct DogKey : IEquatable<DogKey>
{
    public DogKey(int id)
    {
        Id = id;
    }

    public int Id { get; }

    #region IEquatable implementation
    #endregion IEquatable implementation

}

[TypeConverter(typeof(KeyConverter<CatKey>))]
public struct CatKey : IEquatable<CatKey>
{
    public CatKey(int id)
    {
        Id = id;
    }

    public int Id { get; }

    #region IEquatable implementation
    #endregion IEquatable implementation

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...