MVC #Html.Display() - asp.net-mvc

I have something like:
<input type="text" name="TerrMng" id="TerrMng"/>
in HTML. What is the equivalent of the above using #Html.Display?
I tried using: #Html.Display("TerrMng", TerrMng)
but was not successful. Note that I like to use #Html.Display but not sure how to translate the ID value so that it shows up.

The Display method is not for creating input boxes. You'd want to use:
#Html.TextBoxFor(m => m.TerrMng);
or the templated helper method:
#Html.EditorFor(m => m.TerrMng);
I'm assuming that you want to use modelbinding. If not, if you really just want to use a helper to simply make an input tag, use:
#Html.TextBox("TerrMng");
This would be sent to the client:
<input id="TerrMng" type="text" value="" name="TerrMng">
The first 2 methods above would result in the exact same html, if model.TerrMng was "" or String.Empty. If for some reason you don't want the value attribute, you'll need to type it out yourself.

This should do the trick if you are just wanting to display the data and not allow the user to edit the information.
#Html.DisplayFor(m => m.TerrMng);
Edit:
what-is-the-html-displayfor-syntax-for is another question on stackoverflow that may give you some more guidance.
Edit:
TerrMng does not exist on PageLoad so you cannot use the Html.Display in that way. You need to create it and fill its value with the value received from the jQuery. In this case where you would have to do the following:
HTML
#Html.Display("TerrMng"); // This creates the label with an id of TerrMng
jQuery
$("#TerrMng").val(TerrMng); // This puts the value of the javascript variable into the label

You could try something based on this. This is not exact but you could get some idea.
#Html.TextBoxFor(yourmodel => model.yourModelFieldname, null)

#Html.Display() is used instead of #Html.DisplayFor() when your model is not known at compile time, or if you prefer to work with strings, rather than with strong types. For example, these 2 are equivalents (given that your model is some class):
#Html.DisplayFor(m => m.MyProperty)
and
#Html.Display("MyProperty")
But the additional cool feature of the Display() method is that it can also do the lookup in the ViewData, and not just in your Model class. For example, here is a way to display the HTML for the property on a random object, given that we know it has a property named "Blah" (the type of the object doesn't really matter):
#{ ViewData["itsawonderfullife"] = SomeObject; }
<div>#Html.Display("itsawonderfullife.Blah")</div>
This way, we are telling HtmlHelper to look into the ViewData, instead of our Model, and to display the property Blah of a given SomeObject.

Related

Direct Model.Property versus Html Helper DisplayFor in Razor

Is there a reason to use preferably one of these:
#Model.Property
#Html.DisplayFor(m => m.Property)
I never arrived in a crossroad where one works differently from the other.
There is any difference?
Model.Property - as you know - will just write out the value of the property in question. Html.DisplayFor(m => m.Property), on the other hand, will call a display template, which can render out other markup around the property value.
For example, you might define a display template like so:
#model String
<div class="property-wrapper">
<p>#Model.Property</p>
</div>
The surrounding divs will be rendered around the value of the property when using DisplayFor (if the display template is selected, which typically means it has a filename matching the property's type, is specified in the UIHint attribute for the property, or is explicitly specified in the call to DisplayFor.
You also have access to model metadata in your display templates, meaning you can do something like this:
<div class="property-label">
#Html.DisplayNameForModel()
</div>
<div class="property-value">
#Model.Property
</div>
Display templates give you a huge amount of flexibility and reusability. The best way to explore this is to start building custom templates and see where it takes you.

ASP.NET MVC 4 override emitted html name and id

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.

MVC4 Razor - #Html.DisplayFor not binding to model

I am trying to find me feet with MVC4 Razor and I'm stuck with this simple problem.
When I use #Html.DisplayFor the model is always sent back as NULL, but when I use #Html.TextBoxFor this model is fully populated, what am I missing?
Thanks in advance
This is a common issue that many people miss in the asp.net mvc framework. Not just the difference in the helpers such as HiddenFor, DisplayFor, TextBoxFor - but how exactly the framework sets up automatically collecting and validating these inputs. The magic is all done with HTML5's data-* attributes. You will notice when looking at the input tag generated that there are going to be some extra properties in the form of data-val, data-val-required, and perhaps some additional data properties for types, for example numerics would be data-val-number.
These data attributes allow the jQuery extension jquery.validate.unobtrusive.js to parse the DOM and then decide which fields to validate or generate error messages.
The actual collection of posted data is reflected from the name property. This is what should map up to the model that is in the c# or vb [HttpPost] method.
Use HiddenFor when you want to provide posted data that the user does not need to be aware of.
Use DisplayFor when you want to show records but not allow them to be editted.
Use TextBoxFor when you want to allow user input or allow the user to edit a field.
EDIT
"the purpose of this view is to enable the user to view the data before submitting it to the database. Any ideas how I can achieve this?"
You could accomplish this with a duo of HiddenFor and DisplayFor. Use HiddenFor to have the values ready to be posted, and DisplayFor to show those values.
DisplayFor will not do the Model binding. TextBoxFor will do because it creates a input element in the form and the form can handle it when it is being posted. If you want to get some data in the HttpPost action and you dont want to use the TextBoxFor, you can keep that pirticulare model proeprty in a hidden variable inside the form using the HiddenFor HTML helper method like this.
#using(Html.BeginForm())
{
<p>The Type Name is</p> #Html.DisplayFor(x=>x.TypeName)
#Html.HiddenFor(x=>x.TypeName)
<input type="submit" value="Save" />
}
Use both DisplayFor and HiddenFor. DisplayFor simply displays the text and is not an input field, thus, it is not posted back. HiddenFor actually creates <input type="hidden" value="xxxx"/>
DisplayFor builds out a HTML label, not an input. Labels are not POSTed to the server, but inputs are.
I know this is a bit of an old question but you can roll your own, custom combined display control as shown below. This renders the model value followed by a hidden field for that value
#Html.DisplayExFor(model => Model.ItemCode)
Simply use what the framework already has in place
public static MvcHtmlString DisplayExFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> ex)
{
var sb = new StringBuilder();
sb.Append(htmlHelper.DisplayFor(ex));
sb.Append(htmlHelper.HiddenFor(ex));
return MvcHtmlString.Create(sb.ToString());
}
Do you mean during a form post? If you use DisplayFor, this creates a element which does not contain any form values. Typically you use these in conjunction with each other to create a label for your textbox, then using the Html.TextBoxFor to allow users to modify the data element.
Example:
#Html.DisplayFor(x=>x.Item)
#Html.TextBoxFor(x=>x.Item)
Will Render
Item <a text input field following>
Or in HTML
<label for="Item">Item</label><input type="Text" id="Item" name="Item"/>

Is it possible to I create LabelTemplates for Html.Label and Html.LabelFor() in ASP.NET MVC?

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.

How to map form values to an object for ASP.NET MVC HTTP-Post scenario?

i have a simple form for an ASP.NET MVC application. I have a form property that is named differently (for whatever reason) to the real property name.
I know there's [Bind(Exlcude="", Include="")] attribute, but that doesn't help me in this case.
I also don't want to have a (FormsCollection formsCollection) argument in the Action method signature.
is there another way I can define the mapping?
eg.
<%= Html.ValidationMessage("GameServer", "*")%>
results in ..
<select id="GameServer" name="GameServer">
<option value="2">PewPew</option>
</select>
this needs to map to..
myGameServer.GameServerId = 2; // PewPew.
cheers!
i believe you will need to define it in your controller arguments or else it wouldnt have any clue what to accept.
public ActionResult GameServer(string GameServer){
GServer myGameServer = new GServer();
myGameServer.GameServerId.ToString() = GameServer;
return View("GameServer");
}
you can pass in the name/id of the parameter your trying to go for on your view page, it will automagically know the value to recieve based on the id on your view.
What's wrong with having a FormCollection passed as argument? I had to do the same thing as you and I just excluded the GameServer property in the BindAttribute.
Another thing you have to note is that Html.ValidationMessage("GameServer", "*") won't work because the underlying model doesn't contain a GameServer property. You have to add it to the model. I don't know if there is a better way to do it, I didn't find but it was required to make ValidationMessage works
You can create you own ModelBinder (see how to) to do the custom mapping.
An overkill IMO, but you might have your reasons...

Resources