Centralizing Regular Expression Validation Patterns in ASP.Net MVC - c#

I there a way in ASP.Net MVC to have a RegularExpression attribute on a model property to pull the pattern string property from resource file or another class?
When I attempt to use another class I get a message stating that the attribute values must be a constant, typeof expression, or an array.
Ultimately, I'm attempting to abstract some of these patterns so I don't have to update multiple files if a bug is located in a pattern.
Example:
public class MyModel{
[RegularExpression(StaticPatternClass.EmailPattern, ErrorMessage="invalid email")]
public string email { get; set;}
}
public static class StaticPatternClass{
public static string EmailPattern = #"My pattern here";
}

Try
public const string EmailPattern ....
instead

The error description is quite clear, it needs to be a constant. A constant value is compiled and cannot be changed. However a regular static string might be changed (more exactly replaced as strings are immutable) during the execution of the program which is not allowed. Try this instead:
public static class StaticPatternClass{
public const string EmailPattern = #"My pattern here";
}

Related

Const string referencing another const string - how to avoid DRY without readonly

public static class Abc
{
public const string Placeholder = "{$content}";
public const string Pattern = $"<div class=\"embed-responsive\">{Placeholder}</div>";
}
How to correctly solve this to avoid breaching DRY (Dont repeat yourself)? I know I can use static readonly, but then it is a bit of a different thing (even though it works..). I think there should be better way? Or is there really not?
While you cannot call a method to initialize a constant value, it is allowed to use operators. If you need to create a constant that contains another constant value, use the plus operator to concatenate string values.
public static class Abc
{
public const string Placeholder = "{$content}";
public const string Pattern = "<div class=\"embed-responsive\">" + Placeholder + "</div>";
}

C# - Serialize Constants with DataContractJsonSerializer

I'm having the following class:
[DataContract]
class ExampleClass
{
//Properties
[DataMember(Name = "method")]
private const string method = "Example Constant";
...
...
The DataContractJsonSerializer don't seem to include the constant "method" in the JSON output.
How can I keep the member constant, and cause the class to serialize it?
Thank you.
For the JSON-output the const is not accessable at all as it´s private. However serializing a const makes no sense at all, as a const is a static member and belongs to the class itself, not to a specific instance. Therefor the serializer can´t set it on an instance as there is nothing to set on that instance.
Having said this you may wrap your constant in a property:
[DataContract]
class ExampleClass
{
private const string method = "Example Constant";
//Properties
[DataMember(Name = "method")]
public string Method { get; set; }
public ExampleClass(this.Method = method; }
}
PS.: I´m not familiar with contract-serializers, but this is what you would do with an Xml-serializer. Maybe with contract-ser you can also have a get-only property thus you won´t need the extra constructor, but I´m not sure about this.
const is a special keyword in .NET. If you specify field as constant, it would not exist in compiled code, but all the references of constant would be replaced with values of constant at compile time. Therefore this constant does not exist in compiled code and so it is not serialized as well.
The easiest way to fix it is to change constant to regular field (or property) and assign the value in constructor:
[DataContract]
class ExampleClass
{
public ExampleClass()
{
method = "Example Constant";
}
[DataMember(Name = "method")]
private string method;
Alternatively, you can use property:
[DataMember(Name = "method")]
private string Method { get; set; }
Constants are like normal variables. The only difference is that they will replace with the value on compile time.
JSON is a format for transporting data, therefore it does not have any reason for doing something special about constants. But if you have special types like classes or even enums where the name make a difference in the meaning, then there will be additional properties in JSON

Where to define constants and use them anywhere?

In Java I would write something like
public interface ICar {
static String RED_CAR = "/res/vehicles/car_red.png";
static String BLUE_CAR = "/res/vehicles/car_blue.png";
static String GREEN_CAR = "/res/vehicles/car_green.png";
}
Because C# doesn't allow using fields in interface, where do I define this constants in C#, when I wish to use them more than once?
You can define a static class to contain your constants (which need to be public as by default fields without modifier are private):
public static class Car
{
public const string RED_CAR = "/res/vehicles/car_red.png";
public const string BLUE_CAR = "/res/vehicles/car_blue.png";
public const string GREEN_CAR = "/res/vehicles/car_green.png";
}
After this you can use constants like Car.RED_CAR.
If all your constants are files it's better to include them in your resources.
In your project properties there's a resource section, vs can create a Resources.resx if you need one.
In there you can add all sorts of files or strings (for translations mostly).
You can then access them through Properties.Resources.RED_CAR
I would not name them like that though. It's from the time when all variables where globals and naming conventions like that where needed to know what was stored in the variable. But when accessing your data like this it's always clear what's going on.

is it possible to have a getter/setter template in c#?

I want to apply this:
private string _name;
public string name
{
get { return _name; }
set { _name = Fix(value); }
}
to all string the members of a class, and don't want to repeat the same code for all the class members.
An obvious solution would be to put that code on a class to handle the problem and declare all string members as: myString instead of string, however that would mean that I would have to access the main class members like this: email.fixed instead of just email.
So I was wondering, is there is some kind of template I can define and then apply easily?
You could create a Code Snippet for Visual Studio to handle building a property this way.
MSDN includes documentation on Creating a Code Snippet, which can include replacement parameters (the name).
You might want to research Aspect Oriented Programming, which allows you to easily do things like this.
http://www.codeproject.com/Articles/337564/Aspect-Oriented-Programming-Using-Csharp-and-PostS
Create a type with an implicit conversion to and from string:
public class FixedString
{
private string str;
public FixedString(string str){this.str = str;}
public static implicit operator FixedString(string str)
{
return new FixedString(Fix(str));
}
public static implicit operator string(FixedString fixed)
{
return fixed.str;
}
}
You can now create a property of this type, but treat it as if it's a string.
Create a regex replace and use Visual Studio's (v2012/2013) find and replace regex functionality.
For example let us say you have a field like this to change into a property
public string Name;
and you want to change it to have a backing field and the setter you desire.
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = Fix(value); }
}
The find /replace regex pattern in Visual Studio to find is this
public\s+string\s([^;]+);
the replace pattern (with appropriate line spacings and tabs) is this
private string _$1;\r\n\r\n\tpublic string $1\r\n\t{\r\n\t\tget\r\n\t\t\t{ return _$1; }\r\n\t\tset\r\n\t\t\t{\r\n\t\t\t\t_$1 = Fix(value);\r\n\t\t\t}\r\n\t\t}
Then step through the finds and do a replace as needed within your class.
I have done similar to add INotifyChange method calls on blank properties created after doing the code snippet <tab><tab>prop action.

How can I assign a property to an attribute

I would like to assign a property string to below attribute.
[ExtractKeyAttribute(**"Extraction"**)]
public class Extract
{
....
}
so extraction is my string but I don't want hard code into there. Any suggestions on better way to assign
You can't do this.
Attribute values must be constant expressions. The values are baked into the compiled code. If you don't want to use a constant expression, you can't use an attribute... and you possibly shouldn't. It may mean you're using attributes when you should be using a different approach.
You might want to read Eric Lippert's blog post on properties vs attributes.
Of course, you don't have to use a string literal there. You could have:
[ExtractKey(ExtractionKeys.Extraction)]
...
public static class ExtractionKeys
{
public const string Extraction = "Extraction";
}
... but it's still a compile-time constant.
In your comments you say you have all (string) values in a static class. Is your static class a class with readonly properties? I mean, do the values change? If not, replace some of those properties in your static class with const strings values. U can use these values to set your attribute.
So...
static class MyClass
{
public string MyValue {get;}
}
would become:
static class MyClass
{
public const string MyValue= "MyValue";
}
Now your attribute can be set as follows:
[ExtractKey(MyClass.MyValue)]
If you want to modify the property of your attribute during runtime, then you can do this with this code:
ExtractKeyAttribute myAttribute = typeof(Extract).GetCustomAttributes(typeof(ExtractKeyAttribute), false)[0] as ExtractKeyAttribute;
myAttribute.MyValue = "MyRunTimeValue";

Categories