ASP.NET MVC 中的 AutoMapper 更新操作

2023-11-30

对于某些人来说,这可能非常简单,但是我有点困惑,找不到合适的例子。假设我正在使用视图模型,并且我的 POST 操作在该视图模型中进行。通常我会按照以下方式做一些事情:

    [HttpPost]
    public ActionResult Update(UserViewModel uvm)
    {
        User user = Mapper.Map<UserViewModel, User>(uvm);
        _repository.Update(user);

        return RedirectToAction("Index");
    }

尽管这不是完整的图景。映射可以正常工作,但是如果我只是更新已映射的内容,那么它将删除数据库中有价值的数据,因为当然在这种情况下我不会更新密码或其他详细信息。

我的存储库看起来像这样:

    public void Update(User user)
    {
        User u = Session.QueryOver<User>().Where(x => x.UserName == user.UserName).SingleOrDefault();

        if (u == null)
            throw new Exception("User not found");

        u.Forename = user.Forename;
        u.Surname = user.Surname;
        u.EmailAddress = user.EmailAddress;
    }

[我正在使用 NHibernate,因此一旦会话关闭(请求完成后),它会自动为我将对象保存回数据库。]

所以我的问题是,在我的存储库中,我应该加载“用户”实体,然后更新我想要的值,然后将其保存回来,还是有其他方法可以做到这一点?我问的原因是因为它看起来有点......“手动”如果你明白我的意思吗?也许这是正确的,但我只是想看看在这方面更有经验的人的意见。

Cheers


我使用以下方法:

[HttpPost]
public ActionResult Update(UserViewModel uvm)
{
    User user = _userRepository.FindById(uvm.Id);

    user.Forename = uvm.Forename;
    user.Surname = uvm.Surname;
    user.EmailAddress = uvm.EmailAddress;

    _userRepository.Update(user);

    return RedirectToAction("Index");
}

UPDATE:

为了解决有关的评论AutoMapper操作方法如下:

我们以以下类为例:

public class UserViewModel
{
    public string Forename { get; set; }
    public string Surname { get; set; }
    public string EmailAddress { get; set; }
}

public class User
{
    public string Forename { get; set; }
    public string Surname { get; set; }
    public string EmailAddress { get; set; }

    public string Password { get; set; }
}

我们不想在 UI 中修改用户密码。所以我们向AutoMapper表达我们的意图:

Mapper
    .CreateMap<UserViewModel, User>()
    .ForMember(dest => dest.Password, opt => opt.Ignore());

进而:

[HttpPost]
public ActionResult Update(UserViewModel uvm)
{
    // Fetch the original model we would like to update
    User user = _userRepository.FindById(uvm.Id);

    Mapper.Map(uvm, user);
    // At this stage the user model will have its 
    // Forename, Surname and EmailAddress properties 
    // updated from the view model and its Password property
    // will remain the one we got from the repository

    _userRepository.Update(user);

    return RedirectToAction("Index");
}

更新2:

为了解决评论中有关配置 AutoMapper 的问题,我通常使用配置文件:

public class UsersProfile : Profile
{
    protected override void Configure()
    {
        Mapper
            .CreateMap<UserViewModel, User>()
            .ForMember(dest => dest.Password, opt => opt.Ignore());    

        Mapper
            .CreateMap<User, UserViewModel>();
    }
}

然后有一个注册所有映射器的注册表类:

public class MappingsRegistry
{
    public static void Configure()
    {
        Mapper.AddProfile(new UsersProfile());
        Mapper.AddProfile(new SomeOtherProfile());
        ...
    }
}

这被称为Application_Start:

MappingsRegistry.Configure();

最后我的控制器有一个对映射引擎的引用:

public class UsersController : Controller
{
    private readonly IUsersRepository _repository;
    private readonly IMappingEngine _mappingEngine;
    public ContratsFCController(IUsersRepository repository, IMappingEngine mapperEngine)
    { 
        _repository = repository;
        _mapperEngine = mapperEngine;
    }

    [AutoMap(typeof(User), typeof(UserViewModel))]
    public ActionResult Update(int id)
    {
        var user = _repository.FindById(id);
        return View(user);
    }

    [HttpPost]
    public ActionResult Update(UserViewModel uvm)
    {
        if (!ModelState.IsValid)
        {
            return View(uvm);
        }
        var user = _repository.FindById(uvm.Id);
        _mapperEngine.Map(uvm, user);
        _repository.Update(user);
        return RedirectToAction("Index");
    }
}

现在剩下的就是指示您的 DI 框架传递Mapper.Engine构造函数的属性和在单元测试中显然用适当的模拟替换它们。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP.NET MVC 中的 AutoMapper 更新操作 的相关文章

随机推荐

  • 为什么“fopen”返回 NULL 指针?

    我正在用 C 编程语言开发一个简单的文件拆分 合并程序 问题是 由于某种原因fopen返回 NULL 正因为如此 我的程序崩溃了fwrite陈述 我该如何解决 这是 C 文件 int SplitFile char filename char
  • scikit-learn 是否在我的 GPU 上运行?

    这个问题与scikit learn 会使用 GPU 吗 但我认为没有提供相同的答案 我正在针对 Nvidia GPU 执行 scikit learn 算法 没有错误 因此假设 scikit 正在底层硬件上运行 由于 scikit learn
  • 嵌套li - 单击子级时,触发父级单击事件[重复]

    这个问题在这里已经有答案了 我有一个嵌套的李 li class innerMenuLi a href span MainLi span a ul class mainMenu li a href class active span main
  • 使用 WCF 生成 JSON 数组

    我正在开发一个 WCF Web 服务 它返回以下内容 allFormsResult FormId 1 FormName Formulario 1 FormId 2 FormName Formulario 2 FormId 3 FormNam
  • 检查 wifi 连接的质量?

    我遇到这样的情况 当我关闭 4G 并连接到某些 WiFi 接入点但无法发送或接收数据时 用于检查网络连接的标志被设置为 true 如下所示 NetworkInfo ni context getActiveNetworkInfo boolea
  • 如何在 SQL Server 2014 中启用/安装全文搜索

    这个问题可能有一个非常简单的答案 但我不知道如何在 SQL Server 2014 中启用全文搜索 过去几个小时我一直在网上搜索 一些关于 SQL Server 2012 的帖子说它在安装过程中的功能中 但我去了那里 但没有启用它的选项 自
  • 从文本区域读取时不保留换行符

    我的 java web 应用程序从文本区域获取内容 并通过电子邮件发送相同的内容 我面临的问题是 使用以下命令读取相同内容时 文本区域消息中的换行符不会保留 request getParameter message 有什么线索可以解决吗 T
  • 如何以非交互式方式为 gcloud CLI 传递数据库密码?

    我正在尝试以非交互式方式将密码传递给 gcloud sql connect 命令 我想要实现的不是要求输入密码 而是以某种方式将其传递到命令中 不确定是否可能 基于文档 但另一方面 它对于自动化任务非常有用 我坚信有一种方法可以做到这一点
  • 无法创建 externalDataReference 临时文件

    我在我的 iOS 项目中使用 Core Data 我通过以下方式使用多个上下文 我有一个persisent store context它在私有队列上运行并将更改存储到持久存储中 我有一个main queue context那是的孩子pers
  • Android:Eclipse MAT 似乎没有显示我的应用程序的所有对象

    我通过插入语句创建了一个 hprof 文件Debug dumpHprofData sdcard myapp hprof 在我的应用程序的代码中 然后 我通过 hprof conv 运行 hprof 文件 并在 Eclipse 中打开转换后的
  • 子类中的狭义属性类型

    今天我遇到了一个奇怪的行为 我没想到 Objective C 编译器会允许 在 UITableViewCell 中 有一个名为 imageView 的 UIImageView 类型的属性 我对 UITableViewCell 进行了子类化
  • iDangero.us Swiper 多个实例

    我正在尝试添加多个刷卡器 http www idangero us swiper 在我的网站上 我想添加滑动器动态 因此我为每个滑动器使用相同的类 每个滑动器看起来像这样 div class swiper container div cla
  • JavaFX 任务一旦取消或完成一次就不会重新运行

    我正在做一个基本的 Java FX 任务练习 线程上的计数范围为 1 到 150 当前值显示在标签上并更新进度条 有一个按钮可以启动任务 取消任务以及查看任务的取消状态 让我困惑的是为什么我在取消线程一次后无法重新运行任务 如果我让任务完成
  • 对调用另一个方法的方法进行单元测试

    对调用多个方法的方法进行单元测试的最佳方法是什么 例如 modify string value if value Length gt 5 replaceit value else changeit value 该伪代码有一个修改方法 当前
  • Solr 4 中可以更新 uniqueKey 吗?

    我的 uniqueKey 定义为
  • 使用 Gradle - 在 META-INF/spring.factories 中找不到自动配置类

    尝试在 Spring Boot 上使用 IntelliJ 中的 gradle 中的 jar 函数部署我构建的 jar 它使用 bootrun 从我的 IDE 本地运行良好 但没有将 jar 放在 Linux 服务器上 服务器上的完整错误是
  • Sklearn Pipeline:自动错过一项功能

    我创建了一个自定义分类器 虚拟分类器 下面是定义 我还添加了一些打印语句和全局变量来捕获值 class FeaturePassThroughClassifier ClassifierMixin def init self pass def
  • 以编程方式触发来自 Google Play 的应用更新

    在 Google Play 开发者控制台中提交应用程序更新并且所有用户都可以看到该应用程序后 任何设备需要多长时间才能选择更新 假设全天都有有效的互联网 WiFi 连接 并且此应用程序已开启自动更新 我能否以编程方式向 Google Pla
  • React 正在将旧状态发送给其父级

    当我将子组件的状态发送到其父组件时 React 会将旧状态发送到父组件 我想在每次单击正常工作并调用函数handleClick 的列表项时发送更新的状态 但当我打电话时sendStateToParent 它正在过去旧的状态 假设我点击了IT
  • ASP.NET MVC 中的 AutoMapper 更新操作

    对于某些人来说 这可能非常简单 但是我有点困惑 找不到合适的例子 假设我正在使用视图模型 并且我的 POST 操作在该视图模型中进行 通常我会按照以下方式做一些事情 HttpPost public ActionResult Update U