绑定到模型时,是否可以从数据库中提供模型(已填充其值),然后仅使用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实现这种情况?
更新狗的名字时,你想要将整只狗模型传递回控制器,其中包括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);
}
}