The controller for path '/api/sitecore/TestForms/TestFormsAPI' was not found or does not implement IController - sitecore8

I am creating a controller and inheriting GlassController, I am trying to call controller action method using ajax and the URL requested is '/api/sitecore/TestForms/TestFormsAPI' and it throws an exception saying "The controller for path '/api/sitecore/TestForms/TestFormsAPI' was not found or does not implement IController."
Attached are the screen shot of my code and exception:
Can anyone suggest what could be the issue?

Sitecore has a different way of routing. This may be conflicting with the default Sitecore Client route. Implement this using custom route. Follow this link - https://kb.sitecore.net/articles/700677
I shall also suggest to use Route attribute instead and this is how it can be done. (I havent tested following code)
[RoutePrefix("api/Custom")]
public class MyCustomController : ApiController
{
ICustomRepository _customRepository;
public MyCustomController(ICustomRepository _customRepository
{
_customRepository= customRepository
}
[Route("GetCustomMethod")]
[HttpPost]
public IHttpActionResult GetCustomMethod()
{
......
......
return Ok(results);
}
}

Had the custom route registered as in the article in sandy's answer (https://kb.sitecore.net/articles/700677), however it kept crashing with the same error because I included "Controller" when specifying the controller name, removing it fixed the issue (see https://stackoverflow.com/a/41901846/712700).

Related

Sitecore DI with Unity

I'm trying to setup a brand new Sitecore 7.2 website and I'm looking to integrate MVC 5, Glass Mapper and Microsoft Unity as a DI container and Sitecore doesn't want to play very nice.
My scenario is this:
Got a Web project called PoC.Quotes.Web - this will contain only CSS, HTML and any other assets, no controllers
Got a class library project called PoC.Quotes.Controllers - this only contains controllers
Got a class library project called PoC.Quotes.DataLayer - this contain a interface ISitecoreRepository and it's concrete implementation SitecoreRepository
The SitecoreRepository class has a constructor that receives 1 single parameter, the Glass Mapper Context, and one of my controllers receives 1 single parameter in the constructor...the ISitecoreRepository.
Sitecore repository class:
public class SitecoreRepository : ISitecoreRepository
{
ISitecoreContext sitecoreContext = null;
public SitecoreRepository(ISitecoreContext context)
{
this.sitecoreContext = context;
}
}
Controller class:
public class HomeController : Controller
{
private ISitecoreRepository _repository;
public HomeController(ISitecoreRepository repository)
{
this._repository = repository;
}
}
Every time I run the project Sitecore throws an error saying that it cannot create a controller of type (PoC.Quotes.Controllers.HomeController, PoC.Quotes.Controllers). I guess it shows the fully qualified name because that's how I set it up in the controller rendering.
First problem is the controller constructor parameter. I took it out and use this statement to get the instance for the repository:
System.Web.Mvc.DependencyResolver.Current.GetService<ISitecoreRepository>();
The result is null, because the class SitecoreRepository is only having 1 constructor with 1 parameter and it won't get instantiated. Once I get that parameter out of the question too, then all works great.
However, to me this kinda defies the purpose of having a DI container.
I've tried looking at Castle Windsor, but although there is more documentation online, nothing works as I'm getting similar issues.
It is a bit annoying because if I run a similar test in a basic MVC 5 app (I did that just to be sure I'm not going mad), all works fine in less than 5 minutes.
Any ideas?
Edit:
In an interesting twist, after a few good hours spent on this issue, I've noticed that actually either Unity or Windsor containers work fine with one limitation...a big one.
In my controller rendering I've set the controller property as the fully qualified name of the controller:
PoC.Quotes.Controllers.HomeController, PoC.Quotes.Controllers
However, if I go in Sitecore and change that property to just Home, by magic all is good. I've even tried the interim version of using PoC.Quotes.Controllers.Home but still get an error, a different one mind you.
Not sure if I'm doing something wrong but it feels a bit odd.
Any ideas how to get this fixed?
While I can't tell how your registrations are configured, it sounds like you might be better off with a controller factory. The example is Windsor but you could easily swap in Unity. So that you're not modifying the Global.asax, you can also use WebActivatorEx to wire up the bootstrapping startup.
Bootstrapper
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Site.Website.Cms.WindsorConfig), "RegisterComponents")]`
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(Site.Website.Cms.WindsorConfig), "ReleaseComponents")]
/// <summary>
/// Provides a bootstrapping and resolving hook for dependency resolution for MVC, Web API, and service locator.
/// </summary>
public static class WindsorConfig
{
private static Lazy<IWindsorContainer> _container;
static WindsorConfig()
{
_container = new Lazy<IWindsorContainer>(() => BuildContainer());
}
public static IWindsorContainer WindsorContainer
{
get
{
return _container.Value;
}
}
/// <summary>
/// Generates and configures the container when the application is started.
/// </summary>
public static void RegisterComponents()
{
ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(WindsorContainer));
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new WindsorControllerActivator(WindsorContainer));
}
/// <summary>
/// Disposes of the container when the application is shut down.
/// </summary>
public static void ReleaseComponents()
{
WindsorContainer.Dispose();
}
}
Controller Factory
/// <summary>
/// Provides controller dependency resolving for ASP.NET MVC controllers.
/// </summary>
public class WindsorControllerFactory : DefaultControllerFactory
{
private readonly IWindsorContainer _container;
public WindsorControllerFactory(IWindsorContainer container)
{
if (container == null) throw new ArgumentNullException("container");
this._container = container;
}
public override void ReleaseController(IController controller)
{
this._container.Release(controller);
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType == null)
{
throw new HttpException(404, string.Format("The controller for path '{0}' could not be found.", requestContext.HttpContext.Request.Path));
}
return (IController)this._container.Resolve(controllerType);
}
}
Spent a considerable amount of time on this and managed to come up with a solution. It was a bit long to write in here so I've put it on a blog post http://agooddayforscience.blogspot.co.uk/2015/10/sitecore-multi-tenancy-and-di-containers.html
Basically it wasn't an issue with Unity or other DI container, it was around how Sitecore handles fully qualified names. Yes, I know that ideally you don't want to use those but to follow the MVC pattern, but I've explained more in the blog post around why use fully qualified names.
As a high level explanation the problem resides in 2 Sitecore classes ControllerRunner and SitecoreControllerFactory. Both classes contain some methods that identify the fully qualified name and use reflection to call the parameter-less constructor to instantiate a new instance. The fix I've applied overrides these methods to call the controller factory regardless.
Thanks for all the help provided.
Andrei

Ember App Kit: Controller without Route is not recognized?

as I mentioned in several questions here I am migrating an already existing and running Ember project to use Ember App Kit and I ran into several problems... here's another "problem" which wasn't a problem before :)
I've got a NotificationCollectionController which is placed under app/controllers/notification/collection.js.
file 'app/controllers/notification/collection.js':
export default Ember.ArrayController.extend({
addNotification: function (options) {
// some code
},
notifyOnDOMRemove: function (notification) {
this.removeObject(notification);
}
});
As this is the controller for notifications which are rendered through a named outlet I didn't declare a route for it.
Within my ApplicationRoute I want to access this controller within a function
file: 'app/routes/application.js'
import BaseRoute from 'appkit/routes/base';
export default BaseRoute.extend({
addGlobalNotificationCollection: function () {
var controller = this.controllerFor('notificationCollection');
// some more code...
}
});
But as soon as the application starts and this piece of code gets called I traced down the following error:
"Assertion Failed: The controller named 'notificationCollection' could
not be found. Make sure that this route exists and has already been
entered at least once. If you are accessing a controller not
associated with a route, make sure the controller class is explicitly
defined."
What does it mean and why is it thrown? What do I have to do to make it run again?
I didn't recognize that the hint is already given at the Naming Conventions section of the Ember App Kit Webpage:
It says, that the naming convention for a Controller is, for example: stop-watch.js
And if it’s a route controller, we can declare nested/child controllers like such:
app/controllers/test/index.js
So I placed my NotifcationCollectionController in controllers/notification-collection.js and call it like Route#controllerFor('notification-collection') and everything works as expected :)

ServiceStack View/Template control when exception occurs?

I added some razor views and use a request filter to check browser version and switch between desktop and mobile views. But when a exception occurs, especially validation exception, it seems the framework return immediately and never touched any custom code. I tried request/response filter, service exception handler, none got executed. It seems to ignore view/template specified in URL query string as well.
Is there way to set view/template during exception? Thanks
The first question is how are you handling validation exceptions?
the most common procedure to perform this kind of task is by using the fluentValidation, the response can return a message for more than one validation at the time, all the validations are against DTOs and you´ll need to implement an AbstractValidator, the first thing you need to do is to register the validators that belons to your applciation like the following:
Plugins.Add(new ValidationFeature());
container.RegisterValidators(typeof(CredentialsAuthValidator).Assembly);
I´m valdiating in this case that the Auth username and password should not be Empty, take a look to the following example:
public class CredentialsAuthValidator : AbstractValidator<ServiceStack.ServiceInterface.Auth.Auth>
{
public CredentialsAuthValidator()
{
RuleSet(ApplyTo.Post, () =>
{
RuleFor(x => x.UserName).NotNull().WithMessage("Username Required").When(x => x.provider == "Credentials");
RuleFor(x => x.Password).NotNull().WithMessage("Password Required").When(x => x.provider == "Credentials");
}
);
}
}
if some of the validation fails you´ll get a responseStatus from the server with the errorCode and the messages.
You can configure a custom httpHandlers in the case you would like to have a handler for specific scenarios or a global error handler, this can be performed in your serviceHost configuration, something like this:
GlobalHtmlErrorHttpHandler = new RazorHandler("/views/error"),
CustomHttpHandlers =
{
{HttpStatusCode.NotFound, new RazorHandler("/views/notfound")},
{HttpStatusCode.Unauthorized, new RazorHandler("/views/login")},
{HttpStatusCode.Forbidden, new RazorHandler("/views/forbidden")},
}
Thanks for the help from Pedro, and especially mythz from ServiceStack. Now I think I start to understand my problems.
ServiceStack is first and foremost a service framework and Razor is just another view over the same result. But I was a little hesitate with a full on client side solution and keep falling back to familiar territory and looking for some kind of code-behind feature. That seems to be the root of lots of my struggles.
After some more research, this is what I come up so far.
ServiceStack for service, of course.
Razor view to build the basic layout and the main page for each major feature
Build a json script tag from model to hold initial data, like in SS's HTML Report
Jquery and Eldarion ajax for all subsequent in-page processing
Handlebars for javascript templating
Verifyjs for validation
So far look promising. Pages are lot smaller in size, running super smooth and mostly pure json flying over the wire.
Still a work in progress, all suggestions welcome.
ViewSwitch works when I changed to use Request Filter instead. Got the correct layout and all the references, etc. Although they have to share the same error page, but there's not much formatting in there.

asmx web service and IoC

I register components in global.asax.I resolve in try block in every web method and release in finally block. I created a wrapper for container so that it is called directly only during registration. Web methods call this wrapper to resolve and release components. This try finally adds a lot of boilerplate code.
Am I doing right? If not how should I do it? I am using Castle Windsor.
[WebMethod]
public void SomeMethod()
{
ISomeComponent c = null
try
{
c = myContainer.ResolveSomeComponent();
c.Method();
}
finally
{
myContainer.Release(c);
}
}
I have found the solution. As it turns out I can configure my components as Per Web Request and then I don't have to release them because they will be automatically released at the end of request.
You can find details in this article: http://devlicio.us/blogs/krzysztof_kozmic/archive/2010/08/27/must-i-release-everything-when-using-windsor.aspx

Reference model in template beyond request / page scope, in Play! 1.2.4

I came across at this thread, does anybody know how to do this in Play! 1.2.4? Thanks.
The same effect is not quite possible, I think. You can of course reference classes in your Models package by using fully qualified names (models.YourModel) to access enumerations, for example.
Anything you add in the renderArgs scope in your controller will be available in the template, plus there are some implicit objects that are always in use (see Play framework documentation for full listing). For example the play.Play object contains all kinds of useful stuff.
With #Before and #With annotations you can set up a controller used by multiple other controllers to have objects "globally" available - see Interceptions.
Even better, create a super controller extending Controller. Afterwards, let all your controllers extends your SuperController.
class SuperController extends Controller {
#Before
public static function before() {
// Set global variables using renderArgs
}
}
class MyController extends SuperController {
public function myMethod() {
// Do whatever your method does.
}
}
Check out the documentation : http://www.playframework.org/documentation/1.2.4/controllers#result