...再次
我正在使用EF5 App进行MVC。我有一个用户实体,EF绑定数据库中的Users表...看起来像这样。
ClientInfo
我有一个模型类,我在创建视图中使用它....
public partial class Users
{
public long User_id { get; set; }
[Required]
[StringLength(30, ErrorMessage = "LastName cannot be longer than 30 characters.")]
public string LastName { get; set; }
[Required]
[StringLength(30, ErrorMessage = "Name cannot be longer than 30 characters.")]
public string Name { get; set; }
public int ProcessState_id { get; set; }
public string Sex { get; set; }
[Required,Range(1, int.MaxValue, ErrorMessage = "El País es Obligatorio")]
public int Country_id { get; set; }
[Required]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string Email { get; set; }
public System.DateTime CreationDate { get; set; }
public Nullable<System.DateTime> UpDateTime { get; set; }
[RegularExpression(@"^.{5,}$", ErrorMessage = "Minimum 3 characters required")]
[Required]
[StringLength(9, MinimumLength = 3, ErrorMessage = "Password cannot be longer than 9 characters.")]
public string Password { get; set; }
public string Url { get; set; }
public byte[] Picture { get; set; }
public string CodArea { get; set; }
public string PhoneNumber { get; set; }
public virtual Countries Countries { get; set; }
public virtual ProcessStates ProcessStates { get; set; }
public virtual States States { get; set; }
[NotMapped] // Does not effect with your database
[RegularExpression(@"^.{5,}$", ErrorMessage = "Minimum 3 characters required")]
[StringLength(9, MinimumLength = 3, ErrorMessage = "Confirm Password cannot be longer than 9 characters.")]
[Compare("Password")]
public virtual string ConfirmPassword { get; set; }
}
Controller中的“我的创建方法”获取public class UserViewModel
{
public Users user { get; set; }
public IList<SelectListItem> AvailableCountries { get; set; }
}
实例...
我的创建方法看起来像这样。
UserViewModel
到目前为止一切顺利。
对于我的编辑视图,我需要更少的User类属性,所以我有一个新类,其中包含我需要的属性。此类称为public async Task<ActionResult> Create(UserViewModel model, System.Web.HttpPostedFileBase image = null)
{
try
{
if (ModelState.IsValid)
{
model.user.ProcessState_id = Security.WAITING;
model.user.Rol_id = Security.ROL_PUBLIC;
model.user.CreationDate = DateTime.Now;
model.user.IP = Request.UserHostAddress;
model.user.Url = UserValidation.EncriptacionURL(model.user.Email);
if (image != null)
{
// product.ImageMimeType = image.ContentType;
model.user.Picture= new byte[image.ContentLength];
image.InputStream.Read(model.user.Picture, 0, image.ContentLength);
}
_db.Users.Add(model.user);
_db.SaveChanges();
return RedirectToAction("Create");
}
model.AvailableCountries = GetCountries();
return View(model);
}
catch (RetryLimitExceededException /* dex */)
{
}
return View(model);
}
。
UserEditView
我还为编辑视图创建了一个新模型,名为public class UserEditView
{
public long User_id { get; set; }
[Required]
[StringLength(30, ErrorMessage = "LastName cannot be longer than 30 characters.")]
public string LastName { get; set; }
[Required]
[StringLength(30, ErrorMessage = "Name cannot be longer than 30 characters.")]
public string Name { get; set; }
[Required, Range(1, int.MaxValue, ErrorMessage = "El País es Obligatorio")]
public int Country_id { get; set; }
[Required]
[EmailAddress(ErrorMessage = "Invalid Email Address")]
public string Email { get; set; }
public Nullable<System.DateTime> UpDateTime { get; set; }
public byte[] Picture { get; set; }
public string CodArea { get; set; }
public string PhoneNumber { get; set; }
public virtual Countries Countries { get; set; }
}
,看起来像这样。
UserEditViewModel
在我的编辑方法中,我使用public class UserEditViewModel
{
public UserEditView user { get; set; }
public IList<SelectListItem> AvailableCountries { get; set; }
}
将Mapper
实体与User
绑定
UserEditView
当我想更新用户表时出现问题。
Edit方法获取public ViewResult Edit(int User_id=3)
{
Users users = _db.Users
.FirstOrDefault(p => p.User_id == User_id);
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Users, UserEditView>();
});
IMapper mapper = config.CreateMapper();
UserEditView userEditView = mapper.Map<Users, UserEditView>(users);
var model = new UserEditViewModel
{
user = userEditView,
AvailableCountries = GetCountries(),
};
return View(model);
}
个实例。
UserEditViewModel
public async Task<ActionResult> Edit(UserEditViewModel model, System.Web.HttpPostedFileBase image = null)
{
try
{
if (ModelState.IsValid)
{}
}
}
的实例为UserEditViewModel
,但我需要一个UserEditView
的实例,以便EF更新用户表。
我需要再次映射吗? 我如何获得用户实例?
我添加以下类
Users
我添加了我的Global.asax
public static class AutoMapperBootStrapper
{
public static void BootStrap()
{
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Users, UserEditView>();
cfg.CreateMap<UserEditView, Users>();
});
IMapper mapper = config.CreateMapper();
}
然后在控制器中...我做
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AutoMapperBootStrapper.BootStrap();
AreaRegistration.RegisterAllAreas();
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
但是 public ViewResult Edit(int User_id=3)
{
Users users = _db.Users.FirstOrDefault(p => p.User_id == User_id);
UserEditView userEditView = Mapper.Map<Users, UserEditView>(users);
}
有错误......它说没有实例化Mapper。
问题是因为我定义了多个Mapper。如果我只定义一个,它工作得很好......
答案 0 :(得分:2)
我需要再次映射吗?我如何获得用户实例?
您可以使用id从数据库中获取User模型,然后从视图模型中映射您需要更新的属性:
[HttpPost]
public ActionResult Edit(UserEditViewModel model, HttpPostedFileBase image = null)
{
if (!ModelState.IsValid)
{
// Validation failed => redisplay the Edit form so that the
// user can correct the errors
return View(model);
}
var user = _db.Users.FirstOrDefault(p => p.User_id == model.user.User_id);
if (user == null)
{
// no user with the specified id has been found in the database =>
// there's nothing to update
return NotFound();
}
// This will map only the properties of the user object that
// are part of the view model
Mapper.Map<Users, UserEditView>(model.user, user);
// at this stage you could manually update some properties that
// have not been mapped such as the uploaded image
// finally persist the changes to the database
_db.SaveChanges();
// redirect to some other action to show the updated users
return RedirectToAction("users");
}
您在问题中显示的代码:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Users, UserEditView>();
});
IMapper mapper = config.CreateMapper();
这绝对是 NOT 您应该在控制器操作中执行的操作。 AutoMapper映射应该每个应用程序生命周期只配置一次,理想情况下应用程序启动时,即对于Global.asax中Application_Start
的Web应用程序。在控制器操作中,您应该只使用已配置的映射。我强烈建议您浏览AutoMapper的文档,以便更好地了解如何使用此框架。
我在哪里配置AutoMapper?
如果您正在使用静态Mapper方法,则只应进行配置 每个AppDomain发生一次。这意味着最好的地方 配置代码在应用程序启动时,例如Global.asax ASP.NET应用程序的文件。通常,配置 bootstrapper类在它自己的类中,而这个bootstrapper类是 从启动方法调用。 bootstrapper类应该调用 Mapper.Initialize配置类型映射。