2012-08-24 295 views
3

我有两个问题需要在mvc项目中管理模型的最佳方法。ASP.NET MVC中的模型最佳实践

  • 我可以使用一个构造函数初始化我的模型(显然与其相关的逻辑)?
  • 为此,最好使用“构造函数的方式”,或者我应该在创建新模型实例后使用由控制器调用的扩展方法?

例如我有一个联系表单的模型。用户可以有三个角色:匿名,客户或供应商,他可以在每个州提交表格。我唯一想要的是,如果用户登录(如客户的角色或供应商的角色),我想要在他的数据文本框中预先加载。 为了做到这一点,我写了这个代码:

using System; 
using System.Web; 
using System.Web.Security; 
using DrOkR2.Bll.Managers; 

namespace DrOkR2.WebFront.Models 
{ 

    public class RequestModel 
    { 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string Phone { get; set; } 
     public string Email { get; set; } 
     public string Prov { get; set; } 
     public string Request { get; set; } 
     public bool UsageConditions { get; set; } 

     public RequestModel() 
     { 
      if (!HttpContext.Current.User.Identity.IsAuthenticated) return; 
      if (HttpContext.Current.User.IsInRole("Client")) 
      { 
       var guid = (Guid)Membership.GetUser().ProviderUserKey; 
       var manager = new ClientManager(); 
       var client = manager.GetClient(guid); 
       client.Email = Membership.GetUser().Email; 

       FirstName = client.FirstName; 
       LastName = client.LastName; 
       Email = client.Email; 
       Phone = client.Phone; 
       Prov = client.Prov; 
      } 
      else if (HttpContext.Current.User.IsInRole("Supplier")) 
      { 
       var guid = (Guid)Membership.GetUser().ProviderUserKey; 
       var manager = new SupplierManager(); 
       var supplier = manager.GetSupplier(guid); 
       supplier.Email = Membership.GetUser().Email; 

       FirstName = supplier.FirstName; 
       LastName = supplier.LastName; 
       Email = supplier.Email; 
       Phone = supplier.PrimaryPhone; 
       Prov = supplier.BusinessProv; 
      } 
     } 
    } 
} 

它完美,但我的问题是:我使用的最好的方法是什么?

+0

对我来说这是有道理的,因为你不会建立对象无效。 –

+0

我不能有无效的对象。我能做的最糟糕的事情是用户使用空的联系表单登录。问题是:“用户登录逻辑放在这里,或者我应该采用扩展方法?” – G10

+0

@ThiagoCustodio用'HttpContext'耦合你的视图模型对你有意义吗? – James

回答

5

不,您不应该依赖HttpContext或您的模型中的任何数据访问。你打开模型绑定的各种问题(更不用说紧密耦合了)。

在您的Controller或您的Controller使用的存储库中设置您的模型属性。

public ActionResult Contact(string id) 
{ 
    var client = _repository.GetClient(id); 
    var model = new RequestModel(){ /* set your properties from client */ }; 

    return View(model); 
} 
1

您的视图模型中有太多的业务逻辑是我喜欢的。您也将您的视图模型与您的HttpContext耦合,这不是一个好主意。

这种初始化属于控制器,例如,

public class RequestModel 
{ 
    public string FirstName { get; set; } 
    .... 
} 

public ActionResult ContactForm(...) 
{ 
    var contactModel = new RequestModel(); 
    if (User.IsInRole("Client")) 
    { 
     ... 
    } 
    else if (User.IsInRole("Supplier")) 
    { 
     ... 
    } 

    return View(contactModel); 
} 
+0

您的代码是我对此问题的预解决方案。但是我的表单不直接在视图中,我需要从很多不同的页面调用它。出于这个原因,我不想每次管理控制器逻辑。 – G10

+0

@ G10将逻辑移至业务逻辑类,并在您需要的每个控制器中重用它。 – jrummell

+0

@ G10部分视图仍然需要通过某个控制器来完成,因此您可以将这些代码封装在可重用的方法中,甚至可以引入基本控制器并将方法放在那里,以便您可以访问系统范围。 – James

0

我意识到这一点。为了完成这个线程,我把它放在这里。任何建议? 型号:

public class RequestModel 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Phone { get; set; } 
    public string Email { get; set; } 
    public string Prov { get; set; } 
    public string Request { get; set; } 
    public bool UsageConditions { get; set; } 

    public RequestModel(DrOkUser user) 
    { 

     if (user == null) return; 
     var type = user.GetType().Name;   //Client o Supplier 
     Email = user.Email; 
     if (type == "Client") 
     { 
      FirstName = ((Client)user).FirstName; 
      LastName = ((Client)user).LastName; 
      Phone = ((Client)user).Phone; 
      Prov = ((Client)user).Prov; 
     } 
     if (type == "Supplier") 
     { 
      FirstName = ((Supplier)user).FirstName; 
      LastName = ((Supplier)user).LastName; 
      Phone = ((Supplier)user).PrimaryPhone; 
      Prov = ((Supplier)user).BusinessProv; 
     } 
    } 
} 

控制器方法:

public class HomeController : BaseController 
{ 
public ActionResult Assistance() 
    { 
     var user = GetCurrentUser(); 
     var mdl = new RequestModel(user); 
     return View(mdl); 
    } 
} 

和BaseController:

public class BaseController : Controller 
{ 
public DrOkUser GetCurrentUser() 
    { 
     if (!HttpContext.User.Identity.IsAuthenticated) return null; 
     DrOkUser user = null; 
     var guid = (Guid)Membership.GetUser().ProviderUserKey; 
     if (HttpContext.User.IsInRole("Client")) 
      user = ClientManager.GetClient(guid); 
     if (HttpContext.User.IsInRole("Supplier")) 
      user = SupplierManager.GetSupplier(guid); 

     user.Email = Membership.GetUser().Email;    
     return user; 
    } 

}