在C#Web API中隐藏控制器中的模型类成员?

时间:2015-07-31 13:35:08

标签: c# asp.net-mvc asp.net-web-api

我正在努力学习和理解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。 怎么可能?

3 个答案:

答案 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(}