1

このようにモデルでHtmlStringプロパティを使用しています

public HtmlString Html { get; set; }

次に、レンダリングするEditorTemplateとhtmlエディターがありますが、TryUpdateModel()を使用すると、型コンバーターがこれらの型StringとHtmlStringの間で変換できないため、InvalidOperationExceptionが発生します。

カスタムモデルバインダーを作成する必要がありますか、それとも別の方法がありますか?

アップデート:

モデルでHtmlStringを使用しようとしていますが、これは主に、モデルにHTMLが含まれていることを明確にするためです。だからこれは私の完全なモデルがどのように見えるかです:

public class Model {
    public HtmlString MainBody { get; set; }
}

これが私がフォームをレンダリングする方法です:

@using (Html.BeginForm("save","home")){
    @Html.EditorForModel()
    <input type="submit" name="submit" />
}

MainBodyフィールドをテキストエリアとしてレンダリングできるように、Object.cshtmlという独自のエディターテンプレートを作成しました。

私のコントローラーには、次のようなSaveメソッドがあります。

public void Save([ModelBinder(typeof(FooModelBinder))]Model foo) {
    var postedValue = foo.MainBody;
}

ご覧のとおり、私は次のようなカスタムモデルバインダーで遊んでいます。

public class FooModelBinder : DefaultModelBinder {
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) {
        if (propertyDescriptor.PropertyType == typeof(HtmlString)) {
            return new HtmlString(controllerContext.HttpContext.Request.Form["MainBody.MainBody"]);
        }
        return null;
    }
}

これは期待どおりに機能しますが、bindingContext.ModelNameにはMainBodyのみが含まれ、MainBody.MainBodyは含まれないため、bindingContextから完全なModelNameを取得する方法がわかりません。

私はこれに関する他の解決策にも興味があります、あるいは誰かがそれが本当に悪い考えだと思うなら。

4

1 に答える 1

2

カスタムモデルバインダーを作成する必要がありますか

はい。HtmlStringこのクラスにはパラメーターのないコンストラクターがなく、デフォルトのモデルバインダーにはインスタンス化する方法がわからないため、ビューモデルでプロパティを使用する場合は可能です。

または別の方法はありますか?

HtmlStringはい、ビューモデルでプロパティを使用しないでください。他の方法もあるかもしれません。残念ながら、あなたはあなたの文脈とあなたが何を達成しようとしているのかについて厳密に0の情報を提供したので、これまで私たちがあなたを助けることができるのはそれだけです。


アップデート:

コードのほんの一部を示したので、ここにサンプルを示します。

モデル:

public class Model
{
    public HtmlString MainBody { get; set; }
}

コントローラ:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new Model());
    }

    [HttpPost]
    public ActionResult Index([ModelBinder(typeof(FooModelBinder))]Model foo)
    {
        var postedValue = foo.MainBody;
        return Content(postedValue.ToHtmlString(), "text/plain");
    }
}

モデルバインダー:

public class FooModelBinder : DefaultModelBinder
{
    protected override object GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder)
    {
        if (propertyDescriptor.PropertyType == typeof(HtmlString))
        {
            return new HtmlString(bindingContext.ValueProvider.GetValue(bindingContext.ModelName).AttemptedValue);
        }
        return null;
    }
}

ビュー(~/Views/Home/Index.cshtml):

@using (Html.BeginForm())
{
    @Html.EditorForModel()
    <input type="submit" name="submit" />
}

詳細を行うためのカスタムオブジェクトエディタテンプレート(~/Views/Shared/EditorTemplates/Object.cshtml):

@foreach (var property in ViewData.ModelMetadata.Properties.Where(x => x.ShowForEdit))
{
    if (!string.IsNullOrEmpty(property.TemplateHint))
    {
        @Html.Editor(property.PropertyName, property.TemplateHint)
    }
    else
    {
        @Html.Editor(property.PropertyName)
    }
}

HtmlStringテキストエリアとしてレンダリングされるタイプのカスタムエディタテンプレート( ~/Views/Shared/EditorTemplates/HtmlString.cshtml):

@Html.TextArea("")

ちなみに、単純な文字列の代わりにHtmlStringをプロパティとして使用する理由はまだわかりませんが、とにかく。

于 2012-07-08T19:52:48.803 に答える