1

我像这样在我的模型上使用 HtmlString 属性

public HtmlString Html { get; set; }

然后我有一个呈现和 html 编辑器的 EditorTemplate,但是当我使用 TryUpdateModel() 时,我得到一个 InvalidOperationException,因为没有类型转换器可以在这些类型 String 和 HtmlString 之间转换。

我需要创建自定义模型绑定器还是有其他方法?

更新:

我试图在我的模型上使用 HtmlString,主要是为了让它明显包含 HTML。所以这就是我的完整模型的样子:

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

这就是我呈现表单的方式:

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

我创建了自己的名为 Object.cshtml 的编辑器模板,以便可以将 MainBody 字段呈现为文本区域。

我的控制器有一个 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,因为 bindingContext.ModelName 只包含 MainBody 而不是 MainBody.MainBody?

我也对其他解决方案感兴趣,或者如果有人认为这是一个非常糟糕的主意。

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 回答