4

ビューに表示されるプロパティである内部プロパティValueを含むラッパーモデルを作成しました。最も外側のモデルでは、ラッパーのタイプであるプロパティを作成し、そのプロパティにいくつかの属性と検証を適用します。ラッパービューがレンダリングされているときに、すべての検証と属性をラッパーから内部のValueプロパティにコピーして、最終的に呼び出したときにEditorFor(m => m.Value)、子プロパティをレンダリングするビューがコンテナプロパティに関連するバリデーターなどもレンダリングするようにします。

HomeController.cs

namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new IndexModel());
        }
    }
}

IndexModel.cs

namespace MvcApplication1.Models.Home
{
    public class IndexModel
    {
        [Display(Name = "Test Edit Field")]
        [MaxLength(10)]
        [AdditionalMetadata("ViewName", "String")]
        [TemplateVisibility(false, true)]
        public BatchEditField<string> TestEditField { get; set; }

        public IndexModel()
        {
            this.TestEditField = new BatchEditField<string>("TEST");
        }
    }
}

EditField.cs(「ラッパー」モデル。)

namespace MvcApplication1.Models.Home
{
    public class EditField
    {
        public string RawValue { get; set; }
        public object Value { get; set; }
        public string Description { get; set; }

        public EditField() { }

        public EditField(string rawValue, object value, string description = null)
        {
            this.RawValue = rawValue;
            this.Value = value;
            this.Description = (description ?? Convert.ToString(value));
        }

        public override string ToString()
        {
            return this.Description;
        }
    }

    public class EditField<T> : BatchEditField
    {
        public new T Value { get { return (T)base.Value; } set { base.Value = value; } }

        public EditField() { }

        public EditField(string defaultValue) : base(null, defaultValue, null) { }

        public EditField(string rawValue, T value, string description = null)
            : base(rawValue, value, description)
        {
        }
    }
}

EditField.cshtml(「ラッパー」ビュー。)

@using S3.Common.Extensions
@model MvcApplication1.Models.Home.EditField

@{
    //Attempting to copy AdditionalValues from the wrapper property to the child Value property.
    ModelMetadata property = this.ViewData.ModelMetadata.Properties.Single(o => "Value".Equals(o.PropertyName));

    foreach (var item in this.ViewData.ModelMetadata.AdditionalValues)
    {
        property.AdditionalValues[item.Key] = item.Value;
    }
}

@Html.EditorFor(m => m.Value, Convert.ToString(this.ViewData.ModelMetadata.AdditionalValues.ValueOrDefault("ViewName")))

@if (this.Model != null && !this.Model.RawValue.IsNullOrEmpty() && !this.Model.RawValue.Trim().IsNullOrEmpty())
{
    <p class="RawValue@(this.ViewData.ModelMetadata.AdditionalValues.ContainsKey("Style") ? " " + this.ViewData.ModelMetadata.AdditionalValues["Style"] : "")">@(this.Model.RawValue.IsNullOrEmpty() ? "(Not Specified)" : this.Model.RawValue)</p>
}

String.cshtml(子ビュー。)

@* Inspecting this.ViewData.ModelMetaData.AdditionalValues shows that it is empty; the parent AdditionalValues that were copied in the wrapper view did not make it through. *@
@Html.TextBox(string.Empty, this.ViewData.TemplateInfo.FormattedModelValue)
@Html.ValidationMessage(string.Empty)

概要

最後に、ページがレンダリングされるとき、String.cshtmlがレンダリングされるときにModelMetaDataに存在しないため、検証要素などは含まれません。

4

0 に答える 0