繁体   English   中英

关于将内容放在ASP.NET MVC中的位置有些困惑

[英]A little confused about where to put things in ASP.NET MVC

我正在开发我的第一个ASP.NET MVC应用程序,但在创建/更新某些数据时遇到了一些困惑。

我有一个数据库表User ,一个LinqToSql生成的部分类User和我自己的自定义部分类User

我在我的User版本上使用[Bind(Exclude = "Id, InsertDateTime, UpdateDateTime")] ,因为我不希望用户编辑这些字段。

我也有一个PhoneNumber领域,这一点希望用户编辑,但它需要改造。 我将其作为10个数字存储在数据库中,但是当我通过视图将其显示给用户时,我将其转换为视图中的可读电话号码,如下所示:

string.Format("{0:(###) ###-####}", Convert.ToInt64(Model.User.PhoneNumber)).

问题是,当用户单击“保存”时,电话号码将始终采用错误的格式。 在某个地方,我需要去除所有非数字字符(括号,破折号,斜杠和空格)。

问题

对于下面列出的每个字段,如何处理创建和编辑操作?

  1. Id我相信这是由SQL-Server自动处理的,因为我将所有Id字段都设置为IDENTITY (1, 1) 我没有进行广泛的测试,但这似乎“正常”。 请确认。

  2. InsertDateTime我希望将其设置为DateTime.Now 用于Create动作,而不用于Edit动作。 那么,设置此值的合适位置在哪里:User,UserController,UserFormViewModel或其他?

  3. UpdateDateTime对于“创建”和“编辑”操作,我都希望将其设置为DateTime.Now ,但是同样,我应该将执行此分配的代码放在哪里?

  4. PhoneNumber -与上述三个领域,这是一个由用户可编辑的,但它需要得到来自转化(888) 123-45678881234567可以发生更新之前。 这里有几个问题: (1)进行此转换的适当位置在哪里? 我在视图中将电话号码转换为“用户可读”格式,应在哪里将其转换回“数据库存储”格式? (2)我应该在[Bind(Exclude...)]属性中添加PhoneNumber吗?

更新资料

从到目前为止的答案中,我认为至少要为自己澄清一些事情。

首先,这是User数据中发生东西的位置的列表:

  1. 数据库中的User表-处理ID分配。 可以提供InsertDateTime和UpdateDateTime的默认值。

  2. User类-使用GetRuleViolations()方法处理验证。

  3. UserRepository类-抽象出数据持久性功能(获取,获取全部,添加,删除和保存)。

  4. UserController类-处理用户请求和发布尝试(索引,详细信息,编辑,发布的编辑,创建,发布的创建和删除)。

  5. UserFormViewModel类-提供要查看的强类型数据( User对象以及下拉菜单的后备数据)。

  6. Views/User/Create.aspxViews/User/Edit.aspx通过将静态数据与动态数据(存储在视图模型中)组合在一起,生成HTML以向用户显示UI。

我当前的想法是,从概念上讲,设置IdUpdateDateTimeInsertDateTime的责任在于模型。 该数据库肯定负责设置插入时的Id ,但我仍然不清楚应在何处设置日期时间字段。 似乎有两种选择:存储库(由@Aaronaught建议)或User类(已处理验证)。

至于在##########和(###)###-####之间转换PhoneNumber的问题,从概念上讲,这似乎更像是“查看”功能。 我喜欢@Aaronaught的想法,即拥有一个专用的PhoneNumberConverter类,并且我可能会同意,但仍然存在一个问题,即谁在该类上调用方法。 为此,我倾向于使用UserFormViewModel类。

这使我想到了两个后续问题...

后续问题

  1. 应该在UserRepository类还是User类中分配UpdateDateTimeInsertDateTime字段?

  2. UserFormViewModel调用电话号码转换方法(在PhoneNumberConverter类上)是否有意义?

这是我的答案:

1-是的,您是对的,使用SQL Server标识规范列“自动增量列”即可完成

2-您可以在数据库中将此字段的默认值设置为getdate() sql函数,以便它首次使用该值并将其插入数据库,并使用服务器datetime值。

3-这也可以与默认值相同,但是在功能中您将数据保存在ex中。 在您调用的行提交更改时,将此值设置为Datetime.Now。

4-第一部分,我认为适当的地方应该在[Post]方法版本上,我不认为您应该排除它。

通常,您将拥有一个业务逻辑层,MVC将该层称为存储库-介于控制器和DAL之间。 这通常是处理时间戳和数据转换的理想场所。

public class UserRepository : IUserRepository
{
    private IDatabase db;

    public UserRepository(IDatabase db)
    {
        if (db == null)
        {
            throw new ArgumentNullException("db");
        }
        this.db = db;
    }

    public void SaveUser(User user)
    {
        int userID = user.ID;
        DateTime createDate = user.CreatedOn;
        DateTime updateDate = DateTime.Now;
        long phoneNumber = PhoneNumberConverter.Parse(user.PhoneNumber);
        using (TransactionScope tsc = new TransactionScope())
        {
            if (user.ID == 0)
            {
                createDate = updateDate;
                userID = db.InsertUser(user.Name, phoneNumber, createDate,
                    updateDate);
            }
            else
            {
                db.UpdateUser(user.ID, user.Name, phoneNumber, updateDate);
            }
            tsc.Complete();
        }
        user.ID = userID;
        user.CreatedOn = createDate;
        user.LastModified = updateDate;
    }
}

请注意,我在这里做了很多“假设”,例如使用TransactionScope和某种称为IDatabase的瘦CRUD层类型。 这些并不重要 ,它们只是用来说明工作流程:

  1. 具有处理“业务逻辑”的某种类型的“存储库”类-即在用户单击“保存”与它实际进入数据库之间发生的所有事情。 您可以实现单独的AddUpdate方法,也可以实现单个Save方法。

  2. 在“ Add / Update / Save方法中进行所需的任何数据转换。 这并不能代替在UI级别进行验证的需要; 我在上面引用PhoneNumberConverter的原因是,您可能希望使它同时暴露ValidateConvert方法,以便您的存储库和UI都可以依赖相同的中央验证/转换逻辑。 当然,在MVC 2.0中,您可以为此使用数据注释-数据DataType枚举中实际上有一个PhoneNumber成员。

  3. 您的Save方法(或AddUpdate方法)采用一个未附加的实体并将其保存到数据库中。 此方法检查ID,然后根据该ID选择是插入还是更新。 无论哪种方式,它都会在数据库事务成功之后更新传递给它的原始User对象。 这也应该回答您的问题#1-如果您的数据库中有一个IDENTITY列,则您的数据库负责生成ID。 您不会在应用程序中生成它们。

另一种方法是Save方法返回一个全新的User实例,该实例从实际存储在数据库中的任何内容初始化。 换句话说,它在INSERTUPDATE之后INSERT SELECT 尽管这确实会更加可靠,但是在性能方面存在重大折衷。

从技术上讲,存储库是模型的一部分,它应该从根本上回答“ where”问题,尽管我倾向于将其视为一个单独的层。

我不确定这能否很好地回答您的问题-回答这样的“设计”问题有点棘手-但我发现该设计在大多数情况下都能很好地工作,它遵循DRY原理并且易于维护。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM