9

I'm working on an MVC3 application with Razor. I'm having troubles using Dates and doubles on my views. Both my Windows and Visual Studio are English, but I want to customize the culture of my project in "it-IT". I found several articles how to manage different cultures, through the JQuery Validation Plugin or directly setting the culture on the page, but I'm a lot confused!!! The format I want use for dates is "DD/MM/YYYY", while for double is 1.234,32. So,

  • How can I tell to Visual Studio how to use these formats (I checked on the Visual Studio's settings and there is only English)?
  • MVC injects code to validate my fields, how to change it?
  • What is the best approach?

Obviously any suggest would be appreciated. I post the code of my project:

Offerta.cs

[MetadataType(typeof(Offerta_Validation))]
public partial class Offerta
{
}

public class Offerta_Validation
{
    [HiddenInput(DisplayValue = false)]
    public int IDOfferta { get; set; }

    [StringLength(300, ErrorMessage = "Campo troppo lungo")]
    [Required(ErrorMessage = "Campo obbligatorio")]
    public string Titolo { get; set; }

    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:N2}")]
    [Required(ErrorMessage = "Campo obbligatorio")]
    [Price(MinPrice=0.01)]
    public decimal PrezzoIniziale { get; set; }

    [Required(ErrorMessage = "Campo obbligatorio")]
    [Integer]
    public int BuoniScontiMinimo { get; set; }


    public string Sconto { get; set; }

    [Date]
    [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:d}")]
    public System.DateTime DataAttivazione { get; set; }

    [DataType(DataType.MultilineText)]
    [AllowHtml]
    public string Sintesi { get; set; }

    [DataType(DataType.MultilineText)]
    [Required(ErrorMessage = "Inserire le condizioni")]
    [AllowHtml]
    public string Condizioni { get; set; }

    [DataType(DataType.MultilineText)]
    [Required(ErrorMessage = "Inserire la descrizione")]
    [AllowHtml]
    public string Descrizione { get; set; }
}

The field "PrezzoIniziale" is a double on DB. The annotation [Price] derive by this post http://haacked.com/archive/2009/11/19/aspnetmvc2-custom-validation.aspx. This is my view:

@model ManagerEmail.Models.OffertaFormViewModel

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.global.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery.glob.it-IT.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/tiny_mce/tiny_mce.js")"></script>
<script type="text/javascript">
    tinyMCE.init({
        // General options
        mode: "textareas",
        theme: "advanced",
        plugins: "style,searchreplace,paste",

        theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect",
        theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,|,search,replace,|,bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,forecolor,backcolor,|,styleprops",
        theme_advanced_buttons3 : "hr,removeformat,visualaid,|,sub,sup,|,charmap,|,link,unlink,anchor,image,cleanup,help,code",
        theme_advanced_toolbar_location: "top",
        theme_advanced_toolbar_align: "left",
        theme_advanced_statusbar_location : "bottom",

        // Skin options
        skin : "o2k7",
        skin_variant : "silver",

        width: "510",
        height: "300",
        object_resizing: false,

    });
</script>

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "editForm" })){
    @Html.ValidationSummary(true)
    <fieldset>
        <legend></legend>

        <ul>
            <li>
                @Html.LabelFor(model => model.Offerta.Titolo)
                @Html.EditorFor(model => model.Offerta.Titolo) <br />
                @Html.ValidationMessageFor(model => model.Offerta.Titolo)
            </li>
            <li>
                @Html.LabelFor(model => model.Offerta.PrezzoIniziale, "Prezzo iniziale")        
                @Html.EditorFor(model => model.Offerta.PrezzoIniziale) <br />
                @Html.ValidationMessageFor(model => model.Offerta.PrezzoIniziale)
            </li>
            <li>
                @Html.LabelFor(model => model.Offerta.BuoniScontiMinimo, "Minimo Buoni")
                @Html.EditorFor(model => model.Offerta.BuoniScontiMinimo) <br />
                @Html.ValidationMessageFor(model => model.Offerta.BuoniScontiMinimo)
            </li>
            <li>
                @Html.LabelFor(model => model.Offerta.Sconto)
                @Html.EditorFor(model => model.Offerta.Sconto) <br />
                @Html.ValidationMessageFor(model => model.Offerta.Sconto)
            </li>
            <li>
                @Html.LabelFor(model => model.Offerta.DataAttivazione, "Data Attivazione")
                @Html.EditorFor(model => model.Offerta.DataAttivazione) <br />
                @Html.ValidationMessageFor(model => model.Offerta.DataAttivazione)
            </li>
            <li>
                <label for="ddlAffiliato">Affiliato</label>
                @Html.DropDownListFor(model => model.Offerta.Affiliato.IDAffiliato, new SelectList(Model.Affiliati, "IDAffiliato", "RagioneSociale"), new { @id = "ddlAffiliato"} )
            </li>
            <li>
                @Html.LabelFor(model => model.Offerta.Condizioni)  <br />           
                @Html.TextAreaFor(model => model.Offerta.Condizioni) <br />
                @Html.ValidationMessageFor(model => model.Offerta.Condizioni, "", new { style = "top: -30px; left: 210px" })
            </li>
            <li>
                @Html.LabelFor(model => model.Offerta.Sintesi)  <br />           
                @Html.TextAreaFor(model => model.Offerta.Sintesi) <br />
                @Html.ValidationMessageFor(model => model.Offerta.Sintesi)
            </li>
            <li>
                @Html.LabelFor(model => model.Offerta.Descrizione)  <br />           
                @Html.TextAreaFor(model => model.Offerta.Descrizione) <br />
                @Html.ValidationMessageFor(model => model.Offerta.Descrizione, "", new { style = "top: -30px; left: 210px" })
            </li>
        </ul>
        @Html.HiddenFor(model => model.Provincia.IDProvincia)                 
    </fieldset>
    <p>  
        @Html.AntiForgeryToken()
        <input type="submit" value="Salva" id="submitButton"/>
    </p>
}

<script type="text/javascript">

    $("#Offerta_PrezzoIniziale").removeAttr("data-val-number"); //I forced this because MVC adds the data-val-number, so it doesn't accept double values :(

    $(function () {
        jQuery.global.preferCulture("it-IT");        
    });

    $("#submitButton").click(function () {
        tinyMCE.triggerSave();
    });


</script>
<script type="text/javascript">
    $(function () {
        jQuery.validator.addMethod("price", function (value, element, params) {
            if (this.optional(element)) {
                return true;
            }

            if (value > params.min) {
                var cents = value - Math.floor(value);
                if (cents >= 0.99 && cents < 0.995) {
                    return true;
                }
            }

            return false;
        });
    });
</script>

And this is my FormViewModel

public class OffertaFormViewModel
    {
        public Provincia Provincia { get; set; }
        public Offerta Offerta { get; set; }
        public IEnumerable<Affiliato> Affiliati { get; set; }
    }

Thanks!

Ikke
  • 99,403
  • 23
  • 97
  • 120
stuzzo
  • 1,056
  • 1
  • 15
  • 36
  • take a look at this post : http://stackoverflow.com/questions/5300525/how-do-i-render-only-some-specific-model-fields-with-an-invariantculture-while-t – VinnyG Apr 29 '11 at 17:02

2 Answers2

5

Does adding

<globalization culture="it-IT"/>

in your web.config under the system.web section, do the trick?

Edit:

Adding relevant MSDN link http://msdn.microsoft.com/en-us/library/bz9tc508.aspx

Naraen
  • 3,240
  • 2
  • 22
  • 20
  • I added this line on web.config, but the validator still fires..why?!!?I tried with a value like 8,34. I also added the attribute uiCulture="it-IT". – stuzzo Apr 21 '11 at 15:47
  • @stuzzo That should've worked. Hmmm ... something else must be happening. What is the error message you are getting? Two suggestions to pinpoint the problem. Instead of [Price] attribute, test with the standard ASP.NET [Range] attribute. Suggestion 2 - Try debugging into the IsValid() method on PriceAttribute class to see which line is returning the validation error. That might give us additional ideas to narrow down the cause. – Naraen Apr 21 '11 at 16:10
  • I'm at the same point. With or without the [Price] attribute the message error is "The field InitialPrice must be a number" if I set a value like 3,49. I don't know...So the IsValid() method never fires, it stops before. – stuzzo Apr 22 '11 at 08:06
0

Your question is a bit unclear. From what I can understand you want your application to display in correct culture, not your Visual Studio.

To set date and double format (ie. Culture) you would do something like this in your applications Global.asax Application_Start() event:

System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("it-IT");
stuzzo
  • 1,056
  • 1
  • 15
  • 36
juhan_h
  • 3,965
  • 4
  • 29
  • 35
  • Hi, thanks for the answer. I Add these two lines System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("it-IT"); System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("it-IT");, but it doens't work. If I try to define a price like that 23,03, the validator fires with the message "The field PrezzoIniziale must be a number(very ugly :( )". – stuzzo Apr 21 '11 at 13:35
  • 2
    Curious... Application_Start() will run only when once when the application starts. I would guess setting the culture will only set it for the thread that is executing Application_Start() and not for subsequent HTTP requests. Thoughts? – Naraen Apr 21 '11 at 15:00