Reputation: 15003
I am unsure how I can get this to work. I dont know how I can create [Display(Name = "XXXX")]
for my Customer
properties on this ViewModel:
public class CreateAccountViewModel
{
[Required]
public Customer Customer { get; set; }
[Required]
[Display(Name = "Username")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
public string ConfirmPassword { get; set; }
}
Should I create a ViewModel
for Customer
and reference that instead of the Customer
object? And then create Display()
for all of the properties?
If so, will the mapping work on submit?
I use this as follows (snippet):
<div class="form-group">
@Html.LabelFor(m => m.Customer.CompanyName, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Customer.CompanyName, new { @class = "form-control" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(m => m.Customer.CVR, new { @class = "col-md-2 control-label" })
<div class="col-md-10">
@Html.TextBoxFor(m => m.Customer.CVR, new { @class = "form-control" })
</div>
</div>
And the "CompanyName" I wish to change to something more nice like "Company name". :-)
Upvotes: 6
Views: 347
Reputation: 15003
Okay, I have done a different approach. I am not sure if this is any more elegant. Upon my research I came across AutoMapper and have done this. If anyone has a better solution to my problem, please let me know. :-)
public static class AutoMapperWebConfiguration
{
public static void Configure()
{
Mapper.Initialize(cfg =>
{
cfg.AddProfile(new CustomerMapper());
cfg.AddProfile(new CustomerAddressMapper());
});
}
}
public class CustomerMapper : Profile
{
protected override void Configure()
{
Mapper.CreateMap<CustomerViewModel, Customer>().ForMember(customer => customer.Address, expression => expression.MapFrom(viewModel => viewModel.Address));
}
}
public class CustomerAddressMapper : Profile
{
protected override void Configure()
{
Mapper.CreateMap<CustomerAddressViewModel, Address>();
}
}
Global.asax:
AutoMapperWebConfiguration.Configure();
My ViewModels
is then
public class CreateAccountViewModel
{
public CustomerViewModel Customer { get; set; }
[Required]
[Display(Name = "User name")]
public string UserName { get; set; }
[Required]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
public string ConfirmPassword { get; set; }
}
public class CustomerViewModel
{
[Required]
[Display(Name = "Company Name")]
public String CompanyName { get; set; }
[Required]
[Display(Name = "CVR")]
public String CVR { get; set; }
[Required]
[Display(Name = "First name")]
public String FirstName { get; set; }
[Required]
[Display(Name = "Last name")]
public String LastName { get; set; }
[Required]
[Display(Name = "Phone (mobile)")]
public String Phone { get; set; }
[Required]
[Display(Name = "E-mail")]
public String Email { get; set; }
public CustomerAddressViewModel Address { get; set; }
}
public class CustomerAddressViewModel
{
[Required]
[Display(Name = "Streey")]
public String Street { get; set; }
[Required]
[Display(Name = "Postal code")]
public String PostalCode { get; set; }
[Required]
[Display(Name = "City")]
public String City { get; set; }
[Required]
[Display(Name = "Country")]
public String Country { get; set; }
}
And finally my action
, which takes the CreateAccountViewModel
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(CreateAccountViewModel model)
{
if (ModelState.IsValid) {
Customer customer = Mapper.Map<Customer>(model.Customer);
var user = new ApplicationUser() { UserName = model.UserName, Customer = customer };
var result = UserManager.Create(user, model.Password);
if (result.Succeeded)
{
await SignInAsync(user, false);
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
Upvotes: 0
Reputation: 3775
Yo can use this Structure:
[DisplayName("YourName")]
public string UserName { get; set; }
and in your view:
@Html.DisplayNameFor(m => m.Customer.CompanyName, new { @class = "col-md-2 control-label" }))
Upvotes: 0
Reputation: 7458
As usual if I need to display some complex model with such sub objects - I create another model for this object, specify attributes in new model. And then specify this model instead of Customer property.
@Html.LabelFor(m => m.Customer.CompanyName, new { @class = "col-md-2 control-label" })
Should work fine for sub models, if it has Display attribute.
Another way is to specify these attributes under your domain classes, but as for me - i don't like to dirty domain objects with UI attributes
Upvotes: 4