2

I'm using Entity Framework to create my data objects. Here's what my designer.cs file looks like:

namespace MyApp.WebUI.Models
{
    ...

    [EdmEntityTypeAttribute(NamespaceName="MyAppDBModel", Name="AddressType")]
    [Serializable()]
    [DataContractAttribute(IsReference=true)]
    public partial class AddressType : EntityObject
    {
        ...
    }

    ...
}

I have a file called Validation.cs in which I want to keep all my validation for my entities. Here's what it looks like:

namespace MyApp.WebUI.Models
{
    public class Validations
    {
        ...

        [MetadataType(typeof(AddressTypesValidation))]
        public partial class AddressType
        {

        }

        public class AddressTypesValidation
        {
            [Required(ErrorMessage = "Address Type name is required.")]
            [StringLength(50, ErrorMessage = "Address Type name must be 50 characters or less.")]
            public string Name { get; set; }                
        }
    }
}

I have this in my view page:

<% Html.EnableClientValidation(); %>
<% using (Html.BeginForm("Edit", "AddressTypes", FormMethod.Post)) { %>

    <div class="editor-label"><%: Html.LabelFor(m => m.Name) %></div>
    <div class="editor-field">
        <%: Html.TextBoxFor(m => m.Name) %>
        <%: Html.ValidationMessageFor(m => m.Name) %>
    </div>
    <input type="submit" value="Save" />

<% } %>

But my validations aren't loaded. If I try to submit the form with no value for Name, I get an error message saying The value '' is invalid. instead of my error message.

What am I doing wrong?

Steven
  • 18,761
  • 70
  • 194
  • 296

3 Answers3

2

There is a fundamental flaw with your approach. It is generally understood that using your database objects as view models and having Mvc do its model binding on them is a very bad idea.

Darin has a great answer detailing the issues associated with using domain objects in views.

I think your issues are being caused because you're mix data objects with view models, and to quote Darin

About 60% of the question I am [Darin] answering on StackOverflow in the asp.net-mvc tag wouldn't have been asked if the OP have used a view model.

Community
  • 1
  • 1
Omar
  • 39,496
  • 45
  • 145
  • 213
  • 1
    I agree that using viewmodels is the way to go - but isn't it still possible to put validation on the business objects themselves? The viewmodel ultimately wraps those same properties, and I would think it's better to put the validation in one place - near the database - than replicate it across potentially multiple UI-focused implementations. – Kirk Broadhurst Feb 03 '11 at 05:51
0

I'm not sure if you can have a partial class then have another partial class that is a nested class. Try having the partial you've declared not be a nested class.

Edit: Just ran a quick test in VS (not the validation part) and you can't one part of a partial class in a nested type and have another part of the partial class as a non-nested type (or nested in a different type).

Brian Ball
  • 12,268
  • 3
  • 40
  • 51
0

I may be off the mark here, but I believe that the Required attribute simply means 'not null', and your StringLengthValidator is only checking for an upper bound. It's not failing because you are sending through a string - unfortunately it's the String.Empty.

You're using the overload

[StringLength(int upperBound, [Parameters])]

Instead, try

[StringLength(int lowerBound, int upperBound, [Parameters])]

something like this, if you want minimum length of 1:

[Required(ErrorMessage = "Address Type name is required.")]               
[StringLength(1, 50, ErrorMessage = "Address Type...")]
public string Name { get; set; } 
Kirk Broadhurst
  • 27,836
  • 16
  • 104
  • 169