I am developing an MVC solution and I want to have a plugin option for some partial views I am creating. I have separate assembly for each plugin that contains the PartialView as an embedded resource and the viewmodel class that it references. I use a virtualfile provider to find the required PartialView and this works great...until I try to use the ViewModel for the partial.
To render the partial view, I have two properties in the Model that get set at runtime depending on the option chosen...so I use the following:
Html.RenderPartial(Model.PartialViewName, Model.PartialViewModel)
where Model.PartialViewModel is an interface that all the view models in the separate assemblies implement.
I get the following error when the partial view is rendering: error CS1061 'object' does not contain a definition for '{PropertyName}' and no extension method '{PropertyName}' accepting a first argument of type 'object' could be found..." This error occurs for whatever property on the partial viewmodel I'm trying to access.
However, when in debug mode, I can see the viewmodel that has been passed to the partial view and it is correct and all the properties are there and populated. I have even went so far as to remove the plugin-ness and just reference the named classes and types (instead of interfaces) and I still get this error.
Any ideas? Anyone been able to put a partial view and its viewmodel in a separate assembly and get it to work? Thank you.
Related
I have a small confusion in Asp.Net MVC
How rendering works in Asp.net MVC? We invoke View function - > Which will find the view and ask ViewEngine to parse it. Because of ViewEngine final outcome is HTML.
1)Whatever ViewData we create its available inside View. My understanding is ViewData and View function both are part of controller base class which makes ViewData available inside View function. Is it correct?
2)Finally Whats the point with WebViewPage class. ViewData keyword we use inside View(.cshtml) page is coming from the WebViewPage class. What role WebViewPage plays here.
I will really appreciate If you can point me with some good resource to understand the same
1) ViewData is merely a dictionary of objects that you can fill in the Controller and retrieve within the view. Since it is a dictionary of objects you need to cast the data back into the type it was to make full use of it.
2) WebViewPage is the base type of a razor page. It is the defined class which razor pages are compiled into at runtime. The web.config inside the views folder specifies the pageBaseType of the razor pages specifically to WebViewPage. These are two good resources regarding why its use and how you can extend it. Link1 and Link2.
Go peek inside he source code that renders the views
visit msdn
I would like to use the generic razor helper function Html.Partial to render views that have common html in them.
For instance, I have two views set up in Sitecore Payment Information.cshtml and Agent Payment Information.cshtml. These are rendered using the Sitecore rendering engine. Both of these views have very similar html in them that I would like to put in razor views not set in Sitecore and call them with #Html.Partial as appose to #Html.Sitecore().Rendering() as the latter forces me to set up a view and model in Sitecore which I am not sure is necessary.
My question is, is there anything that Sitecore does behind the scenes that makes it necessary to usethe #Html.Sitecore().Rendering() helper method instead of the #Html.Partial() helper method? Everything seems to work fine and I believe the entire view should get cached since the #Html.Partial call is nested inside either the Payment Information view or the Agent Payment information view set up in Sitecore.
Thanks in advance.
I have Html.Partial working in an MVC solution using Glass for ORM. There are two ways I've used this, one where the assumed model being passed to the partial is the same as the parent rendering and another where we create the model on the fly.
Assumes parent rendering model is passed:
#Html.Partial("~/Views/Components/MyPartialView.cshtml")
Instantiates a new model that is passed in:
#Html.Partial("~/Views/Components/Navigation/SecondaryNavigationRendering.cshtml", new SecondaryNavigation())
The parent view will need to have a mapped model in Sitecore. The secondary view does not have a mapped model in Sitecore but is typed to receive the model being passed (so in my first example that would be my IBasePage model, in my second it would be my SecondaryNavigation model).
Hope this helps.
I'm using Umbraco 6, and am using the new MVC architecture. I have a document type view template, which has a view model, which is instantiated and has it's properties populated from the controller. One of these properties is a collection, and in the view template I iterate through the collection and render out a Partial View with a separate view model, using 'Html.Partial("partialName", modelObject)'
The weird problem I'm having is that firstly, in Visual Studio I get a ReSharper warning telling me that it cannot resolve a partial view with that name (I have checked 50 times and I've spelt it correctly). Additionally when I then navigate to the page, I get the trusty ol' "Object reference not set to an instance of an object" YSOD.
I have debugged the code, and the controller action is hit fine, the logic to instantiate the view model for the document type template works fine, and populates the properties correctly, I've also made sure the properties are still set inside the view and the loop for rendering out the collection items correctly instantiates a view model object per collection item and sets the properties correctly. It breaks when it hits the Html.Partial.
Document Type View Code below:
#foreach (KeyValuePair<decimal, IPublishedContent> result in Model.Results)
{
PropertySearchResultViewModel model = ObjectMapper.SearchResultToViewModel(result);
Html.RenderPartial("PropertySearchResultDesktop", model);
}
Partial View Code below:
#using Production.Umbraco.Extensions.Models.ViewModels;
#inherits UmbracoViewPage<PropertySearchResultViewModel>
<article id="property-result-#Model.Node.Id.ToLower()">
<p>#Model.Node.Name</article>
<p>Distance: #Model.Distance Miles</p>
</article>
Here is a screenshot of my VS Solution tree:
The 'NewHomes.cshtml' document type view template is returned from the NewHomesController and the view is calling the 'PropertySearchResultDesktop.cshtml' partial view, which was created from the Umbraco back office, and was placed their automatically.
The Umbraco website says that you can and should place your partial views here
http://our.umbraco.org/Documentation/Reference/Mvc/partial-views
But no matter what I try to do, it just wont render the partial. I've seen one other question about this on SO but the answer was just to place it in MacroPartials instead, which I dont want to do as part of the benefit of using Partial Views in Umbraco 6 is that they inherit from UmbracoViewPage with a strongly typed model declaration, which MacroPartials don't.
Has anyone encountered this before?
Fixed. The issue was with the model I was passing to the document type view from the controller.
In the Umbraco documentation it says, you can create a controller to hijack the Umbraco route and serve up your own view with a custom model, like so:
public ActionResult Index(RenderModel model)
{
SearchResultsViewModel viewModel = new SearchResultsViewModel
return CurrentTemplate(viewModel);
}
and in my view I had:
#inherits UmbracoViewPage<SearchResultsViewModel>
However, it seems as though, in order to do that, you must make sure your custom view model in inherits from RenderModel with a constructor that takes RenderModel as a parameter and then sets some properties on the base object, like so:
public class SearchResultsViewModel :RenderModel
{
public SearchResultsViewModel(RenderModel model) : base(model.Content, model.CurrentCulture)
{
}
}
Previously, my view model had not inherited from anything and had a parameterless constructor.
This article led me to the right answer.
http://www.ben-morris.com/using-umbraco-6-to-create-an-asp-net-mvc-4-web-applicatio
Also, as a side note, I still get the ReSharper warning of "Cannot resolve partial view PropertySearchResultDesktop" but I think that's a ReSharper bug rather than an error.
Even with a full path and file extension in the call, it still complains.
I do find it odd though that while debugging, even with my old controller code, no exception was thrown at the model binding stage or inside the controller, or in the view until it go to the Html.Partial call.
Anyway, I hope this helps anyone having the same issue.
I have created a partial view in my asp.net mvc solution that will show a list of items from a database. However I get an error saying: Object reference not set to an instance of an object.
I'm not sure why this is happening because as far as I'm concerned everything is fine. The list of items are venues which is controlled via VenuesController BUT the partial view is inside the /shared/ folder and NOT the /venues/ folder for the views so is asp.net complaining because it's not linking the two together?
This is the code I have in my VenuesController:
//
// GET: /Venues/
public ActionResult Index()
{
return View(_repository.ListAll());
}
public ActionResult VenuesList()
{
return PartialView("VenuesList",_repository.ListAll());
}
The Index() works fine and displays the data in /Views/Venues/Index.aspx but the VenuesList() throws the error :/
Thanks.
The error message that you mention:
Object reference not set to an instance of an object.
typically deals when a property of a collection is referenced and it is null. You might want to make sure that the list of items is either:
Not empty.
Instantiated properly.
Any code from the Controller-side of things might make this a bit easier to figure out.
Update:
I'm not completely sure what the Venue model looks like, however two things could be occurring here.
In the constructor for Venue (which should be passed the list from your repository),
the List property inside of Venue is never being instantiated prior to Adding the
items in.
or
The repository is not returning any values.
Additional code displaying the Venue class and it's constructor might be helpful.
Make sure that any properties in your model that you reference in your partial view are not null. I've had similar cases where the model passed into the partial view has some null fields that, when rendered, throw NullReferenceExceptions.
E.g. something like
<%: Model.Property %>
or, especially:
<%: Model.Property.ChildProperty %>
i.e. if "Property" is null, then trying to access "ChildProperty" WILL throw a NulLReference exception.
In Eric Hexter's Input Builders, different templates use different strongly-typed models; for example String uses PropertyViewModel<object>, DateTime uses PropertyViewModel<DateTime>, Form uses PropertyViewModel[], and so forth. Spark View Engine doesn't seem to allow this, because all elements that compose the presentation (masters, views, partials, etc.) are compiled into a single class.
If I try to setup a view involving more than one template, I get the following exception:
Only one viewdata model can be declared. PropertyViewModel<DateTime> != PropertyViewModel<object>
If leave just one viewdata declaration, I get another exception about the passed model item mismatching the required one.
It seems like I will have to give up either the Input Builders or Spark, which is sad because I really love both. So I thought I'd ask here to see if anybody has already figured this out.
Thanks.
You can always use <% Html.RenderPartial() %> for partial view rendering with different model. This will create more than one view class.