0

私はMVCをまったく使用したことがなく、検証の概要が表示されない理由を理解しようとしています。コードは次のとおりです。

見る:

<% using(var form = Html.BeginForm("Create", "User"))
{%>
    <table>
        <thead>
            <th>Create User</th>
            <th><%= Html.ValidationSummary(false) %></th>
        </thead>
        <tbody>
            <tr>
                <td><%= Html.LabelFor(model => model.Creating.Username) %>:</td>
                <td><%= Html.TextBoxFor(model => model.Creating.Username) %></td>
            </tr>
            <tr>
                <td><%= Html.LabelFor(model => model.Creating.Firstname) %>:</td>
                <td><%= Html.TextBoxFor(model => model.Creating.Firstname)%></td>
            </tr>
            <tr>
                <td><%= Html.LabelFor(model => model.Creating.Lastname) %></td>
                <td><%= Html.TextBoxFor(model => model.Creating.Lastname) %></td>
            </tr>
            <tr>
                <td colspan="2">
                    <input type="submit" value="Create" />
                </td>
            </tr>
        </tbody>
    </table>

<%}%>

関連するコントローラーの方法:

[HttpPost]
public ActionResult Create(User creating)
{
    var response = _service.Save(creating);
    if (response.Success)
        return RedirectToAction("Index");
    response.Errors.CopyToModelState(this.ModelState);
    return RedirectToAction("Index");
}

ビジネスロジック方式:

public Response Save(User user)
{
    //Place Validation logic here
    //Check username is between 3-30 characters and make sure the username is unique
    //return response if username fails business rules

    bool isDataInvalid = false;
    List<ValidationError> errorList = new List<ValidationError>();
    if ((user.Username.Length < 3) || user.Username.Length > 30)
    {
        ValidationError invalidUsernameLengthError = new ValidationError();
        invalidUsernameLengthError.Property = "Creating.Username";
        invalidUsernameLengthError.ErrorMessage = "must be between 3 and 30 characters long";
        errorList.Add(invalidUsernameLengthError);
        isDataInvalid = true;
    }

    if (isDataInvalid)
    {
        return new Response()
        {
            Success = false,
            Errors = errorList
        };   
    }

    _repository.Save(user);

    return new Response()
    {
        Success = true
    };
}

ヘルパーメソッド:

public static void CopyToModelState(this List<ValidationError> errors,  ModelStateDictionary modelState)
{
    foreach (var error in errors)
    {
        modelState.AddModelError(error.Property, error.ErrorMessage);
    }
}

ロジックは想定どおりに動作しますが、何も表示されません。出力を取得するHTMLを確認しましたが、検証が書き込まれていません。モデルのプロパティをmodelStateに割り当て、関連するフィールドに検証を直接表示しようとしましたが、これも機能しません。何か案は?


ああ!RedirectToActionを実行すると新しいリクエストが発生するため、エラーデータは失われます。また、別のコントローラーを使用しているため、元のビュー(Index.aspx)を明示的に呼び出す必要があります。また、index.aspxが期待するモデルは、実際にはユーザーオブジェクトではなく、別のリストオブジェクトであるため、次のことを行う必要がありました。

        var users = _service.FindAll();
        return View("Index", new UserListModel() { Users = users });

RedirectToActionの代わりに。これは明らかにエラーを検証するための標準パターンです。成功(エラーなし)の場合はRedirectToActionを使用しますが、エラーの場合は正しいビューを返す必要があります。


OK、mattytommoに感謝します-それは本当に便利です。私はまだ問題を抱えています。私は今、コントローラー用にこれを持っています-あなたが提案したものと同様ですが、それでもエラーメッセージの表示はありません。データ注釈を試しましたが、機能させることができませんでした(MVC2を使用しています)。既存のコードを修正するために考えられるすべてのことを試みてきました。

    [HttpPost]
    public ActionResult Create(User creating)
    {
        var response = _service.Save(creating);
        if (response.Success)
            return RedirectToAction("Index");

        foreach (var error in response.Errors)
        {
            ModelState.AddModelError(error.Property, error.ErrorMessage);
        }

        return RedirectToAction("Index");
    }

他にアイデアはありますか?アドバイスに感謝します!

4

1 に答える 1

3

変数を値で渡していると思うModelStateので、その関数で行った変更は実際には保持されていません。関数の機能を再現してみてください。ただし、実際のModelStateオブジェクトに対しては、次のようになります。

[HttpPost]
public ActionResult Create(User creating)
{
    var response = _service.Save(creating);
    if (response.Success)
        return RedirectToAction("Index");

    foreach (var error in response.Errors)
    {
        ModelState.AddModelError(error.Property, error.ErrorMessage);
    }

    return View(creating);
}

Usernameまた、MVCデータアノテーションも確認する必要があります。プロパティに次の2つの属性を設定することで、自分のような検証を簡単に置き換えることができます。

[MinLength(3), MaxLength(30)]
public string UserName { get; set; }

StringLengthまたは、 (@ SimonWhiteheadに感謝)を使用して1つの属性のみ:

[StringLength(30, MinimumLength = 3)]

データ注釈:ここ

于 2013-01-25T00:43:40.540 に答える