web-dev-qa-db-ja.com

mvc razor viewmodelテキスト入力エディターに「必須」属性を追加する方法

次のMVC 5 Razor HTMLヘルパーがあります。

@Html.TextBoxFor(m => m.ShortName, 
  new { @class = "form-control", @placeholder = "short name"})

このフィールドは必須である必要があります(つまり、ユーザーが値innを入力せずにナビゲートすると赤いアウトラインが表示されます)。 WebForms HTML 5では、<input type="text" required />と言うだけでこの効果が得られます。 Razor構文でこれを実現するための適切な構文は何ですか?

41
Eugene Goldberg

必要に応じて、required html属性を使用できます。

@Html.TextBoxFor(m => m.ShortName, 
new { @class = "form-control", placeholder = "short name", required="required"})

または、.Netで RequiredAttribute クラスを使用できます。 jQueryを使用すると、RequiredAttributeはフロントエンドとサーバー側で検証できます。 MVCルートに行きたい場合は、 データアノテーションMVC3必須属性 を読むことをお勧めします。

OR

あなたは本当に高度になることができます:

@{
  // if you aren't using UnobtrusiveValidation, don't pass anything to this constructor
  var attributes = new Dictionary<string, object>(
    Html.GetUnobtrusiveValidationAttributes(ViewData.TemplateInfo.HtmlFieldPrefix));

 attributes.Add("class", "form-control");
 attributes.Add("placeholder", "short name");

  if (ViewData.ModelMetadata.ContainerType
      .GetProperty(ViewData.ModelMetadata.PropertyName)
      .GetCustomAttributes(typeof(RequiredAttribute), true)
      .Select(a => a as RequiredAttribute)
      .Any(a => a != null))
  {
   attributes.Add("required", "required");
  }

  @Html.TextBoxFor(m => m.ShortName, attributes)

}

または、複数のエディターテンプレートに必要な場合:

public static class ViewPageExtensions
{
  public static IDictionary<string, object> GetAttributes(this WebViewPage instance)
  {
    // if you aren't using UnobtrusiveValidation, don't pass anything to this constructor
    var attributes = new Dictionary<string, object>(
      instance.Html.GetUnobtrusiveValidationAttributes(
         instance.ViewData.TemplateInfo.HtmlFieldPrefix));

    if (ViewData.ModelMetadata.ContainerType
      .GetProperty(ViewData.ModelMetadata.PropertyName)
      .GetCustomAttributes(typeof(RequiredAttribute), true)
      .Select(a => a as RequiredAttribute)
      .Any(a => a != null))
    {
      attributes.Add("required", "required");
    }
  }
}

次に、テンプレートで:

@{
  // if you aren't using UnobtrusiveValidation, don't pass anything to this constructor
  var attributes = this.GetAttributes();

  attributes.Add("class", "form-control");
  attributes.Add("placeholder", "short name");

  @Html.TextBoxFor(m => m.ShortName, attributes)

}

更新1( Tomas がViewDataに不慣れな場合)。

ViewDataとViewBagの違いは何ですか?

抜粋:

したがって、基本的にそれ(ViewBag)は魔法の文字列を置き換えます:

ViewData["Foo"]

魔法の特性を持つ:

ViewBag.Foo
76
Erik Philips

モデルクラスで、そのプロパティを[Required]属性で装飾します。つまり:

[Required]
public string ShortName {get; set;}
20
Floremin

.NET Coreでこれを行う新しい方法は、TagHelpersを使用することです。

https://docs.Microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro

これらの例( MaxLengthLabel )に基づいて、既存のTagHelperをニーズに合わせて拡張できます。

RequiredTagHelper.cs

using Microsoft.AspNetCore.Razor.TagHelpers;
using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using System.Linq;

namespace ProjectName.TagHelpers
{
    [HtmlTargetElement("input", Attributes = "asp-for")]
    public class RequiredTagHelper : TagHelper
    {
        public override int Order
        {
            get { return int.MaxValue; }
        }

        [HtmlAttributeName("asp-for")]
        public ModelExpression For { get; set; }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            base.Process(context, output); 

            if (context.AllAttributes["required"] == null)
            {
                var isRequired = For.ModelExplorer.Metadata.ValidatorMetadata.Any(a => a is RequiredAttribute);
                if (isRequired)
                {
                    var requiredAttribute = new TagHelperAttribute("required");
                    output.Attributes.Add(requiredAttribute);
                }
            }
        }
    }
}

次に、ビューで使用するために追加する必要があります。

_ViewImports.cshtml

@using ProjectName
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper "*, ProjectName"

次のモデルを考えます:

Foo.cs

using System;
using System.ComponentModel.DataAnnotations;

namespace ProjectName.Models
{
    public class Foo
    {
        public int Id { get; set; }

        [Required]
        [Display(Name = "Full Name")]
        public string Name { get; set; }
    }
}

およびビュー(スニペット):

New.cshtml

<label asp-for="Name"></label>
<input asp-for="Name"/>

このHTMLになります:

<label for="Name">Full Name</label>
<input required type="text" data-val="true" data-val-required="The Full Name field is required." id="Name" name="Name" value=""/>

これが、.NET Coreを使用しているのと同じ質問を持つ人に役立つことを願っています。

6
bvpb

「必須」HTML5属性が必要だったので、次のようなことをしました。

<%: Html.TextBoxFor(model => model.Name, new { @required = true })%>
2
hestellez

@Erikの答えは私には飛びませんでした。

以下がやった:

 @Html.TextBoxFor(m => m.ShortName,  new { data_val_required = "You need me" })

さらに、フィールドの下で手動でこれを行うと、エラーメッセージコンテナを追加する必要がありました

@Html.ValidationMessageFor(m => m.ShortName, null, new { @class = "field-validation-error", data_valmsg_for = "ShortName" })

これで時間を節約できることを願っています。

0