Is there anyway of putting a new line in a [DisplayName()] annotation of an mvc viewmodel? I currently have a property that is:
[DisplayName("Delivery Time (if different from our normal delivery of 10-30am – 12.30pm):")]
public string DeliveryTime { get; set; }
and I want to have a new line after the Delivery Time part so that the bit in brackets is below, is that possible? I've tried \r\n but that didn't work.
Well, the problem you have is that \n is ignored in html. You'd need to use <br /> BUT that does tie your attribute metadata to using html formatting.
I'm looking for a prettier solutions, but a work around is presented in How to add a new line into Display Attribute, Name field
To summarize you put a <br> (or <br/>) in your DisplayName string and use
#Html.Raw(ViewData.ModelMetadata.DisplayName)
to display it.
You can just use style="white-space: pre-line" in your element and \n in DisplayName attribute. At least, it worked for me.
Related
I'm trying to change the emitted name of the html input created by #Html.HiddenFor.
The code I'm using this:
#Html.HiddenFor(e => e.SomeProperty, new { #id = "some_property", #name = "some_property" }
Now this works for the id, however it doesn't work for the name. Now I don't really care for the id now, I need the name to change, because that's the one that get's posted back to the target server.
Is there
A property I can apply on SomeProperty in my model?
A way in the Html.HiddenFor to override the name property?
Or am I stuck to do a plain <input ...> by hand?
You need to use the Html.Hidden (or write out the <input ...> by hand) instead of the Html.HiddenFor
#Html.Hidden("some_property", Model.SomeProperty, new { #id = "some_property" })
The goal of the strongly typed helpers (e.g the one which the name end "For" like HiddenFor) is to guess the input name for you from the provided expression. So if you want to have a "custom" input name you can always use the regular helpers like Html.Hidden where you can explicitly set the name.
The answer from unjuken is wrong because it generates invalid HTML.
Using that solution generates TWO name attributes:
<input Name="some_property" name="SomeProperty" id="some_property" type="hidden" value="test" />
So you will have Name="some_property" AND name="SomeProperty" which is INVALID HTML because an input can only have ONE name attribute! (although most browers happen to take the first Name="some_property" and don't care about the second one...)
If you use:
#Html.HiddenFor(e => e.SomeProperty, new { #id = "some_property",
#Name = "some_property" });
Notice the capital "N" in #Name. It´ll work.
I was curious as to why specifically overriding the name attribute wouldn't work. Unless I capitalized it (i.e. new {#Name = 'somename'} ), then it doesn't seem to work. As others have pointed out, this only works because it generates duplicated name attributes and Chrome cleans it up.
I looked at the latest MVC source code to figure out what is going on. Consider the following snippet from the GenerateInput method in DefaultHtmlGenerator.cs:
var fullName = NameAndIdProvider.GetFullHtmlFieldName(viewContext, expression);
if (string.IsNullOrEmpty(fullName))
{
throw new ArgumentException(
...
}
var inputTypeString = GetInputTypeString(inputType);
var tagBuilder = new TagBuilder("input");
tagBuilder.TagRenderMode = TagRenderMode.SelfClosing;
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("type", inputTypeString);
tagBuilder.MergeAttribute("name", fullName, replaceExisting: true);
We can see here, the problem is that, regardless of whatever name property you provide, it will be overridden by the last call to MergeAttribute, which will use whatever logic it is that assigns to the variable fullName from the GetFullHtmlFieldName method.
I sort of understand why they enforce this behavior, guessing it has something to do with controlling the names used in the postback to guarantee it works with the model binder.
In any case, to make this happen, I say just manually construct the input element and don't use the razor view helper.
never worked for me (aspnet.core)
I used plain
<input type="hidden" id="#myid" name="#myname" value="#Model.prop" />
and worked like a charm. No need for HtmlHelper HiddenForModel.
I am looking for best practices for design razor view with MVC.
which would be better option:
HtmlHelper extension methods
#Html.TextBox("txtName")
or
write the html directly
<input type"text" id="txtName" name="txtName" />
I found 2 diferent links.
The first one http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx says DO use HTMLHelper extension methods.
and the second one http://codeclimber.net.nz/archive/2009/10/27/12-asp.net-mvc-best-practices.aspx says 10 – Write HTML each time you can
so i am a little cofused
Even the name HtmlHelper should already give you a hint whether you should use it or not. Do you want help? If not, just write html from the scratch. It does not really matter how the html was generated: from the scratch or using html helper. What matter is that it was generated with correct names of the inputs so that model binder can bind these inputs to the model.
For example, suppose you have the following Model that will be passed to the view and that will be received on the POST:
public class SomeModel
{
public Customer Customer { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
In order to make sure that your inputs will be binded to the model you need three inputs on your page:
<input type="hidden" id="whatever" name="Customer.Id" />
<input type="text" id="whatever" name="Customer.FirstName" />
<input type="text" id="whatever" name="Customer.LastName" />
Having this html markup will assure proper model minding. However, you can achieve this markup by using HtmlHelpers, which is a lot easier:
#Html.HiddenFor(m => m.Customer.Id)
#Html.TextBoxFor(m => m.Customer.FirstName)
#Html.TextBoxFor(m => m.Customer.LastName)
This will not only give you proper name attributes on every input, but also assign id attributes accordingly so you don't have to do that all by your self.
It appears that the author from the second article suggests to never use HtmlHelpers for two reasons:
the learning purposes: I assume by saying "web developers have to be
comfortable writing HTML" he means that developer should know
exactly what html markup is required for proper model binding.
the fear of black box: It seem that author is afraid that improper html
markup will be generated by using HtmlHelpers or he just does not
know what html will be generated.
I disagree with his phrase: "HtmlHelpers whose only reason of living is hiding the HTML away". I'd rather say "HtmlHelpers whose only reason of living is helping writing Html markup"
Summary:
HtmlHelpers help you write proper html markup, which is why I suggest you using it.
Since you're using Razor, I would make the most of what it has to offer, and the HtmlHelper extensions allow you to write html quicker and easier in a lot of places.
There may be times when you have to use Html instead, where you might want to include tags in an anchor and cannot use #Html.ActionLink, for example.
But where you can achieve the same result with either approach, I'd recommend you go with Razor.
Html helpers are not cosmetic code snippets that just save time. Consider choosing the appropriate editor based on model property types, and - what is also very important - they help in client validation, provided you include jquery.unobtrusive-ajax.js and jquery.validate.js.
The last cannot be achieved by simply writing HTML.
From what I said it can be easily derived that Html helpers "know" about the model, while plain markup does not.
At the end it is up to you to decide what to use, but knowing more about Html helpers is better when making a decision.
For reasons that are questionable but practical, I'd like to create LabelTemplate defaults, just like EditorTemplates or DisplayTemplates.
So instead of this:
#Html.LabelFor(x => x.PropertyName, "Property Name")
or instead of this(the better way to do it in a View Model):
[DisplayName("Property Name")]
public string PropertyName{ get; set; }
I want this:
#Html.LabelFor(x => x.PropertyName)
With this (in a folder like this: /Views/Shared/LabelTemplates)
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.String>" %>
//Display logic here
Can you help a coder out?
Create your own custom html helper.
http://develoq.net/2011/how-to-create-custom-html-helpers-for-asp-net-mvc-3-and-razor-view-engine/
This is the code you can use to convert your property names:
Regex.Replace("PropertyName", "[a-z][A-Z]", m => m.Value[0] + " " + m.Value[1]);
I know this isn't strictly an answer to your question, but since I still want to suggest a plan of action, I'll post it like this rather than in a comment.
Are you sure you want this?
If you manage to do this, you will set the label of a field to some value based on its type. This might seem tempting at first glance - you could possibly save yourself some key strokes every here and there.
But what happens if you e.g. have a type Address containing some properties for street name, number, zip code etc, and then want the user to fill in the home address and the work address in the same form - how would you label them differently and still use the same type? And even worse - do you really want the same label on all your strings? In order to avoid these two scenarios, you'll need to resort to Html.DisplayFor(m => m.PropertyName, "TemplateName") anyway, which means you'll be in just as sorry a situation as you already are. Furthermore, you'll have at least two places you have to look to find the correct display logic for your label, rather than just one.
Remember that there is no absolute requirement to use the LabelFor() helper - you can just as well just roll your own extension method on HtmlHelper, or even ignore them and output plane HTML:
<label for="Person_HomeAddress">Home address</label> <!-- the ID might be wrong -->
<%: Html.EditorFor(m => m.HomeAddress) %>
Since the EditorFor() outputs an ID matched to the name of the model and property names, you'll be fine.
I'm trying to make a page where the user can search for articles. There is an option to limit the search based on a FromDate and a ToDate. Both of these are DateTime.
The user is asked to enter the date on the form dd.MM.yyas this is normal in our country. I can see the date in the URL after submitting the form and it looks as I want it to. The problem however is that MVC3 assumes the format is MM.dd.yy. How can I change this?
Some code:
This is the Razor code I use
<div class="toDate" >
<label>til dato</label>
#Html.TextBoxFor(m => m.DateTo, new { placeholder = "dd.mm.yy" })
</div>
And in the model all I have is:
public DateTime DateTo { set; get; }
I have tried using EditorFor, but I lose my placeholder text.
In short: How do I make my MVC3 model accept a DateTime input from the user on the form dd.MM.yy
If my question isn't clear enough, let me know and I'll try to clarify.
EDIT:
It appears that I need some clarification, so I'll try to do that by making a scenario:
The user enters his search criteria. He sets a DateFrom and a DateTo in two text boxes.
The form is submitted and posted back to the server.
On the server the DateTime object is treated on the form MM.dd.yy. I wish for it to be interpreted as dd.MM.yy.
I hope that helps.
[DisplayFormat(DataFormatString = "{0:dd MM yy}")]
pubilc DateTime DateTo { get; set }
Try setting up a custom validation attribute where you validate the date format according to your liking.
Here's a nice tutorial for it: http://msdn.microsoft.com/en-us/gg618485 (It's not as difficulty as it might seem at first, and can be really helpful).
Alternatively just build a regex validation attribute with something like:
RegularExpression(#"[0-3][0-9]\.[0-1][0-9].[0-9][0-9]")]
Above regex isn't perfect, but serves as an example.
Edit: If 3nigma's solution works for you that is obviously highly preferable to mine. :)
As the title suggests i have:
DisplayName("This is the display name")
int Id {get;set;}
And i would like to set a part of this name in italics.
DisplayName("This is the <i>display name</i>")
int Id {get;set;}
But this is getting sanitized and the HTML is not getting used. Is there a way round this?
I can't put the italics on the view itself as i only want a part of the display name italicized.
Cheers,
Kohan
You will have to create your own Custom Template. Then you have the full control over the HTML being rendered.