Umbraco Razor - binding content fields - umbraco

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

Related

Custom UIHint attribute

Is it possible to create a custom version of the UIHint attribute?
When my company first adopted MVC, we used a lot of Html.* helper methods. We are in the process of redesigning out MVC template to make use of the full power of MVC. One way we are doing this is with Display and Editor Templates.
However, one popular HTML extension method we had was to generate dropdowns for Enums. One of the options we had was to sort by the int value or the description or text of the EnumMember.
I would like to see about creating a EnumDropdown attribute that accepts several parameters that can customize the output of the HTML dropdown. However, I don't think it's possible to do this while still retaining the benefits of the UIHint attribute. Meaning, that I won't be able to simply call #Html.EditorFor(m => Model)
I had found that there is a System.Web.UI.IAutoFieldGenerator interface but it doesn't appear to do what I want. Any suggestions?
The newer versions of MVC have this built in now:
EnumDropDownListFor HTML Helper
The only thing UIHint does is suggest a Display or Editor template name. MVC will then add this name to the search path when looking for that template.
You can just use UIHint as is and have your generator create these for you in the correct folders and not have to customize it.

Avoiding foreach for #html.checkboxfor

I am developing an application using MVC. I had a requirement where I have to display checkbox for a list.
I was going through different posts for doing this, one of them is the use of avoiding foreach for looping and making use of #html.editorfor() as described in the answer by Darwin dimitrov here:
This answer works fabulously fine, but I have a clarification , it is:
In the same view I have 2 requirements , the one with checkboxfor and the other one with radiobuttonfor
So, If I am using
<div>#Html.EditorFor(x => x.RoleAccess)</div>
How do I write the (~/Views/Shared/EditorTemplates/RoleAccessViewModel.cshtml) to serve for checkboxfor for one requirement , and the other one for #radiobuttonfor .
Wont this approach be hardcoded which will always render the RoleAccessViewModel.cshtml whenever EditorFor(x => x.RoleAccess) is used?Please execuse me If I have used any technical terms wrong way,as I still a novice in mvc.
The EditorFor method has an overload that accepts a template name as argument. I think that solves your problem if I understand it correctly. See http://msdn.microsoft.com/en-us/library/ee407414%28v=vs.118%29.aspx
You can also solve this by using the UIHint attribute on your property instead (or in addition to) relying on naming the template after your view model. Then you can create an alternate template to render the radio buttons and specify that:
[UIHint("RadioList")]
public List<Something> MyRadioButtonList { get; set; }
EditorFor will then look for the template: Views\Shared\EditorTemplates\RadioList.cshtml
You could do the same for your checkbox list, as well, instead of relying on the view model. For example, [UIHint("CheckboxList")] and CheckboxList.cshtml. Then, you'd be able to apply these templates more broadly.

ASP.Net MVC (2) - Getting ModelMetadata from a View without a custom template

How can I (if possible) get to the ModelMetadata from a view without creating a custom template for the given Model's property?
Traditionally, I have just made a new template and altered the template using the ViewData.ModelMetadata.IsRequired (for example). However, I'm looking for how to access this information in the base view and not within a specific editor template.
In terms of why I don't want to go the editor template route - I have a form where I need better control to the markup in terms of attributes on the input elements. EditorTemplates work decent but having a specialized template and ensuring additional ViewData are set to fulfill the attribute values isn't clean in my opinion.
This should give you access:
<%
var metadata = ViewData.ModelMetadata;
%>
You may checkout how the default templates are implemented. It might give you some additional ideas.

EditorTemplates/Object.cshtml using EditorFor() instead of Editor()?

I am trying to create a generic editor template that replicates Html.EditorForModel(), to later customize and build upon. Brad Wilson's template gets pretty close, but I found that it chokes when the same key exist in both ViewData (or ViewBag) and the model. For example ViewBag.Title causes problems if the view model also has a Title property.
I learned here that using strongly-type helpers (i.e. Html.EditorFor(x => x.Title) instead of Html.Editor("Title") seems to help. So I tried to modify Brad's template, but I ran into a brick wall, as nothing I tried so far has worked. I can't figure out how to use strongly-typed helpers in a context where I don't know the model type, like an editor template for example.
Is there any way to create an Object template like Brad's, but using strongly-typed helpers (i.e. LabelFor, EditorFor, ValidatorMessageFor) instead of weakly-typed ones (i.e. Label, Editor, ValidatorMessage)?
Thanks.
I solved this problem in a slightly roundabout way, by removing the ViewData right before the call to #Html.Editor and then putting it back after.
Object.cshtml:
object oldViewData = null;
var hasConflictingViewData = ViewData.TryGetValue(prop.PropertyName, out oldViewData);
if (hasConflictingViewData)
{
ViewData.Remove(prop.PropertyName);
}
#Html.Editor(prop.PropertyName)
if (hasConflictingViewData)
{
ViewData.Add(prop.PropertyName, oldViewData);
}
The only other option I could think of is using a ton of reflection to call EditorFor generically with a runtime type, and pass in an expression for the pertinent property.
You can view all of the code for the new Object.shtml by going and downloading the MVC source code. I thought it was also in some common folder on your pc already but I can't remember where.
http://aspnet.codeplex.com/releases/view/58781

Problem with IEnumerable in View

I have a view that enumerates over a model.
Outside of the grid that enumerates over the model, I want to have a create link that accepts a parameter of MeetingActionId, that will bind the ActionUpdate object to a specific MeetingAction.
How do I get the create link to accept that property? at the moment i get the error
'System.Collections.Generic.IEnumerable' does not contain
a definition for 'MeetingActionId' and no extension method 'MeetingActionId'
accepting a first argument of type
'System.Collections.Generic.IEnumerable' could be found
I assume it's something to do with the IEnumerable. I was going to solve it by putting the grid in a partial, but that seems like a hacky solution to me.
Can anyone assist, and hopefully educate me as to why this is happening?
Thank you.
The code snippet below is using the MVCContrib Grid, and T4MVC for strongly typed action links.
#model IEnumerable<Actioner.Models.ActionUpdate>
#using MvcContrib.UI.Grid
#{
ViewBag.Title = "ListUpdates";
}
<h2>ListUpdates</h2>
#Html.ActionLink("Add New Update",MVC.ActionUpdates.Create(Model.MeetingActionId))
#Html.Grid(Model).Columns(column => {
column.For(a=> a.UpdateText);
column.For(a=> a.CreatedOn).Format("{0:d}");
column.For(a=>a.CreatedBy);
})
EDIT: Thanks for the contributions guys. After some thinking i decided it would be better to have the grid of actionupdates rendered as a partial view within the 'details' view of the MeetingActions, thus avoiding this issue entirely.
This question could be closed
Hi
I'm not sure that I understand this correctly but it seems like the Model is a list that contains items of type ActionUpdate, that type has a property called MeetingActionId. If that is the case the Model itself does not have the property MeetingActionId that you are trying to use. Perhaps you could to this:
Model.First().MeetingActionId

Resources