我正在努力学习和理解C#Web API和MVC。 我理解简单的教程,其中有一个简单的Product或Person类作为Model,然后使CRUD Controller使用该模型。
但是我需要它更复杂一些,并且无法解决它。
我有以下型号:
public class PersonModel
{
public int Id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public DateTime LastUpdated { get; set; }
}
与我的数据库中的表相同。 LastUpdated列具有默认约束:(GETUTCDATE())
我对在PersonsController的POST方法中暴露LastUpdated不感兴趣:
public void PostPerson(PersonModel person)
{
// Upload person to database
}
因为那时可以在LastUpdated中插入无效的日期时间 - 或者我必须在我的业务逻辑中设置LastUpdated,但为什么不让我的SQL服务器执行此操作呢? 无论如何要在PostPerson中隐藏LastUpdated? 作为旁注,我希望能够在我的GetPerson方法中显示LastUpdated。 怎么可能?
答案 0 :(得分:2)
您可以创建自定义DTO作为此控制器上POST操作的视图模型。这将是另外方便的,因为您可能也不希望客户端提供Id
值(我假设)。像这样:
public class PersonDTO
{
public string Name { get; set; }
public string Title { get; set; }
}
这将是控制器操作的输入:
public void PostPerson(PersonDTO person)
{
// Upload person to database
}
然后在代码中,您将创建一个新的PersonModel
以添加到数据上下文中。类似的东西:
using (var db = new MyDataContext())
{
var newPerson = new PersonModel
{
Name = person.Name,
Title = person.Title
};
db.Persons.Add(newPerson);
db.SaveChanges();
}
(或者也许在DTO上创建一种转换方法,它返回模型的一个实例,充当一种工厂方法并将逻辑放在对象中而不是放在控制器中。)这样客户端就不会提供整个PersonModel
实例,只是描述该实例创建的对象。 GET操作仍然可以返回完整的PersonModel
。
在构建API时(例如,使用WebAPI),通常确实可以微调这样的输入和输出。这样的自定义DTO / ViewModel确实派上用场,虽然代价是通过为支持模型创建一个基本上转换层的代码略多。
我发现使用Swagger生成我的API文档时,我发现在确定需要调整API的位置时,我发现了一个特别方便的工具。通过生成的文档,我可能会注意到一些我不想暴露的内容。这是一个指标,我需要更多地自定义API端点,以便生成的文档更清晰。
答案 1 :(得分:2)
在类中实现属性时,可以为get和set访问器指定不同的访问修饰符。
无论您是自己实施属性还是使用自动属性,都是如此。
访问修饰符的不同组合包括:
获取/设置公开 - 客户端可以读/写属性值
获取/设置私有 - 客户无权访问该属性
公开,设置私密 - 属性是只读的
获取私密,设置为公开 - 属性为只写
// get/set both public
public string Name { get; set; }
// get/set both private
private string SecretName { get; set; }
// public get => read-only
public string CalcName { get; private set; }
// public set => write-only
public string WriteOnlyName { private get; set; }
答案 2 :(得分:0)
尝试在属性
上添加exclude属性[Exclude]
public DateTime LastUpdated {get; set(}