Ссылка на экземпляр / Ссылки в webapi 2.0

1

Как вы делаете спокойный экземпляр ссылок в webapi 2?

Объект часто ссылается на экземпляры других объектов. Например, blogpost имеет ссылку на автора, создавшего сообщение.

public class Blogpost {
   public string Title {get; set;}
   public string Text {get; set;}
   public Author Author {get; set;}
}

Принцип RESTful, согласно этому видео @45:00, преобразуется в ссылку на прямой URI. Что-то вроде этого:

{
  "Id": 1,
  "Title": "My first blogpost",
  "Text": "Hello World",
  "Author": [ "href" : "http://app.com/api/authors/4"]
}

Как это должно быть сделано в webapi 2? По умолчанию, если вы отключите ленивую загрузку, ссылки просто возвращаются как пустой массив:

{
  "Id": 1,
  "Title": "My first blogpost",
  "Text": "Hello World",
  "Author": []
}
Теги:
rest
asp.net-web-api
asp.net-web-api2

1 ответ

2
Лучший ответ

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

Базовый класс Entity: Вероятно, у ваших сущностей уже есть базовый класс, определяющий общее свойство Id, если нет, просто создайте базовый класс и измените класс объектов наследования с DomainEntityBase.

public abstract class DomainEntityBase
{
    public int Id { get; set; }
}

Пользовательский разрешитель контрактов. Мы будем использовать настраиваемый разрешающий механизм для изменения поставщика стоимости ссылочных объектов.

public class ReferenceLinkContractResolver : CamelCasePropertyNamesContractResolver
{
    #region Methods
    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        var properties = base.CreateProperties(type, memberSerialization);
        var childProperties = properties.Where(p => typeof(DomainEntityBase).IsAssignableFrom(p.PropertyType));

        foreach (var c in childProperties)
        {
        c.ValueProvider = new ReferenceLinkingValueProvider(ReflectionHelper.GetProperty(type, c.PropertyName));
        }

        return properties;
    }
    #endregion
}

Поставщик настраиваемого значения. С помощью этого поставщика настраиваемых значений мы меняем сериализацию ссылочной сущности на свойство href.

public class ReferenceLinkingValueProvider : IValueProvider
{
    #region Fields
    private PropertyInfo m_property;
    #endregion

    #region Constructors
    public ReferenceLinkingValueProvider(PropertyInfo property)
    {
        m_property = property;
    }
    #endregion

    #region Methods
    public object GetValue(object target)
    {
        if (target == null)
        {
            return null;
        }

        var value = m_property.GetValue(target);
        var entity = value as DomainEntityBase;

        if (entity == null)
        {
        return value;
        }

        // If your resources are in plural, you will need some helper method 
        // to put in right plural (remember the resources with 'y' ends).
        var resourceName = entity.GetType().Name;

        // Here is where the real work happens. You change the entire entity
        // serialization to just the href property.
        return new
        {
        href = "http://app.com/api/{0}/{1}".With(resourceName, entity.Id)
        };
    }

    public void SetValue(object target, object value)
    {
        m_property.SetValue(target, value);
    }
    #endregion
}

Теперь, в вашем веб-конфигураторе api, установите ContractResolver вашего json-форматирования:

var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.JsonFormatter.SerializerSettings.ContractResolver = new ReferenceLinkContractResolver();

Примечание. Некоторые методы помощника и расширения, такие как "С", поступают из библиотеки HelperSharp.

  • 0
    Спасибо за отличный ответ. Это то, что вы используете сами? Мне кажется странным, что по этой теме так мало документации / информации.
  • 1
    Да, я создал его для конкретной ситуации, в моем случае я также сериализую свойства Href и Id.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню