Umbraco cannot find the route in backoffice

蓝咒 提交于 2019-12-08 13:41:33

问题


I've used Umbraco 7.3 in my project. I created a custom data type but when I want to call a Surfacecontroller in here is HelloSurfaceController or Hello2SurfaceController, I got an error in umbraco backoffice that said Request error: The URL returned a 404 (not found):

I studied some articles about routing but I couldn't solve my problem. I don't know that where I did wrong.

How can I solve this problem?

Reply.controller.js:

angular.module("umbraco")
.controller("Reply.controller", function ($scope, $http) {
    $scope.SendReply = function () {
        var sendTo = $("#Email").val();
        var textMessage = $("#TextMessage").val();

        $scope.xxx = "I'm here!";
        var data = { SendTo: sendTo, TextMessage: textMessage };
        //   ~/Hello2Surface/ReplyMessage  ---> Cannot find this URL
        $http.post("~/App_Plugins/Reply/HelloSurface/ReplyMessage") // Can not find this URL
            .then(function (response) {
                alert("YES!");
                //TODO: 
            });
    }
});

SurfaceController

 namespace Jahan.Nuts.Web.Mvc.UmbracoCms.App.App_Plugins.Reply
 {
    public class HelloSurfaceController : SurfaceController
    {
        [HttpPost][ChildActionOnly]
        public ActionResult ReplyMessage()
        {
            //TODO: how should be write this method that be proper for getting data from angularjs?
            return null;
        }
    }
 }

package.manifest

{
propertyEditors: [
    {
        alias: "Send.Reply",
        name: "Send Reply",
        editor:{
            view:"~/App_Plugins/Reply/Reply.html"
        },
    }
]
,
javascript:[
    '~/App_Plugins/Reply/Reply.controller.js'
]
}

Reply.html

<div ng-controller="Reply.controller">
<div style="width: 100%;">
    <input type="button" value="Send Reply" title="SendReply" name="Send Reply" ng-click="SendReply()" />
</div>
<div>
    <input type="text" ng-model="xxx" name="message" />
</div>

Error in umbraco backoffice:


回答1:


remove the "Surface" from the URL and include "backoffice":

 angular.module("umbraco")
    .controller("Reply.controller", function ($scope, $http) {
        $scope.SendReply = function () {
            var sendTo = $("#Email").val();
            var textMessage = $("#TextMessage").val();

            $scope.xxx = "I'm here!";
            var data = { SendTo: sendTo, TextMessage: textMessage };
            //   ~/Hello2Surface/ReplyMessage  ---> Cannot find this URL
            $http.post("backoffice/Reply/Hello/ReplyMessage") // Can not find this URL
                .then(function (response) {
                    alert("YES!");
                    //TODO: 
                });
        }
    });

Also, I'd recommend using UmbracoAuthorizedController not a surface controller as this is being used in the back end by logged in users it'll be wise to keep it secure.

So instead your controller should look something like this:

[PluginController("Reply")]
namespace Jahan.Nuts.Web.Mvc.UmbracoCms.App.App_Plugins.Reply
 {
    public class HelloApiController : UmbracoAuthorizedJsonController
    {
        public [Model-to-be-returned-to-angular] ReplyMessage()
        {
            //sql query etc to populate model
            //return model
        }
    }
 }



回答2:


Take a closer look at the documentation - in particular the Plugin-based SurfaceControllers section:

https://our.umbraco.org/documentation/Reference/Routing/surface-controllers

try doing this (note the PluginController attribute):

namespace Jahan.Nuts.Web.Mvc.UmbracoCms.App.App_Plugins.Reply
{
    [PluginController("Reply")]
    public class HelloSurfaceController : SurfaceController
    {
        [HttpPost][ChildActionOnly]
        public ActionResult ReplyMessage()
        {
            //TODO: how should be write this method that be proper for getting data from angularjs?
            return null;
        }
    }
 }

Other Notes:

  • You don't need to include "Surface" in the controller name anymore - simply calling it HelloController is enough.
  • Don't use a SurfaceController for Api calls if you're using it with AngularJS - Better to use an UmbracoApiController instead. Check out https://our.umbraco.org/documentation/Reference/Routing/WebApi/ for more information (including notes on where to expect the Api Endpoint to be)
  • You might also want to re-locate your controller so it's in a more conventional spot. There's no problem with putting it in the ~/Controllers directory even if it is a Plugin Controller.

Edit: Added "correct" way to do this:

As noted above, to implement an UmbracoApiController, you want a class looking like this - note you can use UmbracoApiController if you don't need to worry about authorization:

namespace Jahan.Nuts.Web.Mvc.UmbracoCms.App.App_Plugins.Reply
{
    [PluginController("Reply")]
    public class HelloApiController : UmbracoAuthorizedApiController
    {
        public void PostReplyMessage(string to, string message)
        {
            // TODO: process your message and then return something (if you want to).

        }
    }
 }

Then in AngularJS set up a resource like this:

function replyResource($q, $http, umbDataFormatter, umbRequestHelper) {
    var replyResource = {
        sendMessage: function (sendTo, msg) {    
            return umbRequestHelper.resourcePromise(
                           $http.post("Backoffice/Reply/HelloApi/PostReplyMessage?" +
                                umbRequestHelper.dictionaryToQueryString(
                                   [{ to: sendTo }, { message: msg }])),
                           'Failed to send message to ' + sendTo + ': ' + msg);
        }
    };


    return replyResource;
}

angular.module('umbraco.resources').factory('replyResource', replyResource);

and finally your actual view controller can use this as follows:

angular.module("umbraco")
.controller("Reply.controller", function ($scope, $http, $injector) {

    // Get a reference to our resource - this is why we need the $injector specified above
    replyResource = $injector.get('replyResource');

    $scope.SendReply = function () {
        // You really shouldn't use jQuery here - learn to use AngularJS Bindings instead and bind your model properly.
        var sendTo = $("#Email").val();
        var textMessage = $("#TextMessage").val();

        replyResource.sendMessage(sendTo, textMessage)
            .then(function (response) {
               // Success
            }, function (err) {
               // Failure
            });
        }
    };
});

It's possible there's some errors in there; I did it mostly from memory - in particular, you may need to look into the best way to post data to the ApiController - it's not likely that it'll just accept the two parameters like that.

For a more complete example, consider reviewing the code of the Umbraco MemberListView plugin: https://github.com/robertjf/umbMemberListView

Also, you really should read up on the ASP.Net MVC fundamentals and the Umbraco Documentation for SurfaceControllers and APIControllers I've listed above already.



来源:https://stackoverflow.com/questions/33616982/umbraco-cannot-find-the-route-in-backoffice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!