0

To explain, my initial setup was as follows:

Contollers:
Library => Controllers => ParametersController.cs
Library => Controllers => ReaderLevelController.cs
Library => Controllers => ResourceTypeController.cs

Views:
Library => Views => Parameters => Index.cshtml
Library => Views => ReaderLevel => Index.cshtml
Library => Views => ResourceType => Index.cshtml

Each view referenced its appropriate Model like so:
@model IEnumerable<Library.DAL.PrmTbl_Level>

and each controller contained an ActionResult for Index(), some FormCollections and not much else. The screens displayed fine, and pulled, edited and updated the db no problem.

I wanted to change my views to a more descriptive hierarchy so moved my View files like so:

Views:
Library => Views => Parameters => Index.cshtml
Library => Views => Parameters => ReaderLevel => Index.cshtml
Library => Views => Parameters => ResourceType => Index.cshtml

I then updated the ParametersController.cs file to reflect the new ActionResults that would now be directed toward it, it being the 'parent' file:

    public ActionResult ResourceType() { return View("ResourceType/Index"); }

Now however the new 'sub' screens (ReaderLevel & ResourceType, in this example) do not display, as an error is thrown when a foreach loop tries to run through their relevant Model - which now returns as null. I am confused as to how changing the location of the View file can alter the viability of the data access (as, to my mind, the Model is filled via the ab path @model IEnumerable<Library.DAL.PrmTbl_Level> which does not change).

Can someone explain how changing the View's location affects its accessing of its Controller and Model?

EDIT
My current setup (file structure as above):

ParametersController

public ActionResult Index() {
    ViewBag.Title = "Parameters";
    return View();
}
public ActionResult ResourceType() {
    return RedirectToAction("ResourceType");
}

This gives me the appropriate url, but 'Firefox has detected that the server is redirecting the request for this address in a way that will never complete.' Using the RedirectToAction "ResourceType","Index" resolves to the url '/Index/ResourceType' and the resource cannot be found.

Eamonn
  • 1,338
  • 2
  • 21
  • 53
  • did you want to create subfolders inside the view? – Jameel Moideen Sep 02 '13 at 15:46
  • @JEMI Yes, in that I wanted the ReaderLevel and ResourceType folders inside the Parameter folder in the View tree. – Eamonn Sep 02 '13 at 16:51
  • You have that backwards--it should be RedirectToAction ("Index","ResourceType"). – Phil Sandler Sep 04 '13 at 12:38
  • @PhilSandler if I do that, it tries to reach '~/Views/Shared/Index.cshtml' (which isn't there). If I try `"Index","Parameters/ResourceType"` I get the browser error ("..way that will never complete") again. – Eamonn Sep 04 '13 at 13:10
  • Is it hitting any code in your Resource Type Controller when you code it like I suggested? – Phil Sandler Sep 04 '13 at 14:23
  • @PhilSandler doesnt appear to be - it's like the browser can't find the file. – Eamonn Sep 04 '13 at 14:40
  • I would start by moving your files back to the default locations, and see if you can get things working with MVC's default conventions. If that works, you can then infer that the problem is indeed the directory structure and not some other problem. I am a bit lost on what is going on to be honest--pushing a sample app up to some location (e.g. Dropbox) might be necessary at this point. – Phil Sandler Sep 04 '13 at 14:44
  • Given that it *was* working in the default locations, and would I assume work there again, what is my next move for debugging? I take it that VS *can* have View files in a hierarchical format? – Eamonn Sep 04 '13 at 14:55
  • Yes, it can. What you generally need to do is override the default conventions for locating views, although in the case presented, it seems you *should* be getting around this by specifying the path to the view (which you are already doing, e.g. return View("ResourceType/Index"). The "way that will never complete" error sounds like an infinite loop, and that's what's confusing me. I would set breakpoints in all controller methods and see what is getting hit when. Maybe post all your controller code as well? – Phil Sandler Sep 04 '13 at 17:41

2 Answers2

0

I'm not clear on this line of code:

public ActionResult ResourceType() { return View("ResourceType/Index"); }

Does this mean that you are loading the resource type view from the Parameters controller?

If that's the case, it's not what you want to do. You want to use RedirectToAction.

Edit: you could also supply the model in your existing code using a different View() overload. I assume this isn't what you want, though, since you do have a ResourceTypeController.

Edit #2

Based on your comment,

I then figured that once those sub views were loaded, their own individual controllers would take over?

No, it actually works the other way around. The controller loads the view (and passes the model, if one is required). It looks like you are trying to load the view, and expecting it to load its own controller. Redirect to the proper URL, and the controller will take over.

Phil Sandler
  • 27,544
  • 21
  • 86
  • 147
  • tbh, I'm not clear on that line of code either. I thought any action taking place through the Parameter view would be handled by the Parameter controller, including the links to other views. I then figured that once those sub views were loaded, their own individual controllers would take over? As such, this line is just passing the user on from the Parameter view to the ResourceType view. I'm wrong, obv... – Eamonn Sep 02 '13 at 18:05
  • If you could provide an example of a `RedirectToAction` call, given the circumstances outlined, I'd be grateful - any version I try either throws an exception, or '*Firefox has detected that the server is redirecting the request for this address in a way that will never complete.*' Unfortunately I find the MSDN manual very abstract (for me). – Eamonn Sep 02 '13 at 19:44
  • What is the exception? Try this: return RedirectToAction("ResourceType", "[Method]"); but replace "Method" with the method name on your resourceTypeController (maybe "Index"?). – Phil Sandler Sep 02 '13 at 22:43
  • Apologies for the delay Phil. I have updated my question to reflect what happens when I try this. – Eamonn Sep 04 '13 at 09:41
0

So a few things I'm noticing here:

  1. In the action method you showed above you are not passing a Model to the View, you are simply calling the view. To pass the View a Model you need to supply it as the second argument to the View method, i.e. return View("ResourceType/Index", model);. Also I believe if you are passing a path, instead of just the name of the View, to the View method you need to specify the full path and file extension, i.e. ~/Views/Parameters/ResourceType/Index.cshtml. @Phil Sandler made a good point about using RedirectToAction as well since you are attempting to return a View associated with another Controller.

  2. If you want to change the default View hierarchy than you should consider extending the RazorViewEngine to supplement its search locations with your new directories. Have a look at this question for an example (it uses the WebFormViewEngine but you do the same thing for Razor): Can I specify a custom location to "search for views" in ASP.NET MVC?

  3. Lastly, I don't really understand your new hierarchy. Why are the ReaderLevel and ResourceType Views being placed under the Parameters subdirectory if they don't belong to that Controller? The new hierarchy actually seems more confusing which may make it harder to understand later. Maybe we don't have all the information to understand your decision but it seems odd.

Community
  • 1
  • 1
asymptoticFault
  • 4,491
  • 2
  • 19
  • 24
  • Apologies in my delay in getting back to you - life, etc. The new hierarchy was purely to get a more descriptive url and file structure. *ReaderLevel* and *ResourceType* are parameters, and therefore (to me) should sit within the Parameters directory. Does this mean that their actions should therefore also belong to the Parameter controller? Can they not keep their own? How exactly does a controller 'link' to a view? – Eamonn Sep 04 '13 at 09:24