Web API中的更新方法:如何知道要更新的字段?

时间:2017-09-21 13:23:49

标签: c# asp.net api asp.net-web-api design-patterns

我有一个典型的Web API,带有几个PUT / UPDATE端点。这些端点只是调用底层服务,并进行更新。

服务层具有典型的签名,例如Object Update(Object object)。然后我做的是基本上运行以下伪代码:

var dbobject = _db.Object.Find(object.Id);    
dbobject.Field1 = object.Field1;
dbobject.Field2 = object.Field2;
// continue for all fields

_db.SaveChanges();

return GetObjectById(object.Id);

然而,这对我来说是一个挑战。

假设我们有API的消费者。此消费者调用我的PUT端点(/api/Object/{id}),有效负载是更新的对象。

但是,假设我们放置的对象不知道示例Field4,那么在运行更新后此值将为NULL

我的问题是:

  • 您对有效负载不包含的所有字段做了什么? 如何处理不将值设置为NULL的期望值 之后是NULL吗?

1 个答案:

答案 0 :(得分:1)

作为可能的方法之一,可以使用NotifyPropertyChangedautomapper的混合

理念是在DTO对象中存储确切设置的字段,并保持填充默认值。并在映射中使用收集的数据。

例如DTO对象将是

public class Dto
{
    private List<string> Changed = new List<string>();
    public bool IsChanged(string field) => Changed.Contains(field);

    private int _age;
    private string _name;

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            // IMPORTANT: field name should fit main object field name
            Changed.Add("Name"); 
        }
    }

    public int Age
    {
        get { return _age; }
        set
        {
            _age = value;
            Changed.Add("Age");
        }
    }
}

我使用Next类进行测试

public class Human
{
    public string Name { get; set; } = "DEFAULT";
    public int Age { get; set; } = -1;
}

和automapper配置看起来像

cfg.CreateMap<Dto, Human>()
       .ForAllMembers(s=> s.Condition(d=>d.IsChanged(s.DestinationMember.Name)));

这是一个简单的例子。但它仍然不能阻止将函数IsChanged用于某些复杂/特定的逻辑,不仅使用字符串Expressions / MethodInfo,还可以添加自定义属性并在automapper配置(DestinationMemberMethodInfo

追加

您可以从控制器中的Request.Properties获取有关已传递字段的信息,而不是复杂的DTO对象(类型为ms_querynamevaluepairs的键Dictionary<string, string>)。