Can I configure the HTML Helper to display String.Empty if my date is MinValue?
${Html.TextBoxFor(v=>v.Date)}
How can I do this?
Why don't you do it in your View?
Caution: Razor syntax
#if(v.Date != DateTime.MinValue)
{
Html.TextBoxFor(v => v.Date);
}
else {
//show whatever
}
There are a few similar questions like
Html.TextboxFor default value for Integer/Decimal to be Empty instead of 0
Display empty textbox using Html.TextBoxFor on a not-null property in an EF entity
If you have full control over the viewmodel, one option would be to make the date field nullable and have the accessor return null if the date is equal to DateTime.MinValue.
If you don't want to change your viewmodel, you can write your own html helper and put the logic to create an empty textbox there. That allows you to keep logic out of your view, where it's difficult to test.
Make your property nullable and it won't default to the min date. If that's a database field and you can't do that then you should create a ViewModel property that is and have it compare against the min value and return null in the get{}
Related
I have these questions
How do I remove time from datetime (01/01/2017 instead of 01/01/2017 00:00:00)
How do I display on year (2017 instead of 01/01/2017 00:00:00)
See the view below
<td>
#Html.DisplayFor(modelItem => item.PAYMENT_YEAR)
</td>
PAYMENT_YEAR is DateTime in the database. I want to do it from view
You can call the ToShortDateString() method on the DateTime object. This will give you the short date string representation from that DateTime value.
<td>item.PAYMENT_YEAR.ToShortDateString()</td>
If you want just the year, you may access the Year property.
<td>item.PAYMENT_YEAR.Year</td>
You can use the Year property with the Html.DisplayFor helper method
<p>#Html.DisplayFor(modelItem=>item.PAYMENT_YEAR.Year)</p>
But you cannot make a method call inside DisplayFor. So you may just go with
<td>item.PAYMENT_YEAR.ToShortDateString()</td>
If the type of PAYMENT_YEAR property nullable DateTime (DateTime), you need to do a null check before calling the helper method
if (item.PAYMENT_YEAR.HasValue)
{
<span>#Html.DisplayFor(modelItem => item.PAYMENT_YEAR.Value.Year)</span>
}
Or you can simply print the value without using the helper method along with null conditional operator
<td>item.PAYMENT_YEAR?.Year</td>
Please help me to implement the editor template when Model and ModelState mismatch.
For example: Model.A == 'x', ViewData.ModelState['A'] == 'y'.
That can occur when form was posted invalid.
Native templates take this in account and display right value from the ModelState. But i could't find their sources.
I need to implement this in my own temlate. Should i just check for a present value in ModelState and use it if it is set. Or may you suggest a better way?
I had a look at the HtmlHelpers (editors) and came up with this. In the example the model/ value is an integer:
var value = Model; //value according to the model
var fieldName = ViewData.TemplateInfo.GetFullHtmlFieldName("");
ModelState modelState;
if(ViewData.ModelState.TryGetValue(fieldName, out modelState) && modelState.Value != null)
{
value = (int?) modelState.Value.ConvertTo(typeof(int?), null);
}
Now the value contains the model value or the posted ModelState value (the attemptedValue).
A simple scenario that I've never seen before, but a colleague has just hit - MVC3
Create an action method MyAction(int myProperty = 0)
Create a model that has a property MyProperty
Pass an instance of this model to a strongly typed view, but set the property to 10 in code (don't use the query string parameter!)
In the view, Html.TextBoxFor(x => x.MyProperty)
This should render 10 in the text box.
Now call the action method MyAction?myProperty=8
Shouldn't this still render 10 in the text box?
I see that I can override the property discovered by the expression and assume this is because they are the same name (Query String parameter and model property). Eveything is then in the ViewData but one overrides the other.
Is this by design?
This is by design - ModelState is the highest priority value-provider for model properties, higher than even model itself. Without query string parameter, ModelState does not contain value for MyProperty, so framework uses model value.
You can use ModelState.Remove("MyProperty") to ensure using model value
If you look at the source code for Html.TextBoxFor you will see that if a value exists in ModelState then it will always use that value before any other.
string attemptedValue = (string)htmlHelper.GetModelStateValue(fullName, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(fullName, format) : valueParameter), isExplicitValue);
If the value is in ModelState, then it doesn't matter what you set in code.
In a razor-view, how can I check the existence of a property in a model?
if (Model._myProp != null) <--- error .RuntimeBinder.RuntimeBinderException if Model does not contain _myProp
{
...do something
}
You do not want to check that one of the model's properties has the value null you want to check the type for it is having a property or not and ofcourse you solution will not work that way but #Satpal's wont work too.
Use stronly typed views and separate different properties into interfaces and use them with partial views.
I have a textbox that I am trimming the value of server side in the viewModel's setter and verifying that the trimmed value is present:
<Required()>
Public Property Name As String
Get
Return Me.mName
End Get
Set(value As String)
Me.mName = value.Trim()
End Set
End Property
In the controller, I check to see if the ModelState is invalid, and if it is, I show the view again:
If (Not ModelState.IsValid) Then
Return View("Locations", viewModel)
End If
In situations where the trimmed value is blank, I re-display the form to the user. At this point, the non-trimmed values are put into the textbox. I would much prefer the trimmed value.
I was looking through the MVC sourcecode, and I found that at one point in the InputHelper function (used by Html.Textbox(), located in InputExtensions.cs) the code was checking the ModelState for the value, and if it existed, replacing the controller-supplied value.
string attemptedValue = (string)htmlHelper.GetModelStateValue(name, typeof(string));
tagBuilder.MergeAttribute("value", attemptedValue ?? ((useViewData) ? htmlHelper.EvalString(name) : valueParameter), isExplicitValue);
I realize that I could fix this by clearing the ModelState in the controller, but I'm just wondering why the MVC Developers chose to have the values in the ModelState supersede the view model values.
This was designed this way because the assumption is if you are not redirecting to another view after a post .. Hence the post-redirect-get pattern, then there was ideally an error and the current posted values would be shown back to the user for them to fix hence why they are pulled from modelstate. You can ModelState.Clear to work with this but keep that design in mind.