2

私のビューでは、html テーブル全体を編集可能にしています。テーブルの各フィールドには検証があります。ここにいくつかのサンプルコードがあります...

<tbody>
    foreach (Item item in Model.Items)
    {
        <tr>
            <td>
                @Html.TextBoxFor(x => em.Value)
                @Html.ValidationMessageFor(x => em.Value)
            </td>
        </tr>
    }
</tbody>

これにより、ブラウザで 2 つの問題が発生しています。

1) すべてのコントロールの name 属性が同じであるため、1 つのフィールドが無効な場合、同じ名前のすべてのフィールドにエラー メッセージが表示されます。

2)おそらく名前にも関連しています。フォームを検証するときに、最初の行のコントロールが無効な場合、フォームは無効です。ただし、他のすべての行のコントロールは、(エラー メッセージが表示されても) フォームを無効にしません。

if (!$(form).valid()) {
    return false;
}

どんな考えでも役に立ちます。

更新: ソリューション

bobek の提案に従って、TextBoxInLoopF​​or と ValidationMessageInLoop のカスタム拡張機能を作成しました。以下は解決策です:

public static MvcHtmlString TextBoxInLoopFor<TModel, IItem, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IItem item, object htmlAttributes)
{
    var model = item as IInLoopForModel; 
    if (model == null)
        return MvcHtmlString.Empty; 

    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    var fieldName = ExpressionHelper.GetExpressionText(expression);
    var name = model.Name + fieldName;

    var tag = new TagBuilder("input");
    tag.MergeAttributes(new RouteValueDictionary(htmlAttributes));
    tag.Attributes.Add("id", name);
    tag.Attributes.Add("for", name);
    tag.Attributes.Add("name", name); 
    tag.Attributes.Add("value", metadata.Model.ToString());

    // Add the validation attributes
    ModelState modelState;
    if (html.ViewData.ModelState.TryGetValue(name, out modelState))
    {
        if (modelState.Errors.Count > 0)
            tag.AddCssClass(HtmlHelper.ValidationInputCssClassName);
    }
    tag.MergeAttributes(html.GetUnobtrusiveValidationAttributes(name, metadata));

    return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
}

public static MvcHtmlString ValidationMessageInLoopFor<TModel, IItem, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, IItem item)
{
        var model = item as IInLoopForModel;
    if (model == null)
        return MvcHtmlString.Empty;

    var fieldName = ExpressionHelper.GetExpressionText(expression);
    var name = model.Name + fieldName;

    var tag = new TagBuilder("span");
    tag.Attributes.Add("class", "field-validation-valid");
    tag.Attributes.Add("data-valmsg-replace", "true");
    tag.Attributes.Add("data-valmsg-for", name);
    return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
}
4

2 に答える 2

1

これはまったく有効ではありません。入力用の MVC3 ヘルパーはそれぞれに ID を追加しているため、ここでは同じ ID を持つ複数のテキスト ボックスが作成されます。HTML では無効です。

モデルの各プロパティに TextBoxFor と ValidationFor を手動で作成するか、可能であれば次を試してください。

foreach (Item item in Model.Items)
    {
        <tr>
            <td>
                @Html.TextBoxFor(x => item.Value)
                @Html.ValidationMessageFor(x => item.Value)
            </td>
        </tr>
    }
于 2012-05-31T13:59:14.737 に答える
0

domain.modelでメタデータを使用することをお勧めします。プロセスを理解するための小さな例を次に示します。

namespace yourDomain.Domain.Model
{
    [MetadataType(typeof(fooEntityMeta))]
    public partial class fooEntity
    {
}

エンティティから値フィールドを選択します。必要にする

public class fooEntityMeta
    {
        [Required(ErrorMessage = "Value is required")]
        public string Value;  
       ...
    }


プロセス全体を支援するリンクは次のとおりです:http://msdn.microsoft.com/en-us/magazine/ee336030.aspx

于 2012-05-31T14:04:59.220 に答える