简体   繁体   中英

Best practice : database class to object class in ASP.NET MVC for validation

In a project using NHibernate, I have this class :

public class AdminVAT : IAdminDecimal
{
    public virtual int Id { get; set; }
    public virtual int Code { get; set; }
    public virtual decimal Value { get; set; }
}

In ASP.NET MVC, I'd like some validation or/and some formatting on some fields. Then I tried this, using AutoMapper :

public class AdminVATDTO : AdminVAT
{
    [DisplayFormat(DataFormatString = "{0:n2}", ApplyFormatInEditMode = true)]
    public override decimal Value { get; set; }
}

In the Controller :

IList<AdminVAT> listAdminVAT = new AdministrationService(session).ListDecimal<AdminVAT>();
AutoMapper.Mapper.CreateMap<AdminVAT, AdminVATDTO>();
model.ListVAT = AutoMapper.Mapper.Map<IList<AdminVAT>, IList<AdminVATDTO>>(listAdminVAT);

In the HTML :

@Html.DropDownList("ddVAT", new SelectList(Model.ListVAT, "Id", "Value", Model.Estimation.AdminVAT))

The "Value" field is a decimal, when I display it on the page, I have 5 decimal, I need 2. The request here is simple but may be more complexe later on other field in other classes. In this case, that's not work, but work on other classes using the same way.

In a previous past someone (Darin) told me it was not a good way to use AutoMapper to do this ... the question is. Wich is thge best way to do this ?

Edit : and no code in the cshtml file

Thanks,

I am afraid that there are some serious issues with your models. It seems as if this AdminVATDTO is intended as a view model provided the fact that it has some formatting attributes on it but view models should never derive from models. That's not correct design.

Here's a correct design:

Domain model (not changing this as I suppose this already exists):

public class AdminVAT : IAdminDecimal
{
    public virtual int Id { get; set; }
    public virtual int Code { get; set; }
    public virtual decimal Value { get; set; }
}

View models:

public class AdminVATViewModel
{
    public int Id { get; set; }
    public string Value { get; set; }
}

public class MyViewModel
{
    public string SelectedVAT { get; set; }
    public IEnumerable<AdminVATViewModel> ListVAT { get; set; }
}

then define a mapping between AdminVAT and AdminVATViewModel :

Mapper
    .CreateMap<AdminVAT, AdminVATViewModel>()
    .ForMember(
        dest => dest.Value,
        opt => opt.MapFrom(src => src.Value.ToString("n2"))
    );

and then in your controller action:

public ActionResult Foo()
{
    IEnumerable<AdminVAT> listAdminVAT = ... fetch from repo
    var model = new MyViewModel
    {
        ListVAT = Mapper.Map<IEnumerable<AdminVAT>, IEnumerable<AdminVATViewModel>>(listAdminVAT)
    };
    return View(model);
}

and finally in the view:

@model MyViewModel

@Html.DropDownListFor(
    x => x.SelectedVAT, 
    new SelectList(Model.ListVAT, "Id", "Value")
)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM