【问题标题】:Errror when passing values from multiple DropDownLists to controller through ViewModel通过 ViewModel 将值从多个下拉列表传递到控制器时出错
【发布时间】:2013-06-25 23:34:34
【问题描述】:

我正在尝试创建由 SelectList 创建的表单 DropDownLists,该表单是根据学生用户关联的不同 [银行] 帐户生成的。到目前为止,我已经能够为所有帐户成功创建两个下拉列表,但是当我提交表单时出现错误:No parameterless constructor defined for this object.

我不太确定这个错误的原因是什么,我认为我设置了控制器并正确查看以处理不同的值,但我不确定我传入的 ViewModel 是否正确。

账户模型(用于转账ActionResult的银行账户)

    public class Account
{
    [Key]
    [Editable(false)]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public virtual int AccountID { get; set; }

    [Required(ErrorMessage = "Required")]
    [MaxLength(50)]
    public virtual string AccountName { get; set; }

    [DisplayFormat(DataFormatString = "{0:c}")]
    [Column(TypeName = "money")]
    public virtual decimal AccountTotal { get; set; }

    [ForeignKey("Student")]
    public virtual int StudentID { get; set; }

    public virtual Student Student { get; set; }

}

TransferFundsViewModel(这是构建强类型视图的类,我正在尝试将其传递给我的控制器。)

    public class TransferFundsViewModel
{
    public SelectList ListOfSourceAccounts { get; set; }
    public int SelectedSourceAccountId { get; set; }

    public SelectList ListOfDestinationAccounts { get; set; }
    public int SelectedDestinationAccountId { get; set; }

    [Required]
    [DisplayFormat(DataFormatString = "{0:c}")]
    public decimal TransferAmount { get; set; }
}

控制器内部的 TransferFunds 方法

[HttpGet]
    public ActionResult TransferFunds()
    {
        //Get logged in user
        var studentProfile = db.UserProfiles.Local.SingleOrDefault(u => u.UserName == User.Identity.Name)
            ?? db.UserProfiles.SingleOrDefault(u => u.UserName == User.Identity.Name);
        //Get student account associated with logged in user
        var student = db.Students.Find(studentProfile.UserId);
        //Get accounts associated with student account
        var accounts = db.Accounts.Where(x => x.StudentID == student.UserId);

        var selectionList = new SelectList(accounts, "AccountID", "AccountName");

        var vm = new TransferFundsViewModel { ListOfSourceAccounts = selectionList, ListOfDestinationAccounts = selectionList };

        return View(vm);
    }

    [HttpPost]
    public ActionResult TransferFunds(TransferFundsViewModel viewModel)
    {
        if (ModelState.IsValid)
        {
            try
            {
                AccountManager manager = new AccountManager();
                Account srcAccount = db.Accounts.Find(viewModel.SelectedSourceAccountId);
                Account destAccount = db.Accounts.Find(viewModel.SelectedDestinationAccountId);

                manager.TransferMoney(srcAccount, destAccount, viewModel.TransferAmount); //From Account Manager
                db.SaveChanges();
            }
            catch (DataException)
            {
                ModelState.AddModelError("", "Something went wrong, transfer could not be completed.");
            }
        }
        return RedirectToAction("AccountSummary");
    }

AccountManager(这是持有实际转移资金逻辑的类。)

    public class AccountManager
{
    public void TransferMoney(Account srcAccount, Account destAccount, decimal transferAmount)
    {
        if (srcAccount.AccountTotal >= transferAmount)
        {
            srcAccount.AccountTotal -= transferAmount;
            destAccount.AccountTotal += transferAmount;
        }
    }
}

最后是转帐视图

@model eBank.ViewModels.TransferFundsViewModel
@using (Html.BeginForm()) {
    <fieldset>
        <legend>Transfer Funds</legend>

        <div class="editor-label">
            Source Account
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(viewModel => viewModel.ListOfSourceAccounts, Model.ListOfSourceAccounts, "Choose an Account")
        </div>

        <div class="editor-label">
            Destination Account
        </div>
        <div class="editor-field">
            @Html.DropDownListFor(viewModel => viewModel.ListOfDestinationAccounts, Model.ListOfDestinationAccounts, "Choose an Account")
        </div>

        <div class="editor-label">
            Transfer Amount
        </div>
        <div class="editor-field">
            @Html.EditorFor(viewModel => viewModel.TransferAmount)
        </div>

        <p>
            <input type="submit" value="Transfer" />
        </p>
    </fieldset>
}

【问题讨论】:

    标签: asp.net asp.net-mvc asp.net-mvc-4 viewmodel


    【解决方案1】:

    您需要在创建下拉列表时将第一个参数更改为使用 SelectedSourceAccountId。

    改变

    @Html.DropDownListFor(viewModel => viewModel.ListOfSourceAccounts, Model.ListOfSourceAccounts, "Choose an Account")
    

    对于

    @Html.DropDownListFor(viewModel => viewModel.SelectedSourceAccountId, Model.ListOfSourceAccounts, "Choose an Account")
    

    与其他下拉列表相同。

    现在您的模型应该具有价值,并且 srcAccount 和 destAccount 对象不会为空。

    【讨论】:

    • 哇,速度真快!谢谢你。我不敢相信修复如此简单......我花了至少一个半小时尝试不同的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多