【问题标题】:.net - Minify Your Dto In Web Api.net - 在 Web Api 中缩小 Dto
【发布时间】:2022-08-23 17:19:19
【问题描述】:

想象一下,如果您有一个包含许多适用于业务逻辑的属性的 dto。一个简单的例子如下:

public class PartnerDto
    {
        public int PartnerId { get; set; }
        public int BrandId { get; set; }
        public int CobrandIdId { get; set; }
        public Brand brand { get; set; }
    }

在此示例中,Brand 类自身具有自定义属性。

这很好,除非我喜欢 WebApi 在响应正文中或作为请求有效负载使用此类。但是如果客户不关心自定义属性怎么办?假设在这种情况下客户端只关心int 字段。

一个想法是创建一个MiniPartnerDto,它只包含我喜欢向客户端公开的属性。然后,使用AutoMapper 映射这两个对象。基本上如下:

public class MiniPartnerDto
    {
        public int PartnerId { get; set; }
        public int BrandId { get; set; }
        public int CobrandIdId { get; set; }
    }

[HttpGet(\"{id}\")]
        public async Task<IActionResult> Get(int id)
        {
            var result = _mapper.Map<MiniPartnerDto>(await _partnerManager.GetById(id));
            if (result == null)
            {
                return NotFound();
            }
            return Ok(result);
        } 

我不介意这个想法,但我不喜欢它。我想知道是否有一种方法可以让我忽略某些属性,而无需创建一个完全不同的类。

  • 为不同的需求使用单独的视图模型是一种很好的做法,而其他方法太痛苦了(比如自定义模型绑定)。如果您不想多次键入属性,也可以使用继承
  • 我也是这么想的。我可以使用MiniPartnerDto 作为基础并在PartnerDto 类中继承它。

标签: c# asp.net-web-api2 .net-6.0


【解决方案1】:

如果您不想制作更多的对象值,其中一种方法是conditional property serialization in Json.NET

试试这样:

public class PartnerDto
{
    public int PartnerId { get; set; }
    public int BrandId { get; set; }
    public int CobrandIdId { get; set; }
    public Brand Brand { get; set; }

    public bool ShouldSerializeBrand()
    {
        // Brand property serialized only when brand name is Stackoverflow
        return (Brand.Name == "Stackoverflow");
    }
}

在复杂的情况下,您可以像这样通过枚举来处理它:

public enum SLForPartnerDto
{
    None,
    ViewForm,
    EditForm
}

public class PartnerDto
{
    [JsonIgnore]
    public SLForPartnerDto SerializationLevel { get; set; }
    public int PartnerId { get; set; }
    public int BrandId { get; set; }
    public int CobrandIdId { get; set; }
    public Brand Brand { get; set; }

    public bool ShouldSerializePartnerId()
    {
        return (SerializationLevel != SLForPartnerDto.None);
    }
    public bool ShouldSerializeBrand()
    {
        return (SerializationLevel == SLForPartnerDto.ViewForm);
    }
}

现在您只需在模型中设置SerializationLevel,例如:

var model = new PartnerDto();
model.SerializationLevel = SLForPartnerDto.ViewForm;

但我认为这不是最佳做法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-04
    • 2011-12-08
    • 2013-05-20
    • 1970-01-01
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多