问题
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