将带参数的视图模型传递给POST方法

时间:2016-01-25 21:42:28

标签: asp.net-mvc constructor dependency-injection asp.net-mvc-5

我想用DI(纯3层应用程序)构建我的应用程序

一个ViewModel类在contructor中填充其中的一些字段:

public class RegisterAsSmartphonePhotographerViewModel
{
    public RegisterAsSmartphonePhotographerViewModel(PixlocateBusinessLogic.IStaticListRepository repository)
    {
        Country = new ListViewModel<Pair<string, int>>();
        State = new ListViewModel<Pair<string, int>>();

        PixlocateBusinessLogic.StaticListService service = new PixlocateBusinessLogic.StaticListService(repository);
        var countries = service.CountryList();
        var states = service.StateList();

        foreach (var item in countries)
        {
            Country.List.Add(new System.Web.Mvc.SelectListItem() { Text = item.CountryName, Value = item.CountryID.ToString() });
        }

        foreach (var item in states)
        {
            State.List.Add(new System.Web.Mvc.SelectListItem() { Text = item.StateName, Value = item.StateID.ToString() });
        }
    }

    [Required]
    public string Username { get; set; }

    [Required(ErrorMessage ="Country is required")]
    public int CountryID { get; set; }
    public ListViewModel<Pair<string, int>> Country { get; set; }

    [Required(ErrorMessage = "State is required")]
    public int StateID { get; set; }
    public ListViewModel<Pair<string, int>> State { get; set; }
}

和我的控制员:

    [AllowAnonymous]
    public ActionResult RegisterAsSmartphonePhotographer()
    {
        ViewModels.RegisterAsSmartphonePhotographerViewModel model = new ViewModels.RegisterAsSmartphonePhotographerViewModel(_staticListRepository);
        return View(model);
    }

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> RegisterAsSmartphonePhotographer(ViewModels.RegisterAsSmartphonePhotographerViewModel model)
    {
        if (ModelState.IsValid)
        {
             // some actions
        }
        return View(model);
    }

当然,我收到一个错误:

  

没有为此对象定义无参数构造函数。

当我将表单发布到服务器时。 当然,我无法从RegisterAsSmartphonePhotographerViewModel构造函数中删除参数。 怎么说'#34;传递参数&#34; POST方法?

1 个答案:

答案 0 :(得分:2)

问题是,当您发布表单数据时,DefaultModelBinder将尝试创建视图模型的对象,并尝试将发布的表单数据映射到视图模型对象的属性。由于您的视图模型没有参数较少的构造函数,因此在尝试创建视图模型的对象时失败。

您需要在视图模型中创建默认的无参数构造函数。

public class RegisterAsSmartphonePhotographerViewModel
{
    public RegisterAsSmartphonePhotographerViewModel(){}
    public RegisterAsSmartphonePhotographerViewModel(IStaticListRepository repository)
    {
      // Existing code   
    }
 // Existing code   
}

同样恕我直言,在视图模型类中混合数据访问代码并不是一个好主意。视图模型应该是精简的POCO类,用于在视图和操作方法之间传输数据。如果您尝试在其中混合数据访问代码,那么您就会紧密耦合并违反单一责任原则。

您应该从视图模型中更改数据/ Web服务调用并将其移动到另一层(您的操作方法/ BL等)。

简单样本。

public class CustomerController : Controller
{
  IStaticListRepository repository;
  public CustomerController(IStaticListRepository repository)
  {
    this.repository= repository;
  }
  public ActionResult Create()
  {
    var vm = new RegisterAsSmartphonePhotographerViewModel();
    // using the repository object, populate the vm properties
    return View(vm);
  }
}