我有一个ASP.NET MVC应用程序,它使用以下部分视图来显示用户输入的注释:
@model NoteViewModel
<div title="@Model.Content"><span class="accordion-header">@Model.HeaderText</span></div>
<div>
@using (Ajax.BeginForm("SaveNote", "Note", null, new AjaxOptions() { OnSuccess = "SaveNoteCallback(data, status, xhr)" }, new { id = ("Note" + Model.NoteId + "_form") }))
{
@Html.HiddenFor(model => model.AuditId)
@Html.HiddenFor(model => model.NoteId)
@Html.HiddenFor(model => model.NoteTypeId)
@Html.TextAreaFor(model => model.Content, new { @class = "rteditor" })
<div class="note-buttons">
<input class="note-button note-submit" type="submit" value="Save" />
@Html.ActionLink("Delete", "Delete", "Note", new { id = Model.NoteId }, new { @class = "note-button note-delete" })
</div>
}
</div>
模型的Content
属性通常包含HTML内容,例如<p>Example</p>
。此内容显示在CKEditor实例中。在初始页面加载期间将部分视图作为另一个视图的一部分加载时,这可以正常工作。我遇到的问题是我还需要能够将部分视图返回到AJAX回调以通过JQuery进行渲染。当我在JQuery中得到结果时,Content
被编码:
<div title="<p>Example</p>"><span class="accordion-header">Added by John Doe on Aug 05, 2014</span></div>
<div>
<form action="/Note/SaveNote" class="smartaudit" data-ajax="true" data-ajax-success="UpdateNoteCallback(data, status, xhr)" id="Note50_form" method="post">
<input data-val="true" data-val-number="The field AuditId must be a number." data-val-required="The AuditId field is required." id="AuditId" name="AuditId" type="hidden" value="327" />
<input data-val="true" data-val-number="The field NoteId must be a number." data-val-required="The NoteId field is required." id="NoteId" name="NoteId" type="hidden" value="50" />
<input data-val="true" data-val-number="The field NoteTypeId must be a number." data-val-required="The NoteTypeId field is required." id="NoteTypeId" name="NoteTypeId" type="hidden" value="2" />
<textarea cols="20" id="Content" name="Content" rows="2">&lt;p&gt;Example&lt;/p&gt;</textarea>
<div class="note-buttons">
<input class="note-button note-submit" type="submit" value="Save" />
<a class="note-button note-delete" href="/Note/Delete/50">Delete</a>
</div>
</form>
</div>
如您所见,我首先直接使用Content
属性在第一个div
元素上设置title属性 - 内容已正确编码为<p>Example</p>
。我还在Content
html帮助器中再次使用TextAreaFor
属性。在这种情况下,视图将文本区域内的内容双重编码为&lt;p&gt;Example&lt;/p&gt;
。这是我在javascript回调中得到的原始结果 - 它不是我在脚本中所做的任何事情的结果。
以下是在此场景中返回局部视图的控制器操作:
[HttpPost]
public PartialViewResult SaveNote(NoteViewModel viewModel)
{
Note note;
if (viewModel.NoteId == 0)
{
note = Db.Notes.Create();
Db.Notes.Add(note);
}
else
{
note = Db.Notes.Find(viewModel.NoteId);
}
Mapper.Map<NoteViewModel, Note>(viewModel, note);
Db.SaveChanges();
Mapper.Map<Note, NoteViewModel>(note, viewModel);
return PartialView("~/Views/Shared/NoteView.cshtml", viewModel);
}
编辑:这是我最初尝试处理返回的部分视图:
function SaveNoteCallback(data, status, xhr) {
var notesContainer = $("#accordion-container");
var html = $(data);
html.appendTo(notesContainer);
notesContainer.accordion("refresh");
var contentArea = $(".rteditor", html)[0];
CKEDITOR.replace(contentArea, {
width: '100%',
resize_enabled: false,
htmlEncodeOutput: true
});
$(".note-button", html).button();
$(".note-buttons", html).show();
}
我想知道最简洁的处理方法是什么。是否可以获取部分视图以返回未编码的HTML内容?最好是从客户端回调函数解码它(以及如何完成)?
编辑2 :在进行一些调试之后,我真的很期待html内容被TextAreaFor
和/或TextArea
html助手双重编码视图通过控制器的PartialView
方法呈现(而不是通过另一个视图中的Html.Partial
呈现)。
答案 0 :(得分:0)
事实证明问题的根源是我的控制器在渲染局部视图之前解码模型的Content
属性(通过automapper)。这是避免双重编码的必要条件。但是,我没有考虑的是ModelState
字典仍然包含Content
属性的编码版本,因此在视图渲染过程中html助手仍在使用它。
解决方案是在返回部分视图之前调用ModelState.Clear()
。