Comment formater la valeur dans une vue fortement typée lors de l'utilisation ASP.Net le Html de MVC.TextBoxFor
j'essaie de formater une date rendue par ASP.Net Mvc's TextBoxFor using the value of a strongly typed view. La date est nullable donc, si c'est nul je veux voir une valeur vide, sinon, je veux le voir dans le format MM/jj/aaaa.
<%= Html.TextBoxFor(model => model.BirthDate, new { style = "width: 75px;" })%>
Merci,
Paul Speranza
11 réponses
vous pouvez garder la forte dactylographie en utilisant un personnaliser l'éditeur de template et Html.EditorFor()
au lieu de Html.TextBoxFor()
.
Créer un nouveau EditorTemplates dossier dans votre / Views / Shared dossier et ajouter un nouveau MVC 2 Voir le contrôle de L'utilisateur DateTime.ascx. Ajouter le suivant
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.DateTime?>" %>
<%= Html.TextBox("", (Model.HasValue ? Model.Value.ToString("MM/dd/yyyy") : string.Empty)) %>
Alors, à votre avis, utiliser
<%= Html.EditorFor(model => model.BirthDate)%></p>
ne vous inquiétez pas pour le"", le nom fonctionnera toujours correctement.
si vous affichez la DateTime dans un format de culture différent de celui de la culture d'application par défaut, vous aurez besoin de changer la culture de l'information ou alternativement créer un personnaliser le modèle de classeur pour que la reliure du modèle fonctionne lors de l'affichage de la DateTime.
MVC4 http://msdn.microsoft.com/en-us/library/hh833694.aspx
@Html.TextBoxFor(model => model.YOUR_DATE, "{0:MM/dd/yyyy}")
tout d'abord, ajoutez cette extension pour obtenir le chemin de la propriété:
public static string GetPropertyPath<TEntity, TProperty>(Expression<Func<TEntity, TProperty>> property)
{
Match match = Regex.Match(property.ToString(), @"^[^\.]+\.([^\(\)]+)$");
return match.Groups[1].Value;
}
Que d'ajouter cette extension pour HtmlHalper:
public static MvcHtmlString DateBoxFor<TEntity>(
this HtmlHelper helper,
TEntity model,
Expression<Func<TEntity, DateTime?>> property,
object htmlAttributes)
{
DateTime? date = property.Compile().Invoke(model);
// Here you can format value as you wish
var value = date.HasValue ? date.Value.ToShortDateString() : string.Empty;
var name = ExpressionParseHelper.GetPropertyPath(property);
return helper.TextBox(name, value, htmlAttributes);
}
vous devez aussi ajouter ce code jQuery:
$(function() {
$("input.datebox").datepicker();
});
datepicker est un plugin jQuery.
Et maintenant vous pouvez l'utiliser:
<%= Html.DateBoxFor(Model, (x => x.Entity.SomeDate), new { @class = "datebox" }) %>
C'est un sale hack, mais il semble fonctionner.
<%= Html.TextBoxFor(model => model.SomeDate,
new Dictionary<string, object> { { "Value", Model.SomeDate.ToShortDateString() } })%>
Vous obtenez la liaison de modèle, et êtes capable de surcharger la propriété HTML "valeur" du champ de texte avec une chaîne formatée.
Vous pouvez considérer l'exemple suivant de la méthode TextBoxFor Extension pour les données datetime:
public static MvcHtmlString CalenderTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
Func<TModel, TProperty> deleg = expression.Compile();
var result = deleg(htmlHelper.ViewData.Model);
string value = null;
if (result.ToString() == DateTime.MinValue.ToString())
value = string.Empty;
else
value = string.Format("{0:M-dd-yyyy}", result);
return htmlHelper.TextBoxFor(expression, new { @class = "datepicker text", Value = value });
}
il suffit de nommer ce qu'il cherche. Comme:
Html.TextBox("Person.StartTime",Person.StartTime.ToShortDateString());
quand il retourne au controller, votre model aura la valeur limitée.
avez-vous essayé de forcer la culture de votre application actuelle? Vous pouvez la remplacer dans le web.config à l'aide de cette ligne (dans la balise) :
<!-- Default resource files are set here. The culture will also change date format, decimal, etc... -->
<globalization enableClientBasedCulture="false" culture="en-US" uiCulture="en-US"/>
une solution simple est de ne pas utiliser le helper fortement tapé.
<%= Html.TextBox("StartDate", string.Format("{0:d}", Model.StartDate)) %>
j'utilise quelques helpers personnalisés et je les ai utilisés avec succès dans MVC 2 et 3 (code aussi sur Snipplr). Les helpers ont une certaine logique css lancée dans que j'utilise le jquery-ui datepicker, mais qui peut facilement être enlevé.
public static MvcHtmlString DateTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string formatString, object htmlAttributes)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string format = String.IsNullOrEmpty(formatString) ? "M/d/yyyy" : formatString;
DateTime date = metadata.Model == null ? new DateTime() : DateTime.Parse(metadata.Model.ToString());
string value = date == new DateTime() ? String.Empty : date.ToString(format);
RouteValueDictionary attributes = new RouteValueDictionary(htmlAttributes);
string datePickerClass = "date-selector";
if (attributes.ContainsKey("class"))
{
string cssClass = attributes["class"].ToString();
attributes["class"] = cssClass.Insert(cssClass.Length, " " + datePickerClass);
}
else
{
attributes["class"] = datePickerClass;
}
return helper.TextBox(ExpressionHelper.GetExpressionText(expression), value, attributes);
}
public static MvcHtmlString DateTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
{
return DateTextBoxFor<TModel, TValue>(helper, expression, String.Empty, null);
}
public static MvcHtmlString DateTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, string formatString)
{
return DateTextBoxFor<TModel, TValue>(helper, expression, formatString, null);
}
Sérieusement, pourquoi la vue de faire cela?
Mappez votre modèle de base qui a l'objet date time vers votre modèle de vue mvc.
//core model
public class Person
{
public DateTime? BirthDate { get; set;}
}
//view model
public class PersonForm
{
public string BirthDate { get; set; }
}
Donc la cartographie pourrait ressembler à:
public interface IDomainToViewMapper<TModel, TViewModel>
{
/// <summary>
/// Use an automapper or custom implementation to map domain model to presentation model.
/// </summary>
/// <param name="source">domain model</param>
/// <returns>presentation model</returns>
TViewModel MapDomainToView(TModel source);
}
public interface IPersonMapper : IDomainToViewMapper<Person, PersonForm>
{
}
public class PersonMapper : IPersonMapper
{
#region IDomainToViewMapper<Person,PersonForm> Members
public PersonForm MapDomainToView(Person source)
{
PersonForm p = new PersonForm();
if (source.BirthDate.HasValue)
{
p.BirthDate = source.BirthDate.Value.ToShortDateString();
}
return p;
}
#endregion
}
Et votre contrôleur de l'action pourrait ressembler à:
public ActionResult Index()
{
Person person = //get person;
var personForm = _personMapper.MapDomainToView(person);
return View(personForm)
}
vous n'aurez pas à changer votre exemple de vue du tout alors.
Dans le Chapitre 2, MVC 2 en Action (Manning)
public class CustomerSummary
{
public string Name { get; set; }
public bool Active { get; set; }
public string ServiceLevel { get; set; }
public string OrderCount { get; set;}
public string MostRecentOrderDate { get; set; }
}
Ce modèle est intentionnellement simple; il se compose principalement de cordes. C'est ce que nous sommes qui représentent, après tout: le texte sur une page. La logique qui affiche les données de cet objet sera simple; la vue seule de sortie. Le modèle de présentation est conçue pour minimiser la prise de décision dans la vue.
avez-vous essayé de passer dans le format de date que vous souhaitez?
Html.TextBoxFor(model => model.BirthDate.ToString("MM/dd/yyyy"),
new { style = "width: 75px;" })