通过 AJAX 请求 DNN MVC 执行操作
Executing an action by an AJAX request DNN MVC
我的DNN MVC开发之旅又出现了一个问题。我想知道这是否是我犯错的 bug/missing 功能。
我会在下面尝试解释这个问题。
我想达到的目标
我想通过调用 AJAX post 在我的控制器中执行一个动作。到目前为止它有效。
但是,当我尝试 return 一些变量到我的视图时,它不仅 return 变量。它将整个 HTML-source 添加到响应中。
JSON REPONSE
我的控制器
我的方法 return 是一个 ActionResult(我尝试了 JsonResult 和一些不同的东西:HttpResponseMessage 以及)。
该程序本身正在运行并执行 return JSON-消息。
public ActionResult Mark(int itemId)
{
var item = _itemService.GetItem(itemId, ModuleContext.ModuleId);
// Check if item exists
if (item == null)
return Json(new { success = false, Description = "the item you want to vote for does not exist (anymore)" }, JsonRequestBehavior.AllowGet);
// Check if user is voting on his own item
if (item.CreatedByUserId == User.UserID)
return Json(new { success = false, Description = "it is not allowed to vote for your own item" }, JsonRequestBehavior.AllowGet);
我的观点
下面的视图不是我的最终视图,而是为了测试。
$("#button").click(function () {
$.ajax({
type: "POST",
url: "@Url.Action("Mark", "Vote")",
dataType: "json",
data: { itemId: JSON.stringify(16) },
success: function (data) { console.log(data); },
error: function (errMsg) {
responseText = jQuery.parseJSON(errMsg.responseText);
console.log(responseText.Description);
}
});
});
这是一个错误,还是我可以修复的问题?非常感谢您的宝贵时间。
https://dnntracker.atlassian.net/browse/DNN-8522
根据 DNN 关于 Unsupported MVC Features 的文档,目前不支持 ActionResult 以外的任何结果。
我能够在我的一个 MVC 控制器方法中 return JsonResult,它会 return JSON 响应,但是,就像你提到的,附加到它的是 View HTML。我的 hacky 解决方案是解析响应以从中获取我的 json 字符串。
...
success: function (response) {
var dnnViewResp = response.xhr.responseText;
dnnViewResp = dnnViewResp.substring(0, dnnViewResp.indexOf("<!DOCTYPE html>"));
var data = JSON.parse(dnnViewResp);
}
但实际上,在 DNN 添加对其他 ActionResult 类型的支持之前,您需要为这些类型的服务创建 WebAPI 服务或处理程序。
你需要像下面那样传递 url 和 headers:
$.ajax({
type: 'post',
url: "/DesktopModules/MVC/YourModuleName/controllerName/actionName",
data: {itemId:JSON.stringify(16)},
headers: {
"ModuleId": @Dnn.ModuleContext.ModuleId,
"TabId":@Dnn.ModuleContext.TabId,
"RequestVerificationToken": $("input[name='__RequestVerificationToken']").val()
},
success: function (data) { ... },
error: function () { ... }
});
=========================================== ==========
并且您必须在模块的根目录中有 RouteConfig.cs 文件,其中包含以下内容才能注册路由:
using DotNetNuke.Web.Mvc.Routing;
namespace Dnn.Modules.YourModuleName
{
public class RouteConfig : IMvcRouteMapper
{
public void RegisterRoutes(IMapRoute mapRouteManager)
{
mapRouteManager.MapRoute("YourModuleName", "YourModuleName", "{controller}/{action}", new[]
{"Dnn.Modules.YourModuleName.Controllers"});
}
}
}
==========================================
但是!!!
在 dnn mvc 模块中使用 ajax 的最佳方式是使用 DnnMvcAjaxHandler 库
那么你可以拥有:
@AjaxHandler.ActionLink(linkText: "delete", actionName: "delete", controllerName: "home", routeValues: new { id = item.Id }, ajaxOption:
new AjaxHandlerOption
{
LoadingElementId = "#global-ajax-loading",
OnConfirm = "are you sure ?",
},
htmlAttributes: new { @class = "btn btn-danger btn-xs" })
我也遇到了困难,在尝试了我在网上找到的所有内容后,最终解决了这个问题的是将 javascript 中的 url 替换为:
@Url.Action("ActionName", "ControllerName", new {SomeParameter = "SomeValue"))
收件人:
dnn.getVar("sf_siteRoot", "/") + "DesktopModules/MVC/ModuleName/Controller/Action"
我的DNN MVC开发之旅又出现了一个问题。我想知道这是否是我犯错的 bug/missing 功能。 我会在下面尝试解释这个问题。
我想达到的目标
我想通过调用 AJAX post 在我的控制器中执行一个动作。到目前为止它有效。 但是,当我尝试 return 一些变量到我的视图时,它不仅 return 变量。它将整个 HTML-source 添加到响应中。
JSON REPONSE
我的控制器
我的方法 return 是一个 ActionResult(我尝试了 JsonResult 和一些不同的东西:HttpResponseMessage 以及)。 该程序本身正在运行并执行 return JSON-消息。
public ActionResult Mark(int itemId)
{
var item = _itemService.GetItem(itemId, ModuleContext.ModuleId);
// Check if item exists
if (item == null)
return Json(new { success = false, Description = "the item you want to vote for does not exist (anymore)" }, JsonRequestBehavior.AllowGet);
// Check if user is voting on his own item
if (item.CreatedByUserId == User.UserID)
return Json(new { success = false, Description = "it is not allowed to vote for your own item" }, JsonRequestBehavior.AllowGet);
我的观点
下面的视图不是我的最终视图,而是为了测试。
$("#button").click(function () {
$.ajax({
type: "POST",
url: "@Url.Action("Mark", "Vote")",
dataType: "json",
data: { itemId: JSON.stringify(16) },
success: function (data) { console.log(data); },
error: function (errMsg) {
responseText = jQuery.parseJSON(errMsg.responseText);
console.log(responseText.Description);
}
});
});
这是一个错误,还是我可以修复的问题?非常感谢您的宝贵时间。 https://dnntracker.atlassian.net/browse/DNN-8522
根据 DNN 关于 Unsupported MVC Features 的文档,目前不支持 ActionResult 以外的任何结果。
我能够在我的一个 MVC 控制器方法中 return JsonResult,它会 return JSON 响应,但是,就像你提到的,附加到它的是 View HTML。我的 hacky 解决方案是解析响应以从中获取我的 json 字符串。
...
success: function (response) {
var dnnViewResp = response.xhr.responseText;
dnnViewResp = dnnViewResp.substring(0, dnnViewResp.indexOf("<!DOCTYPE html>"));
var data = JSON.parse(dnnViewResp);
}
但实际上,在 DNN 添加对其他 ActionResult 类型的支持之前,您需要为这些类型的服务创建 WebAPI 服务或处理程序。
你需要像下面那样传递 url 和 headers:
$.ajax({
type: 'post',
url: "/DesktopModules/MVC/YourModuleName/controllerName/actionName",
data: {itemId:JSON.stringify(16)},
headers: {
"ModuleId": @Dnn.ModuleContext.ModuleId,
"TabId":@Dnn.ModuleContext.TabId,
"RequestVerificationToken": $("input[name='__RequestVerificationToken']").val()
},
success: function (data) { ... },
error: function () { ... }
});
=========================================== ==========
并且您必须在模块的根目录中有 RouteConfig.cs 文件,其中包含以下内容才能注册路由:
using DotNetNuke.Web.Mvc.Routing;
namespace Dnn.Modules.YourModuleName
{
public class RouteConfig : IMvcRouteMapper
{
public void RegisterRoutes(IMapRoute mapRouteManager)
{
mapRouteManager.MapRoute("YourModuleName", "YourModuleName", "{controller}/{action}", new[]
{"Dnn.Modules.YourModuleName.Controllers"});
}
}
}
==========================================
但是!!!
在 dnn mvc 模块中使用 ajax 的最佳方式是使用 DnnMvcAjaxHandler 库
那么你可以拥有:
@AjaxHandler.ActionLink(linkText: "delete", actionName: "delete", controllerName: "home", routeValues: new { id = item.Id }, ajaxOption:
new AjaxHandlerOption
{
LoadingElementId = "#global-ajax-loading",
OnConfirm = "are you sure ?",
},
htmlAttributes: new { @class = "btn btn-danger btn-xs" })
我也遇到了困难,在尝试了我在网上找到的所有内容后,最终解决了这个问题的是将 javascript 中的 url 替换为:
@Url.Action("ActionName", "ControllerName", new {SomeParameter = "SomeValue")) 收件人:
dnn.getVar("sf_siteRoot", "/") + "DesktopModules/MVC/ModuleName/Controller/Action"