How to convert IPublisedContent list to Strongly typed List - Umbraco Model Builder - umbraco

I'm using the Models Builder to create C# classes for all my document types, in my custom controller I am retriving all the content nodes that are of a specfic type:
var viewModel = new HomePageViewModel(model);
var caseStudyNodes = viewModel.Content.AncestorOrSelf().Descendants(CaseStudy.ModelTypeAlias).ToList();
the caseStudyNodes variable is now a list of IPublished content. Is there a way to get this as a list of CaseStudy objects?
I'm using Umbraco 8 is there a diffrence between how you would do it if you where using umbraco 7

Found the answer to my own question, just in case it helps someone else.
var caseStudyList = caseStudyNodes.Select(c => new CaseStudy(c));

Related

Getting content from umbraco to mvc backend

My client wants to be able to enter things into the admin section of umbraco and add things into the editor. From there how can I pull that data from the mvc backend? I am able to find the node, it's parent, etc, but cannot find the text he wrote in the tinymce editor. What is the best way to get that text? Thank you for
There are two ways of getting data in Umbraco now:
1) ContentService - get IContent object from database
2) Umbraco.TypedContent - get IPublishedContent object from XML cache
In your case the best way will be to use Content service object and get data from the database, I would do it like that:
var content = ApplicationContext.Services.ContentService.GetById(1234);
var propertyValue = content.GetValue<Type>("propertyAlias");
Don't use IPublishedContent at backend because you have to use actual data from the database for working in controllers.

How to display the array index number in an editor template

In my model I have a List property of a complex type called EventField.
I created an editor template, which works fine using:
#Html.EditorFor(e => e.EventField)
My question is, within that Editor template I want to pick out the index/sequence number on its own, as a number. This index will simply be added into the template as a data attribute so I can pick it up using javascript.
A couple of answer are out there that don't suffice:
#html.IdFor - outputs the whole name e.g Name[0].other
here - you can't pass through the model name "EventField" this way.
Is there a simple method/function/helper that will give me access to that Index, without having to change how I call the Editor template?
How about:
#using System
#using System.Text.RegularExpressions
var i = Convert.ToInt32(Regex.Matches(
ViewData.TemplateInfo.HtmlFieldPrefix,
#"\[([0-9]+)?\]")[0].Groups[1].ToString());

Umbraco 7 when to use #Umbraco vs #CurrentPage vs #Model in Razor views?

As the title says, when should I use #Umbraco, #CurrentPage or #Model in Razor views to get properties from a node.
#Model.Content.GetPropertyValue() returns a strongly typed object, whereas #CurrentPage returns a dynamic object. However, with #Umbraco I can get a dynamic (#Umbraco.Content()) or a strongly typed object (#Umbraco.TypedContent()).
Can #Umbraco helper do everything that #CurrentPage and #Model can do? When should I be using which, and why?
You answered most of your question yourself. #Model and #CurrentPage are the same except #CurrentPage is dynamic. Both return the current page. That means that, if you interit your views from UmbracoViewPage, you can not use #CurrentPage because this is only available on the UmbracoViewTemplate. Personally I like #Model more than #CurrentPage, but it's a personal choice
#Umbraco is a completely different beast. It does not return the current page, but it has a bunch of methods to get other content, media and members in different ways (e.g. xpath). But also templating and misc methods like:
Umbraco.If(condition, trueValue [, falseValue])
Umbraco.Trunctate // limit text size
Umbraco.StripHtml // remove html tags
Umbraco.Search // full text search
To know more about the #Umbraco, visit the Umbraco helper documentation
E.g. If you got an image ID from the current node using
var imgId = #Model.Content.GetPropertyValue<string>("img")
then you could use #Umbraco.TypedMedia(imgId) to get the image IPublishedContent object.
Update:
Next to #Umbraco.Field("propertyAlias") which is one of the template helpers, you can also use #Umbraco.Field( x, "propertyAlias") where x is an IPublishedContent. This will always return an IHtmlString which makes it impractical for other programming efforts, but makes the Umbraco.Field() a very nice helper method to return properties.
Update 2:
Starting from version 7.4, There is a modelBuilder which allows you to define UmbracoTemplatePage<ContentModels.HomePage> and use #Model.Content.BodyText later on. Starting from Umbraco v8 (on the roadmap), support for dynamics (CurrentPage on UmbracoTemplatePage) is said to be dropped. So prepare by using ModelsBuilder and UmbracoViewPage<MyModel>.
Update 3:
Starting from version 8, there will be only an UmbracoViewPage. That means that CurrentPage will not be available anymore. Try to use the "models builder" approach to be future proof or read the first v8 documentation about this topic.

Umbraco Razor - binding content fields

I've created a template (View) in Umbraco (MVC) and am trying to figure out how to bind to the document type content. Keeping it really simple:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
Layout = null;
}
<h1>#Model.Title</h1>
My Umbraco document type has a Title field (alias is 'title') but if I try and run this I get build errors. I've found a whole load of documentation suggesting using a Library.NodeById() method but I believe that's for WebForms and not MVC. Can anyone offer some guidance?
You can get a property value in multiple ways with Model::
#Model.Content.GetPropertyValue("title")
#Model.Content.GetProperty("title").Value
And as a dynamic
#CurrentPage.Title
Did you remember to add your template to your document type?
You can also use the Field helper method:
#Umbraco.Field("myFieldName")
nice thing about this helper is that you can also specify alternative fields (if the first one was empty.
You can find this back in the documentation:
http://our.umbraco.org/documentation/reference/templating/Mvc/views#RenderingafieldwithUmbracoHelper

ASP.NET MVC generic view for displaying data

I am working on a project involves exposing many data entities (more than 200) through an ASP.NET MVC application.
I do not want to write views for every entity mode and I am wondering if there is a way of having one generic view to display different models (for example, a view which reads the model properties(metadata) and generates a HTML table to display a list of entities.
If you only need to display, you can write your own generic renderer in few minutes using reflection. Or, you can use ModelVisualizer from MvcContrib, or Grid from MvcContrib which can do Html.Grid(Model).AutoGenerateColumns() to automatically show properties as columns. It doesn't support DataAnnotations or attributes, but you can write your own extension method that will use reflection to generate Grid's columns based on some attributes. And you can quickly turn this grid into jqGrid using jqGrid's tableToGrid() method.
If you need input support, there're several choices:
MvcContrib's InputBuilder (here you can see a simple example on how it's done with reflection)
MVC v2 InputFor(), I think it supports rendering several properties, but I'm not sure.
My solution does read metadata (attributes) from view models and generates jqGrid formatting and editing options automatically.
There should be commercial tools, too.
Two choices:
Dynamic Data Project
Have you tried Asp.net Dynamic data project that can automagically create what you need?
Asp.net MVC
But if you want to do what you're asking, you can always create a single view that will not have a strong type model. You will always pass data to it ViewData dictionary. The view would then parse that data and display what's required.
Routing
You can always create these two routes:
routes.MapRoute(
"EntityRoute",
"{entityName}",
new {
controller = "Entity",
action = "Display",
entityName = "SomeDefaultEntity" }
);
routes.MapRoute(
"EntityRoute",
"{entityName}/{recordId}",
new {
controller = "Entity",
action = "Details",
entityName = "SomeDefaultEntity",
recordId = string.Empty }
);
that will redirect all requests to the same controller action that will provide correct entity set data and pass it into the ViewData dictionary and return the view that will consume it. The second one will display details of a certain record within some entity (in case you need to provide master/details functionality).
MVC Contrib has Model Visualizer which let you display a Model by reflecting its properties. That a no go if you need any performance at all, but maybe it gets you started.

Resources