Executing an action by an AJAX request DNN MVC

2020-06-28 03:51发布

问题:

Another problem occured in my DNN MVC development journey. I am wondering whether this is a bug/missing feature of I've made a mistake. I will try to explain the problem below.

What I want to achieve

I want to execute an action in my controller by calling an AJAX post. So far it works. However, when I try to return some variables to my View, it doesn't only return the variables. It adds an whole HTML-source to the response.

JSON REPONSE

My controller

My method returns an ActionResult (I tried JsonResult and something different: HttpResponseMessage as well). The program itself is working and does return the JSON-message.

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);

My View

The View below isn't my final View, but's meant to test.

$("#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);
        }
    });
});

Is this a bug, or something I am able to fix? Thank you very much for your time. https://dnntracker.atlassian.net/browse/DNN-8522

回答1:

According to DNN's documentation on Unsupported MVC Features, any result other than ActionResult isn't currently supported.

I was able to return a JsonResult in one of my MVC controller methods and it would return the JSON response but, like you mentioned, appended to it was the View HTML. My hacky solution was to parse the response to get my json string out of it.

...
success: function (response) {
    var dnnViewResp = response.xhr.responseText;
    dnnViewResp = dnnViewResp.substring(0, dnnViewResp.indexOf("<!DOCTYPE html>"));
    var data = JSON.parse(dnnViewResp);
}

But really, you need to create a WebAPI service or handler for these types of services until DNN adds support for other ActionResult types.



回答2:

you need to pass url and headers like bellow:

$.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 () { ... }

});

=======================================================

and you must have RouteConfig.cs file in root of Module with following content to register route :

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"});

}

}

}

==========================================

But !!!

best way to work with ajax in dnn mvc modoule is use of DnnMvcAjaxHandler library

then you can have :

@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" })


回答3:

I have been having a hard time with this too, what finally resolved the issue after trying everything I found on the web was to replace the url in the javascript from:

@Url.Action("ActionName", "ControllerName", new {SomeParameter = "SomeValue"))​ To:

dnn.getVar("sf_siteRoot", "/") + "DesktopModules/MVC/ModuleName/Controller/Action"​

share | improve this answer | |