Answers.Body: <p>Craft 3 action routes are <code>snake-case</code> rather than <code>camelCase</code> thus your route needs to be <code>plugin-handle/controller-handle/function-name</code> instead of <code>pluginHandle/controllerName/functionName</code></p>
  
  <p>Your Controllers namespace must be <code>prefix\namespace\name\controllers</code> so in your case it could be <code>kr37\drycalendar\controllers</code> not Craft.</p>
  
  <p>Furthermore you don't need to include your plugin name to the classname anymore. Your controller name can be</p>
  
  <p><code>CalendarOccurrencesFieldController</code></p>
  
  <p>Your action will then be <code>drycalendar/calendar-occurrences-field/generate-ajax-mini-calendar</code></p>
  
  <p>Keep in mind you'll have to create <a href="https://craftcms.stackexchange.com/questions/26454/resolving-the-entry-variable-for-custom-routes-somewhere-but-a-twig-template/26455#26455">routes</a> of you don't use the <a href="https://docs.craftcms.com/v3/changes-in-craft-3.html#action-params" rel="nofollow noreferrer">action</a> parameter in your request. Currently you are trying to access your controller via cp/site route, not via action route</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-13T05:40:52.710Z
Answers.Text: Snake-case-was-it, thank you! I think, Robin, that you are rewriting my plugin for me. Very kind.
Answers.UserDisplayName: kr37
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-06-12T18:30:05.763Z
Answers.LastActivityDate: 2018-06-12T18:35:06.510Z
Answers.LastEditDate: 2018-06-12T18:35:06.510Z
Answers.UserDisplayName: Robin Schambach
Body: <p>Updating a plugin to Craft 3 (also changed its name). I know this is probably something very simple, like capitalization, but can anyone point out what's wrong?</p>
  
  <p>Firefox console shows a 404 for<br>
  <code>http://f.test/index.php?p=admin/actions/dryCalendar/calendarOccurrencesField/generateAjaxMiniCalendar</code><br>
  and then<br>
  <code>Type error: Response is null</code></p>
  
  <p>So perhaps Craft is getting the request, but <code>$this-&gt;returnJson($response);</code> isn't terminating the request, i.e. Craft continues to try to find a page to match?</p>
  
  <p>My files are set up like this:</p>
  
  <pre><code>DryCalendar.php
  controllers/DryCalendar_CalendarOccurrencesFieldController.php
  </code></pre>
  
  <p>is </p>
  
  <pre><code>&lt;?php
  namespace Craft;
  //namespace kr37\drycalendar\controllers;
  use Craft;
  use craft\base\Controller;
  class DryCalendar_CalendarOccurrencesFieldController extends BaseController
  {
      public function actionGenerateAjaxMiniCalendar() {
          ...
          $this-&gt;returnJson($response);    
      }   
  }
  </code></pre>
  
  <p>and in my Garnish js is</p>
  
  <pre><code>Craft.postActionRequest(                   
      'dryCalendar/calendarOccurrencesField/generateAjaxMiniCalendar', 
      data, 
      function(response) {
           ...
      });
  </code></pre>
  
  <p>Thanks for any help!</p>
  
Tags: <plugin-development><craft3><controller><404>
Title: Craft 3 Controller giving 404
ThreadText: # Craft 3 Controller giving 404
  
  (Asked by: username_0 on 2018-06-12)
  
  Updating a plugin to Craft 3 (also changed its name). I know this is probably something very simple, like capitalization, but can anyone point out what's wrong?
  
  Firefox console shows a 404 for  
  `http://f.test/index.php?p=admin/actions/dryCalendar/calendarOccurrencesField/generateAjaxMiniCalendar`  
  and then  
  `Type error: Response is null`
  
  So perhaps Craft is getting the request, but `$this->returnJson($response);` isn't terminating the request, i.e. Craft continues to try to find a page to match?
  
  My files are set up like this:
  
  ```
  DryCalendar.php
  controllers/DryCalendar_CalendarOccurrencesFieldController.php
  
  ```
  
  is
  
  ```
  <?php
  namespace Craft;
  //namespace username_0\drycalendar\controllers;
  use Craft;
  use craft\base\Controller;
  class DryCalendar_CalendarOccurrencesFieldController extends BaseController
  {
      public function actionGenerateAjaxMiniCalendar() {
          ...
          $this->returnJson($response);    
      }   
  }
  
  ```
  
  and in my Garnish js is
  
  ```
  Craft.postActionRequest(                   
      'dryCalendar/calendarOccurrencesField/generateAjaxMiniCalendar', 
      data, 
      function(response) {
           ...
      });
  
  ```
  
  Thanks for any help!
  
  **Tags:** plugin-development, craft3, controller, 404
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2018-06-12. Score: 4 | Accepted answer
  
  Craft 3 action routes are `snake-case` rather than `camelCase` thus your route needs to be `plugin-handle/controller-handle/function-name` instead of `pluginHandle/controllerName/functionName`
  
  Your Controllers namespace must be `prefix\namespace\name\controllers` so in your case it could be `username_0\drycalendar\controllers` not Craft.
  
  Furthermore you don't need to include your plugin name to the classname anymore. Your controller name can be
  
  `CalendarOccurrencesFieldController`
  
  Your action will then be `drycalendar/calendar-occurrences-field/generate-ajax-mini-calendar`
  
  Keep in mind you'll have to create [routes](https://craftcms.stackexchange.com/questions/26454/resolving-the-entry-variable-for-custom-routes-somewhere-but-a-twig-template/26455#26455) of you don't use the [action](https://docs.craftcms.com/v3/changes-in-craft-3.html#action-params) parameter in your request. Currently you are trying to access your controller via cp/site route, not via action route
  
  > **Comments:**
  > **username_0**: Snake-case-was-it, thank you! I think, username_1, that you are rewriting my plugin for me. Very kind.  
  
  ---
  
  