如何仅更新ASP.NET MVC中预先存在的模型的提供属性?

问题描述 投票:1回答:1

绑定到模型时,是否可以从数据库中提供模型(已填充其值),然后仅使用Web请求提供的内容更新该模型?

例如,如果我有这个模型:

public class Dog {
    public string Name {get; set;}
    public string Owner {get; set;}
}

并且可以从数据库填充该模型,以便:

Dog.Name == "Rolo"
Dog.Owner == "Matt"

我收到一个带有以下参数的Web请求:

?name=Max

那么我想要做的是提供已经填充的模型,只更新“Name”属性。

结果对象是:

Dog.Name == "Max"
Dog.Owner == "Matt"

Owner属性已经从数据库中填充,我不必复制值,任何其他映射等。

如何使用ASP.NET MVC实现这种情况?

asp.net forms model-view-controller model modelstate
1个回答
0
投票

更新狗的名字时,你想要将整只狗模型传递回控制器,其中包括DogId。这样,您可以在数据库中查询狗记录并相应地更新。以下示例使用实体框架

public class Dog
{
   public int DogId { get; set; }
   public string Name { get; set; }
   public string Owner { get; set; }
} 


[HttpPost]
public async Task<ActionResult> UpdateDog(Dog model)
{
      if(!ModelState.IsValid)
          return View(model);

      var dbDog = await db.Dogs.SingleAsync(x => x.DogId = model.DogId);

      // ! at the beginning is shorthand for if the condition is false
      // this is just a shorter way of doing the other example below 
      if(!string.IsNullOrEmpty(model.Name))
      {
          dbDog.Name = model.Name;
      }

      if(string.IsNullOrEmpty(model.Owner))
      {
          // model.Owner is null or an empty string so we don't want to 
          // update. We can leave this blank
      }
      else
      {
         // model.Owner has a value in it so we will update
         dbDog.Owner = model.Owner
      }

      // you can update more properties here if you wish, or ignore them
      // dbDog.Owner = model.Owner

      await _db.SaveChangesAsync();

      return View(model);
}

如果你不想传回整个模型,你可以传递你的model.Name,就像你正在做的那样你也想要包含model.DogId,这样你才能知道要更新的数据库中的哪条记录。

UpdateDog?名称=最大&dogId = 4

希望这可以帮助。

//基于注释的AutoMapper实现您需要创建一个映射配置文件,例如:

using AutoMapper;

public class DogProfile : Profile
{
    public DogProfile()
    {
       CreateMap<DogViewModel, Dog>()
          .ForMember(destination => destination.Owner, options => options.Condition(source => string.IsNullOrEmpty(source.Owner))
          .ForMember(destination => destination.Name, options => options.Condition(source => string.IsNullOrEmpty(source.Name));
    }
}

然后在您的UpdateDog ActionResult中,您可以尝试:

使用AutoMapper;

public class DogsController : Controller
{
    private readonly IMapper _mapper;

    public DogsController(IMapper _mapper)
    {
        _mapper = mapper
    }

    [HttpPost]
    public async Task<ActionResult> UpdateDog(DogViewModel viewModel)
    {
          if(!ModelState.IsValid)
              return View(viewModel);

          var dbDog = await db.Dogs.SingleAsync(x => x.DogId = viewModel.DogId);

          dbDog = _mapper.Map<Dog>(viewModel)

          await _db.SaveChangesAsync();

          return View(model);
    }
}

此外,不确定您是如何使用AutoMapper的,但如果您有一个,可能需要在Startup.cs文件中的下面的代码段中包含该行:

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
       services.AddMvc();

       // Add this line 
       services.AddAutoMapper(typeof(Startup).Assembly);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.