I'm trying to make a simple table pulling from a custom table in the SQL CE Umbraco.sdf. I'm new to MVC so this may be an issue in my understanding or implementation of it.
I've looked through almost all of the related problems on the forum and still can't seem to understand it.
Sometimes the problem seems to be between @model and @inherits? I'm using the PureLive models of Models Builder. I've tried to make my model inherit from RenderModel, and that just says the RenderModel doesn't contain a constructor for 0 arguments, so I'm not sure that's the direction I'd want to go (or even when it would be).
Can someone explain why this error occurs and how I might fix it?
The exception thrown
Umbraco.Web.Mvc.ModelBindingException: Cannot bind source type USNStarterKit.USNModels.USNBaseViewModel to model type System.Collections.Generic.IEnumerable`1[[AnviPayorListViewModel, App_Code.mvefwepm, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]].
My ViewModel
public class AnviPayorListViewModel
{
public string PayorID { get; set;}
public string PayorName { get; set;}
}
My Controller
using System.Web.Mvc;
public class AnviPayorListController : Umbraco.Web.Mvc.SurfaceController
{
[System.Web.Http.HttpGet]
public ActionResult GetPayors()
{
//Connect to custom table DB
var db = ApplicationContext.DatabaseContext.Database;
//Get list of payors to iterate over
var payors = db.Fetch<AnviPayorListViewModel>("SELECT * FROM Payors");
//return PartialView("USNForms/AnviPayorResults", AnviPayorListViewModel);
return PartialView(payors);
}
}
The problem here I think is in your main view where you have
@Html.Partial("USNListings/GetPayors")
Essentially as no model is specified, the model of the current view 'USNStarterKit.USNModels.USNBaseViewModel' is sent to the Partial View
which is expecting a model of type: IEnumerable
So in your main view, you need to write out the results of your surface controller action (which will then send the correct model to the partial view)
In MVC you do this by using Html.Action, and passing in the controller name, and action name you want to call, (and any optional route parameters)
eg
@Html.Action("AnviPayorList". "GetPayors")
(you should also decorate your GetPayors ActionResults with [ChildActionOnly] to prevent it being requested directly via Url.)
Changing the @Html.Partial to @Html.Action("GetPayors","AnviPayorList") did the trick for getting past that binding source type to model error, straight into a different exception for the same line.
System.Web.HttpException: The controller for path '/payor-list/' was not found or does not implement IController.
From what I can tell it has to do with either the namespace of the controller as with
this forum post or the "area" of the controller as with this stackoverflow post. Now neither of these really makes sense to me. The Controllers file can't be in the App_Data folder? Plus if I try that it can't find my GetPayors partial view.
Couple of things to check, the HttpGet declaration you have is from the System.Web.Http namespace, which is used when creating Web Api controllers... when decorating an action in a surface controller you need to use the HttpGet class from the System.Web.Mvc namespace, eg [System.Web.Mvc.HttpGet]
but that is a little 'by the by' as you don't intend to make a web request to this action result, you only want to call this in your template using Html.Action.
Therefore the actionresult should be decorated with [ChildActionOnly]
So:
replace
[System.Web.Http.HttpGet]
public ActionResult GetPayors()
{
with
[ChildActionOnly]
public ActionResult GetPayors()
{
and let's see if we can move on again to a different error :-P
Ahh okay I think I understand what you're saying about the HttpGet. Sad to say after I replaced it, the same exception didn't go away.
In case this will help I'll include the hierarchy:
I have spun up a copy of Umbraco 7.11 and I have added a 'AnviPayorListController to the App_Code folder:
and then in my view I write out the action like so:
When I visit the page, I hit the 'breakpoint' in the GetPayors() method successfully!
If you are not using Visual Studio and can't set a breakpoint to debug - see that I'm returning a Content("<h2>hello world</h2>") message!
What would be interesting to know is if you are able to do the same, eg write out in the view the Html.Action to call the Surfacecontroller action, and hit a breakpoint within the actionresult or return the simple hello world message - just to confirm all is wired up correctly on the controller-actionfront, and therefore that the error you now have is connected with the implementation of the Partial View.
Cannot bind source type to model type
I'm trying to make a simple table pulling from a custom table in the SQL CE Umbraco.sdf. I'm new to MVC so this may be an issue in my understanding or implementation of it.
I've looked through almost all of the related problems on the forum and still can't seem to understand it.
Sometimes the problem seems to be between @model and @inherits? I'm using the PureLive models of Models Builder. I've tried to make my model inherit from RenderModel, and that just says the RenderModel doesn't contain a constructor for 0 arguments, so I'm not sure that's the direction I'd want to go (or even when it would be).
Can someone explain why this error occurs and how I might fix it?
The exception thrown
My ViewModel
My Controller
My PartialView (GetPayors.cshtml)
My Main View
Hi Kevin
The problem here I think is in your main view where you have
@Html.Partial("USNListings/GetPayors")
Essentially as no model is specified, the model of the current view 'USNStarterKit.USNModels.USNBaseViewModel' is sent to the Partial View which is expecting a model of type: IEnumerable
So in your main view, you need to write out the results of your surface controller action (which will then send the correct model to the partial view)
In MVC you do this by using Html.Action, and passing in the controller name, and action name you want to call, (and any optional route parameters)
eg
@Html.Action("AnviPayorList". "GetPayors")
(you should also decorate your GetPayors ActionResults with [ChildActionOnly] to prevent it being requested directly via Url.)
Anyway see
https://our.umbraco.com/documentation/reference/templating/mvc/child-actions
for more background info.
but switching the Html.Partial for Html.Action should resolve your issue.
regards
Marc
Thanks for responding!
Changing the
@Html.Partial
to@Html.Action("GetPayors","AnviPayorList")
did the trick for getting past that binding source type to model error, straight into a different exception for the same line.System.Web.HttpException: The controller for path '/payor-list/' was not found or does not implement IController.
From what I can tell it has to do with either the namespace of the controller as with this forum post or the "area" of the controller as with this stackoverflow post. Now neither of these really makes sense to me. The Controllers file can't be in the App_Data folder? Plus if I try that it can't find my GetPayors partial view.
Hi Kevin
Couple of things to check, the HttpGet declaration you have is from the System.Web.Http namespace, which is used when creating Web Api controllers... when decorating an action in a surface controller you need to use the HttpGet class from the System.Web.Mvc namespace, eg [System.Web.Mvc.HttpGet]
but that is a little 'by the by' as you don't intend to make a web request to this action result, you only want to call this in your template using Html.Action.
Therefore the actionresult should be decorated with [ChildActionOnly]
So:
replace
with
and let's see if we can move on again to a different error :-P
Hey Marc,
Ahh okay I think I understand what you're saying about the HttpGet. Sad to say after I replaced it, the same exception didn't go away. In case this will help I'll include the hierarchy:
-UmbracoWebAnvi
--App_Code
---USN Controllers
----AnviPayorListController.cs
---USNModels
----AnviPayorListViewModel.cs
--Views
---Partials
----USNListings
-----GetPayors.cshtml
---AnviPayorSearchPage.cshtml
Thank you helping me out!
Hi Kevin
Which version of Umbraco are you using?
I have spun up a copy of Umbraco 7.11 and I have added a 'AnviPayorListController to the App_Code folder:
and then in my view I write out the action like so:
When I visit the page, I hit the 'breakpoint' in the GetPayors() method successfully!
If you are not using Visual Studio and can't set a breakpoint to debug - see that I'm returning a
Content("<h2>hello world</h2>")
message!What would be interesting to know is if you are able to do the same, eg write out in the view the Html.Action to call the Surfacecontroller action, and hit a breakpoint within the actionresult or return the simple hello world message - just to confirm all is wired up correctly on the controller-actionfront, and therefore that the error you now have is connected with the implementation of the Partial View.
regards
Marc
Hey Marc,
I'm using Umbraco 7.10.4.
I've placed the breakpoint, gone to the page, and I have not successfully hit my breakpoint. Here are some pictures.
In my AnviPayorListController.cs:
In my AnviPayorListSearchPage.cshtml:
Still lost at what's going on. Hopefully sometime in the future this trouble may end up helping someone else.
Hi Kevin
Just a thought, wondering if there is another version of the AnviPayorListController cached or somewhere else in your project...
... straws clutching...
Can you try to rename your surface controller to
AnviPayorList2Controller
and update your Html.Action to be
@Html.Action("GetPayors","AnviPayorList2")
???
regards
Marc
Still no dice on the change after the AnviPayorList2Controller and Html.Action update.
Same exception. Same controller path '/payor-list/' (the link assigned in the info tab of the backoffice) was not found.
Hi Kevin
Do you have a namespace for the surface controller?
regards
Marc
is working on a reply...