【问题标题】:Remote validation works for creating or editing but not both远程验证适用于创建或编辑,但不能同时适用
【发布时间】:2017-01-04 10:41:22
【问题描述】:

我想使用远程验证来检查用户名是否存在。我正在使用 Viewmodel 创建用户。虽然我可以这样做以获得创建或编辑目的的验证,但它不适用于创建和编辑。这是我的模型:

    [Required]
    [Display(Name = "Homeowner Username")]
    [Remote("doesUserNameExist", "Homeowners", HttpMethod = "POST", ErrorMessage = "User name already exists. Please enter a different user name.", AdditionalFields = "InitialUsername")]

这是我的编辑视图:

    @Html.Hidden("Homeowner.InitialUsername", Model.Username)


    <div class="form-group">
        @Html.LabelFor(model => model.Username, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Username, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Username, "", new { @class = "text-danger" })
        </div>
    </div>

这是我的控制器在注册但不能编辑的版本中(编辑时,参数为空):

    public JsonResult doesUserNameExist([Bind(Prefix = "Homeowner.Username")]string Username, [Bind(Prefix = "InitialUsername")] string InitialUsername)  
    {
       MY CODE
    }

这是我的控制器,用于编辑但不能创建(创建时,两个参数都为空):

    public JsonResult doesUserNameExist([Bind(Include = "Homeowner.Username")]string Username, [Bind(Include = "InitialUsername")] string InitialUsername)  
    {
       MY CODE
    }

我已经尝试了很多变体,但就是无法做到。

我看过这里:ASP.NET MVC Binding with Remote Validation

这里:

Remote ViewModel validation of nested objects not working

在这里:http://forums.asp.net/t/1652512.aspx?Compound+View+Model+object+causing+remote+validation+failure

但我似乎遗漏了什么。有没有办法让我既可以编辑也可以注册?我对此很陌生,如果有任何想法,我将不胜感激!

编辑:

也许这是一个糟糕的设计选择(第一次使用视图模型,只编写了几个月的代码),但我试图在创建新应用程序用户的同时创建一个新的房主和地址角色。这是我正在使用的视图模型:

public class RegisterHomeownerViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    public string Email { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
    public int roles { get; set; }
    public virtual Address Address { get; set; }
    public virtual Homeowner Homeowner { get; set; }
}

这是我在帐户控制器中的方法:

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> RegisterHomeowner(RegisterHomeownerViewModel model, Address address, Homeowner homeowner)
    {
        ApplicationDbContext db = new ApplicationDbContext();

        if (ModelState.IsValid)
        {
            var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
            var result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {

                var role = db.Roles.Find("0");
                UserManager.AddToRole(user.Id, role.Name);
                await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                db.Addresses.Add(address);
                homeowner.UserId = user.Id;
                homeowner.AddressID = address.ID;
                db.Homeowners.Add(homeowner);
                db.SaveChanges();


                return RedirectToAction("Index", "Homeowners");

            }
            AddErrors(result);
        }

        return View(model);
    }

这是我用来创建这些实体的视图:

<div class="form-horizontal">
    <h4>RegisterViewModel</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Homeowner.Username, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Homeowner.Username, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Homeowner.Username, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Email, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Email, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Email, "", new { @class = "text-danger" })
        </div>
    </div>

据我所知,除了对用户名进行远程验证外,一切都有效。在上面的帐户方法中创建时我可以得到它给我一个错误,或者我可以通过删除前缀进行编辑时出错(这使得我的用户名无法识别。显然我做错了什么。

【问题讨论】:

  • 显示 create 方法的视图。如果你使用视图模型,为什么你有Homeowner.InitialUsername 而不是简单的InitialUsername。并且拥有Bind(Include="..") 毫无意义(您没有发布模型)。而创建的时候怎么会有InitialUsername呢?
  • 我编辑了我的帖子并添加了更多细节。我可以按照您的建议通过更改来提取 InitalUsername,但在尝试编辑时仍然无法同时获取用户名和 InitalUser 名称。感谢上面帖子中的提示。在我根本无法提取 InitialUsername 之前。
  • A view model 不应包含数据模型,当然也不应包含虚拟属性。但是你想用你的Remote 属性做什么(到目前为止你所展示的没有任何意义)。在任何情况下,您都需要 2 个单独的模型来创建和编辑)
  • 感谢您的提示。我很感激。
  • 知道了。非常感谢斯蒂芬!你直率的指导真的很有帮助。

标签: c# jquery asp.net-mvc validation


【解决方案1】:

我明白了。我读了几次斯蒂芬的帖子和一些关于虚拟属性的帖子。我上床睡觉,起床并通过删除所有数据模型来修改我的视图模型。然后,为了在创建时进行验证,我将输入与我的视图模型中的验证属性进行了比较,而不是我的实际模型。这适用于创作。然后,当我编辑时,我将输入与实际模型中的验证属性进行比较。当我了解到您可以对视图模型进行与模型中不同的验证时,这是有道理的。这个线程也有帮助:View Model virtual properties and drop down lists。非常感谢!我从中学到了很多!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多