I've a problem when adding metadata to a class named as a reserved keyword. During the generation of the data model (the DBML file), an # has been added to the class name to have it working.
When I apply metadata to the class, it is not working (metadata info is not taken in consideration - the DisplayName and other validation stuff). For all other classes of my project (that do not have a class name as a reserved keyword, it is working). It is currently not possible to rename that class.
Generated class definition:
[global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.operators")]
public partial class #operator : INotifyPropertyChanging, INotifyPropertyChanged
{...}
MetaData class definition:
[MetadataType(typeof(OperatorMetaData))]
public partial class #operator
{
}
public class OperatorMetaData
{
[DisplayName("Operator Type")]
[Required(ErrorMessage = "Operator type is required.")]
public int operator_type_id { get; set; }
...
}
Anyone any idea how to work around this? Or what did I do wrong ?
Related
I have ignored a column through fluent API but want to populate that property while executing stored procedure using some logic. But it is not mapping the ignored column property. Please let me know if there is any way to do this in Entity framework code first.
I've faced with the same problem recently. The only solution I found is a class hierarchy:
public class MyEntityBase {
public int Id { get; set; }
}
public class MyEntity: MyEntityBase {
...
}//This class is mapped to DB with a fluent API and does not contain ignored property.
//Also it does not have derivative classes, so EF will not create class inheritance in DB.
public class DerivedEntity: MyEntityBase {
public int IgnoredProperty { get; set; }
}//Use this class while executing stored procedures
P.S. Do not mark class MyEntityBase as ABSTRACT - EF will map this relationship as database inheritance.
I have come across a scenerio that to customize DataAnnotations in Dynamic Data Web Application. This is the scenerio:
[Display(Name="DispName")]
public string DName{get;set;}
Instead of hardcoding Name="DispName" for Display DataAnnotation, I want to fetch some value from DataBase and fit int the Name attribute. like:
[Display(Name=SomeValueFromDB)]
public string DName{get;set;}
Is there any way to show the Name attribute of Display DataAnnotation from database instead of hardcoding its value?
Thanks in advance,
Sujith
I found a solution. But this is applicable only if we build the application:
Create a custom class (Say: CustomDisplayNameAttribute ) which inherits DisplayNameAttribute. And call that class name as display attribute (here "CustomDisplayName") above the property name.
While setting DataAnnotation for Display attribute, omit that "Attribute" part from the class name. ie. the DataAnnotation for Display attribute will be CustomDisplayName (not CustomDisplayNameAttribute).
public class DomainClass
{
[CustomDisplayName("")]
public object PropertyName{ get; set; }
}
public class CustomDisplayNameAttribute : DisplayNameAttribute
{
public CustomDisplayNameAttribute(string value)
: base(GetMessageFromResource(value))
{ }
private static string GetMessageFromResource(string value)
{
return "Custom Display Name";
}
}
Hope this helps all....
Happy Coding....
I am using MVC4 with EF5 database first and Newtonsoft.Json for serializing objects to JSON for example in Web API controllers.
To avoid the problem of self referencing loops i set the attribute [JsonIgnore] to the specific collections in my generated classes.
My problem is now that each time i update my model i have to readd the attributes to the classes.
How can i avoid that? I think i have to edit the DBModel.tt script? What have i to do?
You should be able to use a metadata class with the MetadataType attribute. If your generated class is:
public partial class MyClass{
public string SomeProperty {get; set; }
public string SomePropertyToIgnore {get; set; }
}
Then you need to create a metadata class like so (in the same namespace):
public class MyClass_Metadata{
[JsonIgnore]
public string SomePropertyToIgnore {get; set; }
}
The create a partial of your generated class (in the same namespace) with the MetadatType attribute applied:
[MetadataType(typeof(MyClass_Metadata))]
public partial class MyClass{
}
Ref: http://msdn.microsoft.com/en-us/library/ee707339(v=vs.91).aspx
I am just extending my this question a bit.
I have my App_LocalResources in my MVC web application (I don't have it in separate dll).
I have a my Model in different assembly. In the Model I have 2 classes Country and City:
public class Country: MyContainer
{
public City city {get;set;}
}
public class City
{
public CityName {get;set;}
}
public class MyContainer
{
public Cid {get;set;}
}
So in my action method I create and pass an object of country as my viewmodel.
And in the view I use this:
#Html.LabelFor(mdl=>mdl.City.CityName)
#Html.LabelFor(mdl=>mdl.Cid)
So this works well and label with text are rendered in English.
But how do I modify this so that it reads the text from my Resource files in my web application?
You could write a custom display attribute:
public class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
public LocalizedDisplayNameAttribute(string key): base(FormatMessage(key))
{
}
private static string FormatMessage(string key)
{
// TODO: fetch the corresponding string from your resource file
throw new NotImplementedException();
}
}
and then:
public class City
{
[LocalizedDisplayName("cityname")]
public string CityName { get; set; }
}
You may also checkout the following localization guide. It provides a full implementation of a sample attribute.
You can use [Display(ResourceType = typeof(App_LocalResources), Name = "AgreeTandCs")] where App_LocalResources is the name of the resource class (your .resx) and Name is the name of the static string you want to reference. Use LabelFor as usual in your view, and it will automagically pull in your resource.
In my example, the label displays the string stored with the variable name AgreeTandCs, and if you're viewing it in English it will be shown in the page as "I agree to these Terms and Conditions".
You can also use translation with {0}, {2} parameters inside translation string.
He is my example Localize Compare attribute
I'm trying implement Data Annotation to my Linq to SQL objects. The .dbml file is generated and I'm not sure how to add data annotation to the objects without touching the generated source code.
I tried to add data annotations to the a separate partial class of the object, but its not recognizing it, no Intelli sense either.
As I said in my original answer to this question, you should use an interface. The answer posted after mine (which was marked as Accepted) said to use a class. This is not as good. An interface is a better option for the following reasons:
If there is a mismatch between the name in your LINQ class and the name in your interface, the compiler will flag it for you
An interface can not be instantiated, so this protects class users from accidentally instatntiating the metadata type
If you use Resharper (or similar), the interface can be automatically extracted from the LINQ class
An interface is less verbose than an empty class
If you program against interfaces rather than classes (which is a good practice), then you've already got an interface you can use as your metadata type
For a class called, say "User", create an interface for it (say 'IUser'), and then update the definition of your partial User class as follows:
[MetadataType(typeof(IUser))]
public class User : IUser
Then, in your IUser interface, add appropriate Data Annotation attributes to the properties:
[Required]
[StringLength(50, ErrorMessage = "Username cannot exceed 50 characters")]
string Username { get; set; }
For a class called, say "User", create an interface for it (say 'IUser'), and then update the definition of your partial User class as follows:
[MetadataType(typeof(IUser))]
public class User : IUser
Then, in your IUser interface, add appropriate Data Annotation attributes to the properties:
[Required]
[StringLength(50, ErrorMessage = "Username cannot exceed 50 characters")]
string Username { get; set; }
Linq to SQL generates object classes as partial. An easy way to implement data annotations is to create your own partial class of the object, place the [MetadataType(typeof(YourDataAnnotationClass))] on the partial class you created.
Example:
// Linq to SQL Class
public partial class Article
{
public string Title { get; set; }
...... etc
}
Create your own MetaData class with Metadata for each field you want to validate
public class MyMetaDataClass
{
[Required]
[Range(5,20)]
public string Title { get; set; }
}
Create a Partial Class for the Object class you want to add metadata to, in this case Articles class:
[MetadataType(typeof(MyMetaDataClass))]
public partial class Article { }
Note: you don't need to specify anything in the class, just the metadata type.
Thanks,but the problem is MS define the prototype of MetadataTypeAttrubute as
[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public sealed class MetadataTypeAttribute : Attribute
So, you had to use class but not interface
From China
Forest Lee: 李晓强
xiaoqianglinsen#163.com (MSN)
lixiaoqiang#webservice.com.cn