3

I used Database-First to generate a model class (EDMX file), and I want to validate using "MetadataType". I read solutions here but they didn't work for me.

Here is my code:

[MetadataType(typeof(MovieEntitiesMetaData))]
public partial class MovieEntities
{        
}

public class MovieEntitiesMetaData
{
    [DisplayFormat(DataFormatString = "{0:c}")]
    public Nullable<global::System.Decimal> PRICE { get; set; }
}

Is there anything missing here, or why did my solution did not work?

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
Eddy Setiawan
  • 77
  • 1
  • 7

1 Answers1

1

Create a new file called MoviePartial.cs and place the following code inside it:

[MetadataType(typeof(MovieMetaData))]
public partial class Movie
{    
    internal sealed class MovieMetaData
    {
        [DisplayFormat(DataFormatString = "{0:F2}", ApplyFormatInEditMode = true)]
        [Required(ErrorMessage = "Price is required")]
        public decimal? PRICE { get; set; }
    }
}

You also need to pass the Movie type to the view so that the data annotations can be wired up. If you have a custom view model the data annotations won't get in action.

In the Create/Edit view you must have:

@Html.EditorFor(m => m.PRICE)

In the Details view you must have:

@Html.DisplayFor(m => m.PRICE)

For more on this, just follow this nice step by step tutorial:

Validation with the Data Annotation Validators (C#)

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
  • I changed the code but still did not work, how to pass the MovieEntities to View? – Eddy Setiawan Oct 06 '12 at 05:02
  • What's the name of the object your view is going to consume? Is `MovieEntities` the name of your data context or is it the table name that came from the database? – Leniel Maccaferri Oct 06 '12 at 05:05
  • MovieEntities is the name of the Model/ConnectionString that save in web.config the table name Movie. But I change the class to Movie still did not work. Here is the model in the beginning on my View @model IEnumerable – Eddy Setiawan Oct 06 '12 at 05:15
  • I edited my answer to reflect the name of your entity - in this case `Movie`. Now, in your Controller action named `Create` just pass a new `Movie` object to the View and place `@model MvcApplication3.Models.MOVIE` at the top of the view file. You should see the validation in action. By the way: you did not specify any validation for the `Price` property. I'll add the `[Required]` one. See my answer. For a complete tutorial, see the link I provided you. – Leniel Maccaferri Oct 06 '12 at 05:18
  • Beside validation, I want to add display format for currency I think it work the same. But the display still the same as before. Is there any missing code that I left behind? – Eddy Setiawan Oct 06 '12 at 05:27
  • Edited my answer. Look here for more info: http://stackoverflow.com/q/5080451/114029 – Leniel Maccaferri Oct 06 '12 at 05:31
  • I change the metadata to [Required(ErrorMessage = "Price Required")] but the validation won't work. I don't how to use it. I used database first to generate model so I cannot edit file .cs that generated from visual studio. Could you help solved this issue? – Eddy Setiawan Oct 06 '12 at 05:41
  • You must create a file called `MoviePartial.cs` and add the code in my answer to that file. – Leniel Maccaferri Oct 06 '12 at 05:47
  • I have tried to create MoviePartial.cs but the validation and displayformat still did not work. The view is same as you mention on your answer. Is there any step that I need to do? – Eddy Setiawan Oct 06 '12 at 06:12
  • You must add a reference to jquery, jquery-validate and jquery-unobtrusive scripts in your `_Layout.cshtml` file. – Leniel Maccaferri Oct 06 '12 at 06:14
  • What should I add jquery-unobtrusive-ajax.js or jquery.validate.unobtrusive.js? I just add jquery-unobtrusive-ajax.js but did not work. My class that contain table is MovieEntities and the table represent with Movie Class, is there anything wrong about my information that give it to you? – Eddy Setiawan Oct 06 '12 at 06:25
  • You should add `jquery.validate.unobtrusive.js`. – Leniel Maccaferri Oct 06 '12 at 06:25
  • Still did not work. I think the error is in the model class, I also do that about the link you gave me. Is that because I did not add Microsoft.Web.Mvc.DataAnnotations.dll? I used ASP.net MVC 3 – Eddy Setiawan Oct 06 '12 at 06:38
  • Sorry my bad, the problem solved because I named my class MOVIE not movie so your answer has worked already. Thanks for your help – Eddy Setiawan Oct 06 '12 at 07:22
  • Question, will this work if I want to inherit from IValidatableObject? – Vyache May 14 '14 at 19:50
  • @Vyache yes... you can still do your validation with `IValidatableObject`. – Leniel Maccaferri May 14 '14 at 19:51
  • @LenielMacaferi, can you provide an example? I'm not able to do it. I have my data annotations in a private sealed class. The partial class inherits from BaseEntity, IValidatableObject and so you know, this is a database first. I'm not able to validate my custom validation, but my sealed data annotation work just fine. – Vyache May 14 '14 at 21:01
  • @Vyache why not? Check this: http://stackoverflow.com/a/3401178/114029 if it does not work, please ask a new questin here on StackOverflow and show us a sample of what you're doing and why it's not working. :) – Leniel Maccaferri May 14 '14 at 21:11
  • @LenielMacaferi actually, I figured out the issue. The client side validations need to validate first before the IValidateObject. – Vyache May 15 '14 at 14:34
  • @Vyache: in fact, client side validation is not tied to server side validation... you don't need client side val to do server side val. You mentioned `IValidatableObject` which is server side val. Anyways it's nice to know you got the result expected. – Leniel Maccaferri May 15 '14 at 14:42
  • @LenielMacaferi Sorry I meant that I wanted to do both. Thanks for the help. – Vyache May 15 '14 at 19:34