9

編集する多くのプロパティを持つエンティティの Edit.cshtml ファイルを作成したいので、次のコードを何度も記述する必要があります。

<div class="form-group">
    <label asp-for="Email" class="col-md-2 control-label"></label>
    <div class="col-md-10">
        <input asp-for="Email" class="form-control" />
        <span asp-validation-for="Email" class="text-danger"></span>
    </div>
</div>

実際には、多くのエンティティがあるため、多くの Edit.cshtml ファイルを作成する必要があります。いくつかの単純化を行いたい

コントローラーでエンティティのいくつかのプロパティを選択し、ループを使用してビューにプロパティを表示したいと考えています。例: コントローラ ファイル内:

public IActionResult Edit(string id)
{
    var model = GetModel(id);
    var propertyNames= new List<string>()
    {
        "Name",
        "Email"
        // add some other property names of the entity 
    };
    ViewData["PropertyList"] = propertyNames;
    return View(model);
}

ビューファイルで:

@{
    var propertyNames = (List<string>)ViewData["PropertyList"];
    foreach (string item in propertyNames)
    {
        <div class="form-group">
            <label asp-for="@(item)" class="col-md-2 control-label"></label>
            <div class="col-md-3">
                <input asp-for="@(item)" class="form-control" />
                <span asp-validation-for="@(item)" class="text-danger"></span>
            </div>          
        </div>
    }
}

しかし、間違ったコードを生成するため、機能しません。"asp-for" タグ ヘルパーに文字列値を渡すことができないようです。

たとえば、 top のコードを次のように変更すると:

@{
    string e = "Email";
    <div class="form-group">
        <label asp-for="@e" class="col-md-2 control-label"></label>
        <div class="col-md-10">
            <input asp-for="@e" class="form-control" />
            <span asp-validation-for="@e" class="text-danger"></span>
        </div>
    </div>
}

上記のコードはこれを生成します:

<div class="form-group">
    <label class="col-md-2 control-label" for="e">e</label>
    <div class="col-md-10">
        <input class="form-control" type="text" id="e" name="e" value="Email" />
        <span class="text-danger field-validation-valid" data-valmsg-for="e" data-valmsg-replace="true"></span>
    </div>
</div>

予想されるコードは次のとおりです。

<div class="form-group">
    <label class="col-md-2 control-label" for="Email">Email</label>
    <div class="col-md-10">
        <input class="form-control" type="email" data-val="true" data-val-email="Email &#x5B57;&#x6BB5;&#x4E0D;&#x662F;&#x6709;&#x6548;&#x7684;&#x7535;&#x5B50;&#x90AE;&#x4EF6;&#x5730;&#x5740;&#x3002;" data-val-required="Email &#x5B57;&#x6BB5;&#x662F;&#x5FC5;&#x9700;&#x7684;&#x3002;" id="Email" name="Email" value="" />
        <span class="text-danger field-validation-valid" data-valmsg-for="Email" data-valmsg-replace="true"></span>
    </div>
</div>

どうすればいいですか?

カミソリで可能ですか?

4

4 に答える 4

10

わかりました、私はこれを機能させることができました。免責事項:それは非常にハッキーであり、可能な限り最善の方法で行ったかどうかはわかりません。私が知っているのは、それがあなたが望むことをし、正しい方向にあなたを向けるかもしれないということだけです.

まず、モデルを作成しました:

using System.ComponentModel.DataAnnotations;

namespace WebApplication1.Models
{
    public class TestModel
    {
        [Required]
        public string Name { get; set; }

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

次に、カスタム タグ ヘルパーを作成しました。これは、「魔法」が起こる恐ろしい部分です。具体的には、Processメソッドの最初のセクション...

using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Mvc.ViewFeatures;
using Microsoft.AspNet.Razor.TagHelpers;
using System.Linq;

namespace WebApplication1.TagHelpers
{
    [HtmlTargetElement("edit")]
    public class EditTagHelper : TagHelper
    {
        [HtmlAttributeName("asp-for")]
        public ModelExpression aspFor { get; set; }

        [ViewContext]
        [HtmlAttributeNotBound]
        public ViewContext ViewContext { get; set; }

        protected IHtmlGenerator _generator { get; set; }

        public EditTagHelper(IHtmlGenerator generator)
        {
            _generator = generator;
        }

        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            var propName = aspFor.ModelExplorer.Model.ToString();
            var modelExProp = aspFor.ModelExplorer.Container.Properties.Single(x => x.Metadata.PropertyName.Equals(propName));
            var propValue = modelExProp.Model;
            var propEditFormatString = modelExProp.Metadata.EditFormatString;

            var label = _generator.GenerateLabel(ViewContext, aspFor.ModelExplorer,
                propName, propName, new { @class = "col-md-2 control-label", @type = "email" });

            var input = _generator.GenerateTextBox(ViewContext, aspFor.ModelExplorer,
                propName, propValue, propEditFormatString, new { @class = "form-control" });

            var validation = _generator.GenerateValidationMessage(ViewContext, aspFor.ModelExplorer, 
                propName, string.Empty, string.Empty, new { @class = "text-danger" });

            var inputParent = new TagBuilder("div");
            inputParent.AddCssClass("col-md-10");
            inputParent.InnerHtml.Append(input);
            inputParent.InnerHtml.Append(validation);

            var parent = new TagBuilder("div");
            parent.AddCssClass("form-group");
            parent.InnerHtml.Append(label);
            parent.InnerHtml.Append(inputParent);

            output.Content.SetContent(parent);
            base.Process(context, output);
        }
    }
}

NB : カスタム TagHelper を機能させるには、次の_ViewImports.cshtmlようにファイルに行を追加する必要があります (名前空間に置き換えWebApplication1ます)。

@addTagHelper "*, WebApplication1"

私は自分のアクションをこれに変更して、あなたのアクションと少し一致させました(リフレクションを使用して、ここでモデルのプロパティ名を取得できますか?):

public IActionResult Index()
{
    var propertyNames = new List<string>()
    {
        "Name",
        "Email"
    };
    ViewData["PropertyList"] = propertyNames;

    var m = new TestModel()
    {
        Name = "huoshan12345",
        Email = "test@test.net"
    };
    return View(m);
}

最後に、ビューで次のようなことができます。

<div class="row">
    @using (Html.BeginForm())
    {
        var propertyNames = (List<string>)ViewData["PropertyList"];
        foreach (string item in propertyNames)
        {
            <edit asp-for="@item"></edit>
        }
        <input type="submit" value="Submit" />
    }
</div>
于 2015-12-15T14:23:48.813 に答える
0

はい、カミソリで書くことは可能です。これがあなたを助けると思います。「type」属性を入れないと、で生成されtype='text'ます。data-val 属性をハードコーディングすることもできますが、単に「-」を「_」に置き換えることはお勧めしません。例:@data_val_email

<div class="form-group">
  @Html.LabelFor(x=>x.Email)
  <div class="col-md-10">
     @Html.TextBoxFor(x => x.Email, new { @class = "form-control", @type = "email" })
      @Html.ValidateFor(x=>x.Email)
  </div>
</div>
于 2015-12-15T09:32:29.357 に答える