简体   繁体   中英

Asp Net Core 2 Models in one page Validation

To be short, I have 2 View Models, one is for creating and another for editing. The problem is to bypass ModelState validation for one of them. For example, I want to edit a user. When I post it will say validation is invalid for the Input Model which I do not want to use when I trigger the OnPostEdit handler. I tried to remove the key from ModelState but does not work because using debugger all the properties appear without the class which means I would have to remove all properties one by one by their names. The point is, how can I handle all of this without having to remove keys one by one? I know I could just create another page but it's better UX to have it all on one.

Also I found a similar post but has no solution, but should explain what I need better too. Razor Pages - Model validation fails due to multiple objects sharing parameters

@if (Model.EditInput != null)
{
    <form method="post" asp-page-handler="Edit">
        <!-- Modal -->
        <div class="modal fade" id="modalEditUser" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
            <div class="modal-dialog modal-lg" role="document">
                <div class="modal-content">
                    <div class="modal-header bg-warning">
                        <h5 class="modal-title" id="exampleModalLabel"><i class="fas fa-edit"></i> Editar Utilizador</h5>
                        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                            <span aria-hidden="true"><i class="fas fa-times"></i></span>
                        </button>
                    </div>
                    <div class="modal-body">
                        <input type="hidden" asp-for="EditInput.Id" />

                        <div class="form-row">
                            <div class="form-group col-md-12">
                                <label asp-for="EditInput.UserName"></label>
                                <input asp-for="EditInput.UserName" class="form-control rounded-0" />
                                <span asp-validation-for="EditInput.UserName" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group col-md-12">
                                <label asp-for="EditInput.Name"></label>
                                <input asp-for="EditInput.Name" class="form-control rounded-0" />
                                <span asp-validation-for="EditInput.Name" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group col-md-12">
                                <label asp-for="EditInput.Email"></label>
                                <input asp-for="EditInput.Email" class="form-control rounded-0" />
                                <span asp-validation-for="EditInput.Email" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group col-md-12">
                                <label asp-for="EditInput.Password"></label>
                                <input asp-for="EditInput.Password" class="form-control rounded-0" />
                                <span asp-validation-for="EditInput.Password" class="text-danger"></span>
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group col-md-12">
                                <label asp-for="EditInput.ConfirmPassword"></label>
                                <input asp-for="EditInput.ConfirmPassword" class="form-control rounded-0" />
                                <span asp-validation-for="EditInput.ConfirmPassword" class="text-danger"></span>
                            </div>
                        </div>

                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancelar</button>
                        <button type="submit" class="btn btn-warning">Guardar</button>
                    </div>
                </div>
            </div>
        </div>
    </form>
}

<form method="post">
    <!-- Modal -->
    <div class="modal fade" id="modalAddUser" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content">
                <div class="modal-header bg-lightblue">
                    <h5 class="modal-title" id="exampleModalLabel">Adicionar Artigo a Kit</h5>
                    <button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true"><i class="fas fa-times"></i></span>
                    </button>
                </div>
                <div class="modal-body">

                    <div class="form-row">
                        <div class="form-group col-md-12">
                            <label asp-for="Input.UserName"></label>
                            <input asp-for="Input.UserName" class="form-control rounded-0" />
                            <span asp-validation-for="Input.UserName" class="text-danger"></span>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-group col-md-12">
                            <label asp-for="Input.Name"></label>
                            <input asp-for="Input.Name" class="form-control rounded-0" />
                            <span asp-validation-for="Input.Name" class="text-danger"></span>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-group col-md-12">
                            <label asp-for="Input.Email"></label>
                            <input asp-for="Input.Email" class="form-control rounded-0" />
                            <span asp-validation-for="Input.Email" class="text-danger"></span>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-group col-md-12">
                            <label asp-for="Input.Password"></label>
                            <input asp-for="Input.Password" class="form-control rounded-0" />
                            <span asp-validation-for="Input.Password" class="text-danger"></span>
                        </div>
                    </div>
                    <div class="form-row">
                        <div class="form-group col-md-12">
                            <label asp-for="Input.ConfirmPassword"></label>
                            <input asp-for="Input.ConfirmPassword" class="form-control rounded-0" />
                            <span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
                        </div>
                    </div>

                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancelar</button>
                    <button type="submit" class="btn bg-lightblue">Adicionar</button>
                </div>
            </div>
        </div>
    </div>
</form>

Page Model

    [BindProperty]
    public EditUserVM EditInput { get; set; }
    [BindProperty]
    public UserVM Input { get; set; }

   public async Task<IActionResult> OnPostAsync()
    {     
        if (!ModelState.IsValid)
        {
            GetData();
            _toast.AddErrorToastMessage("Dados inválidos.");
            return Page();
        }

        // add user

        _toast.AddSuccessToastMessage("Utilizador alterado.");
        return RedirectToPage("Index");
    }

    public async Task<IActionResult> OnPostEditAsync()
    {
        ModelState.Remove(nameof(UserVM));
        if (!ModelState.IsValid)
        {
            GetData();
            _toast.AddErrorToastMessage("Dados inválidos.");
            return Page();
        }

        var user = await _userManager.FindByIdAsync(EditInput.Id.ToString());

        user.UserName = EditInput.UserName;
        user.Name = EditInput.Name;
        user.Email = EditInput.Email;
        user.IsBlocked = EditInput.IsBlocked;
        user.ModifiedAt = DateTime.Now;

        var hashedPassword = _userManager.PasswordHasher.HashPassword(user, EditInput.Password);
        user.PasswordHash = hashedPassword;

        await _userManager.UpdateAsync(user);

        _toast.AddSuccessToastMessage("Utilizador alterado.");
        return RedirectToPage("Index");
    }

So the solution is to wrap both models into one

For example instead of having this

[BindProperty]
public EditUserVM EditInput { get; set; }
[BindProperty]
public UserVM Input { get; set; }

I would create another class in my page and change the properties around the page accordingly. With this If I hit the Edit Handler, the UserVM won't appear on the ModelState and the same vice-versa

[BindProperty]
public FormModel Form { get; set; }

public class FormModel 
{
    public UserVM Input { get; set; }
    public EditUserVM EditInput { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM