如何使用 XmlHttpRequest 在 Mvc 5 中从 Json 渲染 PartialView
How to Render PartialView from Json in Mvc 5 with XmlHttpRequest
在Html
@section Scripts
{
<script type="text/javascript">
$(document).ready(function() {
$('#bSubmit').click(function(event) {
event.preventDefault();
var formData = new FormData();
formData.append('@Html.Get__RequestVerificationTokenString()', '@Html.GetAntiForgeryToken()');
formData.append('request.MessageId', @Model.MessageId);
formData.append('request.Message', $('#Message').val());
var xmlHttpRequest = new XMLHttpRequest();
if (!window.XMLHttpRequest) {
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttpRequest.open("POST",
'@Url.Action("Send", "Page", new {area = "Question"})',
true);
xmlHttpRequest.onloadend = function() {
var response = JSON.parse(xmlHttpRequest.responseText);
$('#prButton').removeClass("visible");
$('#prButton').addClass("invisible");
switch (response.Type) {
case 10:
LOG(response.PartialView);
$('#layoutSingleMessageItems .card-box').replaceWith(response.PartialView);
break;
case -13:
@Html.ShowAlert("خطا در ارسال اطلاعات!");
break;
}
};
xmlHttpRequest.send(formData);
});
});
</script>
}
<div class="row">
<div class="col-md-7">
@Html.Partial("Par_SingleMessageItem", Model.SingleMessageItems)
</div>
<div class="col-md-5">
<div class="card-box">
<form>
@Html.AntiForgeryToken()
<div class="form-group col-md-12">
<label class="col-form-label">پاسخ</label>
<textarea rows="8" id="Message" placeholder="لطفا پاسخ خود را وارد کنید ..."></textarea>
</div>
<div class="form-group col-md-12 m-t-10">
<button id="bSubmit" type="submit">
ارسال پاسخ
</button>
</div>
</form>
</div>
</div>
在局部视图中 (Par_SingleMessageItem)
@model List<_4Wheels.Areas.Question.Models.SingleMessage.SingleMessageItem>
<div id="layoutSingleMessageItems" class="card-box">
<div class="card-box">
@{
foreach (var item in Model)
{
//code
}
}
</div>
</div>
在控制器中
[HttpPost]
public ActionResult Send() {
/*
items = list object
*/
return Json(new SendAnswerResponse {
Type = 10,
SingleMessageItems = PartialView("Par_SingleMessageItem" , items)
});
}
在 SendAnswerResponse
public class SendAnswerResponse : MvcResponse
{
public PartialViewResult SingleMessageItems { get; set; }
}
所有这些代码都可以正常工作,但是 $('#layoutSingleMessageItems .card-box'). replaceWith(response.PartialView);
它不起作用,它不会出错 Returns 所需的 PartialView 只是 标签未更新。
我什至把它放在Console.log(response.PartialView)中来显示这条消息
Model: (5) […]
0: Object { Message: "fdgdfgdfg", Username: "", MessageDate: "1398-08-06 23:01:11", … }
1: Object { Message: "dsafd", Username: "", MessageDate: "1398-08-07 08:34:19", … }
2: Object { Message: "vcgdsafd", Username: "", MessageDate: "1398-08-07 08:34:58", … }
3: Object { Message: "fdgfdg", Username: "", MessageDate: "1398-08-07 08:42:43", … }
4: Object { Message: "fdgfdg", Username: "", MessageDate: "1398-08-07 08:42:54", … }
length: 5
: Array []
TempData: Array []
View: null
ViewBag: Object { }
ViewData: []
length: 0
: Array []
ViewEngineCollection: Array [ {…} ]
ViewName: "Par_SingleMessageItem"
: {…}
defineGetter: function defineGetter()
defineSetter: function defineSetter()
lookupGetter: function lookupGetter()
lookupSetter: function lookupSetter()
proto:
constructor: function Object()
hasOwnProperty: function hasOwnProperty()
isPrototypeOf: function isPrototypeOf()
propertyIsEnumerable: function propertyIsEnumerable()
toLocaleString: function toLocaleString()
toSource: function toSource()
toString: function toString()
valueOf: function valueOf()
: function proto()
: function proto()
Utility.js:13:13
response.SingleMessageItems return 是什么意思?
它 returns html ?还是数据结构?
我想你试试这样的东西
for(var i =0; i< response.SingleMessageItems.length; i++)
{
$('#layoutSingleMessageItems .card-box').append(response.SingleMessageItems[i]);
}
更新了以下 PartialView 代码
public static string RenderPartialViewToString(ControllerContext context, string viewPath, object model = null, bool partial = false)
{
// first find the ViewEngine for this view
ViewEngineResult viewEngineResult = null;
if (partial)
viewEngineResult = ViewEngines.Engines.FindPartialView(context, viewPath);
else
viewEngineResult = ViewEngines.Engines.FindView(context, viewPath, null);
if (viewEngineResult == null)
throw new FileNotFoundException("View cannot be found.");
// get the view and attach the model to view data
var view = viewEngineResult.View;
context.Controller.ViewData.Model = model;
string result = null;
using (var sw = new StringWriter())
{
var ctx = new ViewContext(context, view, context.Controller.ViewData, context.Controller.TempData, sw);
view.Render(ctx, sw);
result = sw.ToString();
}
return result;
}
public static T CreateController<T>(RouteData routeData = null) where T : Controller, new()
{
// create a disconnected controller instance
T controller = new T();
// get context wrapper from HttpContext if available
HttpContextBase wrapper;
if (System.Web.HttpContext.Current != null)
wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
else
throw new InvalidOperationException("Cannot create Controller Context if no active HttpContext instance is available.");
if (routeData == null)
routeData = new RouteData();
// add the controller routing if not existing
if (!routeData.Values.ContainsKey("controller") &&
!routeData.Values.ContainsKey("Controller"))
routeData.Values.Add("controller", controller.GetType().Name.ToLower().Replace("controller", ""));
controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
return controller;
}
并使用
return Json(new SendAnswerResponse {
Type = 10,
SingleMessageItems = MvcHelper.RenderPartialViewToString(
MvcHelper.CreateController<Controller Name>().ControllerContext ,
"view Path", items , true)
});
在Html
@section Scripts
{
<script type="text/javascript">
$(document).ready(function() {
$('#bSubmit').click(function(event) {
event.preventDefault();
var formData = new FormData();
formData.append('@Html.Get__RequestVerificationTokenString()', '@Html.GetAntiForgeryToken()');
formData.append('request.MessageId', @Model.MessageId);
formData.append('request.Message', $('#Message').val());
var xmlHttpRequest = new XMLHttpRequest();
if (!window.XMLHttpRequest) {
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttpRequest.open("POST",
'@Url.Action("Send", "Page", new {area = "Question"})',
true);
xmlHttpRequest.onloadend = function() {
var response = JSON.parse(xmlHttpRequest.responseText);
$('#prButton').removeClass("visible");
$('#prButton').addClass("invisible");
switch (response.Type) {
case 10:
LOG(response.PartialView);
$('#layoutSingleMessageItems .card-box').replaceWith(response.PartialView);
break;
case -13:
@Html.ShowAlert("خطا در ارسال اطلاعات!");
break;
}
};
xmlHttpRequest.send(formData);
});
});
</script>
}
<div class="row">
<div class="col-md-7">
@Html.Partial("Par_SingleMessageItem", Model.SingleMessageItems)
</div>
<div class="col-md-5">
<div class="card-box">
<form>
@Html.AntiForgeryToken()
<div class="form-group col-md-12">
<label class="col-form-label">پاسخ</label>
<textarea rows="8" id="Message" placeholder="لطفا پاسخ خود را وارد کنید ..."></textarea>
</div>
<div class="form-group col-md-12 m-t-10">
<button id="bSubmit" type="submit">
ارسال پاسخ
</button>
</div>
</form>
</div>
</div>
在局部视图中 (Par_SingleMessageItem)
@model List<_4Wheels.Areas.Question.Models.SingleMessage.SingleMessageItem>
<div id="layoutSingleMessageItems" class="card-box">
<div class="card-box">
@{
foreach (var item in Model)
{
//code
}
}
</div>
</div>
在控制器中
[HttpPost]
public ActionResult Send() {
/*
items = list object
*/
return Json(new SendAnswerResponse {
Type = 10,
SingleMessageItems = PartialView("Par_SingleMessageItem" , items)
});
}
在 SendAnswerResponse
public class SendAnswerResponse : MvcResponse
{
public PartialViewResult SingleMessageItems { get; set; }
}
所有这些代码都可以正常工作,但是 $('#layoutSingleMessageItems .card-box'). replaceWith(response.PartialView);
它不起作用,它不会出错 Returns 所需的 PartialView 只是 标签未更新。
我什至把它放在Console.log(response.PartialView)中来显示这条消息
Model: (5) […] 0: Object { Message: "fdgdfgdfg", Username: "", MessageDate: "1398-08-06 23:01:11", … } 1: Object { Message: "dsafd", Username: "", MessageDate: "1398-08-07 08:34:19", … } 2: Object { Message: "vcgdsafd", Username: "", MessageDate: "1398-08-07 08:34:58", … } 3: Object { Message: "fdgfdg", Username: "", MessageDate: "1398-08-07 08:42:43", … } 4: Object { Message: "fdgfdg", Username: "", MessageDate: "1398-08-07 08:42:54", … } length: 5 : Array [] TempData: Array [] View: null ViewBag: Object { } ViewData: [] length: 0 : Array [] ViewEngineCollection: Array [ {…} ] ViewName: "Par_SingleMessageItem" : {…} defineGetter: function defineGetter() defineSetter: function defineSetter() lookupGetter: function lookupGetter() lookupSetter: function lookupSetter() proto: constructor: function Object() hasOwnProperty: function hasOwnProperty() isPrototypeOf: function isPrototypeOf() propertyIsEnumerable: function propertyIsEnumerable() toLocaleString: function toLocaleString() toSource: function toSource() toString: function toString() valueOf: function valueOf() : function proto() : function proto() Utility.js:13:13
response.SingleMessageItems return 是什么意思? 它 returns html ?还是数据结构? 我想你试试这样的东西
for(var i =0; i< response.SingleMessageItems.length; i++)
{
$('#layoutSingleMessageItems .card-box').append(response.SingleMessageItems[i]);
}
更新了以下 PartialView 代码
public static string RenderPartialViewToString(ControllerContext context, string viewPath, object model = null, bool partial = false)
{
// first find the ViewEngine for this view
ViewEngineResult viewEngineResult = null;
if (partial)
viewEngineResult = ViewEngines.Engines.FindPartialView(context, viewPath);
else
viewEngineResult = ViewEngines.Engines.FindView(context, viewPath, null);
if (viewEngineResult == null)
throw new FileNotFoundException("View cannot be found.");
// get the view and attach the model to view data
var view = viewEngineResult.View;
context.Controller.ViewData.Model = model;
string result = null;
using (var sw = new StringWriter())
{
var ctx = new ViewContext(context, view, context.Controller.ViewData, context.Controller.TempData, sw);
view.Render(ctx, sw);
result = sw.ToString();
}
return result;
}
public static T CreateController<T>(RouteData routeData = null) where T : Controller, new()
{
// create a disconnected controller instance
T controller = new T();
// get context wrapper from HttpContext if available
HttpContextBase wrapper;
if (System.Web.HttpContext.Current != null)
wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);
else
throw new InvalidOperationException("Cannot create Controller Context if no active HttpContext instance is available.");
if (routeData == null)
routeData = new RouteData();
// add the controller routing if not existing
if (!routeData.Values.ContainsKey("controller") &&
!routeData.Values.ContainsKey("Controller"))
routeData.Values.Add("controller", controller.GetType().Name.ToLower().Replace("controller", ""));
controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
return controller;
}
并使用
return Json(new SendAnswerResponse {
Type = 10,
SingleMessageItems = MvcHelper.RenderPartialViewToString(
MvcHelper.CreateController<Controller Name>().ControllerContext ,
"view Path", items , true)
});