Custom UIHint attribute - asp.net-mvc

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.

Related

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.

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 model property meta data to specify TextBox id

With MVC, when you use something like #Html.TextBoxFor(...) the control renders using property attributes from the model for things like validation.
It also uses the class's property name as the name of the rendered HTML control. This conflicts a little with our naming conventions so I'd like to be able to control the ID a bit more.
I've added the 'htmlAttributes:' to the helper, which does what I want, but I was wondering:
How does this impact MVC's ability to instantiate the model again
when the information is posted?
Is there a way to specify the control ID using property attributes in the model class?
Thanks,
Jacques
How does this impact MVC's ability to instantiate the model again when the information is posted?
The ID attribute has absolutely no impact on anything that is posted. The ID attribute is never used when submitting a form. The only requirement is that this attribute is unique throughout your entire DOM. It is the name attribute that is used by the model binder. You cannot change this attribute anyway using the htmlAttributes because this attribute is inferred from the lambda expression used as first argument and you shouldn't need to change it anyway, otherwise you could break the way the default model binder rehydrates your view models.
Is there a way to specify the control ID using property attributes in the model class?
Yes, but it could be a little more work. You could use custom editor templates for the standard types and a custom metadata aware attribute that will pass this additional metadata information to the custom editor template. If you are interested in the implementation specifics I could provide an example but first I have to understand why you need that.

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.

ASP.NET MVC / Linq-to-SQL classes: Can I get it to infer readable display names?

If I have a table Orders with fields CustomerID, OrderID and OrderDate, then the "Linq-to-SQL classes" generated class will be called Orders, with members called CustomerID, OrderID and OrderDate. So far so good.
However, if I then do Html.LabelFor(m => m.OrderDate) then the generated text will be "OrderDate" instead of "Order Date".
I tried using Order_Date as the field name, but that didn't work. Is there any way to get it to infer a better display name?
[I know that I can use data annotations to specify the display name explicitly, but I really don't want to do that for all my classes/members - I just want it to work by convention.]
I suggest you create your own HTML Helper for this, something like Html.MyLabelFor.
The rules to apply from here are up to you. You can simply split the word by case.
There is a solution available for your requirements contained within the answer to this question. Asp.Net MVC 2 LabelFor Custom Text.
This method takes advantage of existing MVC 2 architecture to place conventions over the entire *For rendering methods instead of one off HTML helpers and without having to re-label everything with spaced property names.
How to "DRY up" C# attributes in Models and ViewModels?
Essentially what your doing is overriding the default ConventionModelMetadataProvider behavior of MVC 2 and providing hooks for you to insert your own opinionated conventions.

Resources