【问题标题】:MVC - Manage account. One view with two partial views and two modelsMVC - 管理帐户。一个视图有两个局部视图和两个模型
【发布时间】:2014-02-07 11:54:38
【问题描述】:

上课好!

我正在处理我的管理帐户页面,用户可以在其中更改密码和电子邮件。

我有一个管理视图,其中有两个部分视图,更改密码和更改电子邮件。两者都使用两种不同的模型。这样做的目的是在同一页面上同时更改密码和更改电子邮件。

如果当前密码正确,则可以更改密码,但我的问题是我输入了错误的当前密码。这给了我一个 InvalidOperationException:

“传入字典的模型项的类型为‘test.Models.LocalPasswordModel’,但此字典需要‘test.Models.LocalEmailModel’类型的模型项。”

忽略瑞典语错误信息:)

这是我的模型:

public class LocalPasswordModel
{
    [Required(ErrorMessage = "Nuvarande lösenord måste fyllas i.")]
    [DataType(DataType.Password)]
    [Display(Name = "Nuvarande lösenord")]
    public string OldPassword { get; set; }

    [Required(ErrorMessage = "Nya lösenordet måste fyllas i.")]
    [StringLength(100, ErrorMessage = "Lösenordet måste vara minst 4 tecken lång.", MinimumLength = 4)]
    [DataType(DataType.Password)]
    [Display(Name = "Nya lösenordet")]
    public string NewPassword { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Bekräfta nya lösenordet")]
    [Compare("NewPassword", ErrorMessage = "De nya angivna lösenorden stämmer inte med varandra.")]
    public string ConfirmPassword { get; set; }
}

public class LocalEmailModel
{
    [Required(ErrorMessage = "Nuvarande E-postadress måste fyllas i.")]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Nuvarande E-postadress")]
    public string OldEmail { get; set; }

    [Required(ErrorMessage = "Nya E-postadressen måste fyllas i.")]
    [System.Web.Mvc.Remote("IsUserEmailAvailable", "Account", ErrorMessage = "E-postadressen används redan. Var god skriv in en annan E-postadress.")]
    [DataType(DataType.EmailAddress)]
    [Display(Name = "Nya E-postadressen")]
    public string NewEmail { get; set; }

    [DataType(DataType.EmailAddress)]
    [Display(Name = "Bekräfta nya E-postadressen")]
    [Compare("NewEmail", ErrorMessage = "De nya angivna E-postadresserna stämmer inte med varandra.")]
    public string ConfirmEmail { get; set; }
}

这是我的看法:

“父视图”:

@model test.Models.LocalPasswordModel
@{
    ViewBag.Title = "Hantera ditt konto";
}

<p class="message-success">@ViewBag.StatusMessage</p>

<p>Du är inloggad som <strong>@User.Identity.Name</strong>.</p>

<div id="Managebox1">
    @Html.Partial("_ChangePasswordPartial")
</div>

<div id="Managebox2">
    @Html.Partial("_ChangeEmailPartial")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

“子视图,修改密码”:

@model test.Models.LocalPasswordModel

<h3>Byt lösenord</h3>

@using (Html.BeginForm("Manage", "Account")) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    <fieldset>
        <legend>Change Password Form</legend>
        <ol>
            <li>
                @Html.LabelFor(m => m.OldPassword)
                @Html.PasswordFor(m => m.OldPassword)
            </li>
            <li>
                @Html.LabelFor(m => m.NewPassword)
                @Html.PasswordFor(m => m.NewPassword)
            </li>
            <li>
                @Html.LabelFor(m => m.ConfirmPassword)
                @Html.PasswordFor(m => m.ConfirmPassword)
            </li>
        </ol>
        <input type="submit" value="Byt lösenord" id="managesubmit" />
    </fieldset>
}

“子视图,更改邮箱”:

@model test.Models.LocalEmailModel

<h3>Byt E-postadress</h3>

@using (Html.BeginForm("ManageEmail", "Account")) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary()

    <fieldset>
        <legend>Change Email Form</legend>
        <ol>
            <li>
                @Html.LabelFor(n => n.OldEmail)
                @Html.TextBoxFor(n => n.OldEmail)
            </li>
            <li>
                @Html.LabelFor(n => n.NewEmail)
                @Html.TextBoxFor(n => n.NewEmail)
            </li>
            <li>
                @Html.LabelFor(n => n.ConfirmEmail)
                @Html.TextBoxFor(n => n.ConfirmEmail)
            </li>
        </ol>
        <input type="submit" value="Byt E-postadress" id="managesubmit"/>
    </fieldset>
}

【问题讨论】:

  • 我在父视图中删除了@model test.Models.LocalPasswordModel,进行管理。这并没有解决它。使用具有两个不同模型的两个局部视图,这不应该吗?
  • 动作方法的方法签名是什么样的?你有两种形式都在AccountController上的操作方法Manage上,看起来MVC选择了错误的一种。

标签: c# asp.net-mvc


【解决方案1】:

当您调用Html.Partial 时只使用一个参数,即要渲染的局部视图的名称,它会自动传入主视图的模型,即LocalPasswordModel。您需要做的是如下所示:

public class ManageViewModel
{
    public ManageViewModel()
    {
        LocalPassword = new LocalPasswordModel();
        LocalEmail = new LocalEmailModel();
    }

    public LocalPasswordModel LocalPassword { get; set; }
    public LocalEmailModel LocalEmail { get; set; }
}

然后,在您的主视图中:

@model test.Models.ManageViewModel

...

<div id="Managebox1">
    @Html.Partial("_ChangePasswordPartial", Model.LocalPassword)
</div>

<div id="Managebox2">
    @Html.Partial("_ChangeEmailPartial", Model.LocalEmail)
</div>

【讨论】:

  • 您好,感谢您的回复。我尝试了您的代码,但单击管理视图后立即收到 nullreferenceexception:对象引用未设置为对象的实例。
  • 您是否按照我的指示添加了构造函数?你需要初始化两个模型,否则你会得到空引用异常。
  • 是的,我完全按照你说的做了。在我的 ChangeEmailPartial 中,我将使用:模型 test.Models.LocalEmailModel,在我的 ChangePasswordpartial 中,我将使用模型 test.Models.LocalPasswordModel,对吗?谢谢
  • 我错过了什么吗?谢谢
  • 我在这里的另一个问题中更彻底地解释了它:stackoverflow.com/questions/21677514/…
猜你喜欢
  • 1970-01-01
  • 2019-04-21
  • 1970-01-01
  • 1970-01-01
  • 2014-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-02
相关资源
最近更新 更多