4

I have a edmx model created from a database and a metadata.cs for it.

In the client, the .g.cs includes [StringLength(X)] attributes alongside my attributes from my metadata.

I am doing some serverside validation for a flat file import that is seperate to the client side editors of these entities.

I am able to apply my range and regular expression validations but I am unable to find the StringLength attribute on the server. Does anyone know how to do this without duplicating the StringLength attributes manually on the metadata properties.

Edit:

Here is some code:

Server side file ProductService.metadata.cs:

internal sealed class PRODUCTMetadata
{
  [Required]
  [RegularExpression("[A-Z]+")]
  [Display(Name = "Product Code", Order = 10)]
  public string Product_code { get; set; }
}

Client side Generated_Code\NameSpace.Web.g.cs:

public sealed class PRODUCT
{
  [DataMember()]
  [Display(Name="Product Code", Order=10)]
  [RegularExpression("[A-Z]+")]
  [Required()]
  [StringLength(8)] //This is what I want to know, but server side
  public string Product_code
  {...etc
  }
}
ken2k
  • 48,145
  • 10
  • 116
  • 176
weston
  • 54,145
  • 21
  • 145
  • 203
  • Please specify what do you mean under client and server? do you have a WCF service, other type of service or some kind of Web UI client? – Sasha Feb 07 '12 at 14:23
  • @OleksandrPshenychnyy It's a "Silverlight-enabled WCF service" on an ASP web site project on the server side. The client side is Silverlight, and that is where the auto generated `.g.cs` file resides, which is correct, but I don't have access to that from the server code. – weston Feb 07 '12 at 14:27
  • Sorry, I'm not expirienced in Silverlight. But in general it is not a good practice to use the same object for DB access and communication through WCF service. Actually I don't understand why edmx file generates some atributes on client? Does your client have direct access to DB??? That's server responsibility. – Sasha Feb 07 '12 at 14:35
  • No it doesn't, it's just the way the EF services work. The client side attributes are to enable client side validation. I've added an example. It's not a Silverlight question really, as I want to do this without the client being involved at all, it just happens that the client's automatically generated code knows more than the server does! – weston Feb 07 '12 at 14:39
  • I ran into the same question 2 days ago. Is your `ProductService.metadata.cs` file generated by EF (server-side), or is it a custom metadata file that you created yourself? – ken2k Feb 08 '12 at 14:42
  • @ken2k Generated by entity framework. – weston Feb 08 '12 at 14:59

1 Answers1

2

I've investigated a bit around this problem, and couldn't find any good information about the topic on the Internet. So what' I'll say here is only assumption.

As you have seen, the auto-generated client proxy code is much more decorated with attributes than the server-side code. Your entities for instance have the nice [StringLength(8)] attribute that comes from the Entity Model. On the server side, the auto-generated .metadata.cs file doesn't have those attributes on entities. I think it's all about code-generation templates.

I suspect that the code generation template of RIA Services (that creates the .g.cs file) is much more complete than the template that creates the .metadata.cs file on server side.

The fact that the attribute that is missing in your case is 95% of time used for UI validation on client-side might explain why the template for the .metadata.cs file doesn't produce those validation attributes.

I see 2 work-arounds for your problem:

1. Write your own metadata class on server side

Some example:

[MetadataTypeAttribute(typeof(PRODUCT.PRODUCTMetadata))]
public partial class PRODUCT
{
    internal sealed class PRODUCTMetadata
    {
        // Metadata classes are not meant to be instantiated.
        private PRODUCTMetadata()
        {
        }

        [StringLength(8)]
        public string Product_code { get; set; }
    }
}

You can manually add any attributes to the properties of your entities, as entities are partial classes.

Unfortunately, you'll have to maintain those metadatas each time you modify your model: if (for example), your DB table column changes from varchar(8) to varchar(10), you'll be able to automatically update your EDMX model from your database, but you'll have to manually check that your metadatas are still OK (in this example, you would have to manually replace [StringLength(8)] by [StringLength(9)]).

Here's a nice link about metadata.

2. Modify the T4 templates

Second option is probably the best one, but I didn't experienced myself the code generation template modification, so I don't known what can effectively be done or not.

Code generation templates are known as T4 templates (Text Template Transformation Toolkit). It is possible to modify those templates to include anything you want in the code generation process. You could modify the default EF template so it generates the missing attributes just as the RIA Services template does.

Here's some nice articles about T4 code generation:


I write this as an answer (it wouldn't fit as a comment), but remember it's all assumptions.

ken2k
  • 48,145
  • 10
  • 116
  • 176
  • 2
    Thanks very much, really appreciate the effort you've gone to! I will take a look at modifiying the templates :) – weston Feb 09 '12 at 11:15