【问题标题】:Umbraco cannot find the route in backofficeUmbraco 在后台找不到路由
【发布时间】:2016-02-10 13:30:16
【问题描述】:

我在我的项目中使用了 Umbraco 7.3。我创建了一个自定义数据类型,但是当我想在这里调用Surfacecontroller 时是HelloSurfaceControllerHello2SurfaceController,我在umbraco 后台收到了一个错误,上面写着Request error: The URL returned a 404 (not found):

我研究了一些关于路由的文章,但我无法解决我的问题。我不知道我哪里做错了。

我该如何解决这个问题?

回复.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: 
            });
    }
});

表面控制器

 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'
]
}

回复.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>

umbraco 后台错误:

【问题讨论】:

    标签: asp.net-mvc-routing umbraco angularjs-routing umbraco7


    【解决方案1】:

    仔细查看文档 - 特别是基于插件的 SurfaceControllers 部分:

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

    尝试这样做(注意PluginController 属性):

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

    其他说明:

    • 您不再需要在控制器名称中包含“Surface” - 只需将其称为 HelloController 就足够了。
    • 如果您将 SurfaceController 与 AngularJS 一起使用,请勿将其用于 Api 调用 - 最好使用 UmbracoApiController。查看https://our.umbraco.org/documentation/Reference/Routing/WebApi/ 了解更多信息(包括关于 Api 端点的预期位置的注释)
    • 您可能还想重新定位控制器,使其位于更传统的位置。即使是Plugin Controller,放在~/Controllers目录下也没有问题。

    编辑:添加了“正确”的方法:

    如上所述,要实现 UmbracoApiController,您需要一个如下所示的类 - 请注意,如果您不需要担心授权,则可以使用 UmbracoApiController:

    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).
    
            }
        }
     }
    

    然后在 AngularJS 中设置这样的资源:

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

    最后你的实际视图控制器可以按如下方式使用它:

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

    其中可能有一些错误;我主要是凭记忆做的 - 特别是,您可能需要研究将数据发布到 ApiController 的最佳方式 - 它不太可能只接受这样的两个参数。

    如需更完整的示例,请考虑查看 Umbraco MemberListView 插件的代码:https://github.com/robertjf/umbMemberListView

    另外,您真的应该阅读上面已经列出的 ASP.Net MVC 基础知识和 SurfaceControllers 和 APIControllers 的 Umbraco 文档。

    【讨论】:

    • 您能更正我的代码吗?如果可以,请这样做,因为我已经尝试过,但我没有得到好的结果。我很迷惑!我收到错误 404
    • 非常感谢。我认为您是对的,但您的答案似乎很复杂!也许是因为我是 Umbraco 7 和 Angularjs 中的小说!我必须更多地研究Angularjs。幸运的是,@MNelmes 给出了一个简单的答案。无论如何,谢谢。
    【解决方案2】:

    从 URL 中删除“Surface”并包含“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: 
                    });
            }
        });
    

    另外,我建议使用 UmbracoAuthorizedController 而不是表面控制器,因为登录用户在后端使用它,保持安全是明智之举。

    因此,您的控制器应如下所示:

    [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
            }
        }
     }
    

    【讨论】:

    • 如果我想将一个对象传递给ReplyMessage() 方法,我该怎么做?例如我们有 public ActionResult ReplyMessage(SendMailViewModel vm) {}
    猜你喜欢
    • 1970-01-01
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    相关资源
    最近更新 更多