I have lots of property names with PascalCase names.
For example:
public string ProposalNotes { get; set; }
I am after overriding the default Html.DisplayNameFor() method to automatically split the property names to "Proposal Notes" without having to add the display attributes as below:
[Display(Name = "Proposal Notes")]
I want the DisplayName attributes to still work when I need to override this new convention. For example when I have property names like "PgCodeInst" to "Institution Code".
Is there any way of doing this?
I remember a tutorial on how to do something similar but cannot find it.
It's certainly possible, but I just went digging through the source a bit, and I think you're going to find it far more trouble than it's worth. There's multiple classes you'd have to derive from and override methods on, and then you'd have to wire in all your custom stuff in place of the built-ins.
Adding the Display attribute is not really all that much of a burden, and frankly is a bit more explicit in its intention, which is always a good thing. However, if you're dead-set against using it, you might instead consider using a library like Humanizer and just doing something like:
#nameof(Model.ProposalNotes).Titleize();
FWIW, you'd need to add the using statement to your view (#using Humanizer), but you can do that just once in _ViewImports.cshtml.
Also, depending on what you actually want the display name for, you can always just create a custom tag helper. For example, to automatically do this with labels, you can simply inherit from LabelTagHelper (or create your own) and use you own custom logic for determining the display name to show there, instead of worrying about changing the behavior of something like DisplayNameFor. You can also create a custom tag helper to just output the titleized name as above:
public class TitleizeTagHelper : TagHelper
{
const string ForAttributeName = "asp-for";
[HtmlAttributeName(ForAttributeName)]
public ModelExpression For { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "span";
output.SetContent(For.Name.Titleize());
}
}
Then:
<titleize asp-for="ProposalNotes" />
That's a bit of overkill for something so simple, admittedly, but you could beef it up by stealing the logic from LabelTagHelper to support custom display names, as well, if the attribute is actually applied.
Related
I see a lot of code snippets with this example:
private string _possessor;
public string Possessor
{
get { return _possessor; }
set { _possessor = value; }
}
My questions is, why not just use plain property as in:
public string Possessor { get; set; }
I was reading on the internet, but could not really see the difference? You can either way set values in both examples and second example requires less coding and looks cleaner.
In the case that you are showing, it's true, there are no differences on doing each approach and the second one is cleaner. Knowing the first approach is useful because sometimes you need a property to do more than just get/set so in that case you will need to use the first approach.
You can also see here that with each new c# version, different ways of implement properties were created. The second approach is Auto-implemented properties
The main purpose of doing this is to help achieve data Encapsulation, which helps us by hidden the data in a class from other classes. this is also known as data-hiding.
Another good reason why this is done is when there some special validation or special business rules that needs to be checked before we set that particular value.
You can read more on Encapsulation from this site https://www.geeksforgeeks.org/c-sharp-encapsulation/
I have to write custom attribute to check dependent property using MVC pattern. I am using System.ComponentModel.DataAnnotations for checking required fields.
My WPF application contains listview control. All my properties written in modal class get filled in listview when view is loaded first time.
I am providing functionality where user can include/exclude new property in listview. However I don't want to allow user to exclude those property on which other properties are dependent.
For example, If securitynumber property depends on employeename property. While excluding employeename, I want to display validation message that "securitynumber depends on employeename, so can't exclude employeename"
I need help in writing and using custom attribute for e.g
[Dependencyon("Employeename")]
public object securitynumber { get ;set ;}
and want to get value of "Dependencyon" wherever I needed.
You have three options:
A) You can use the CustomValidationAttribute and supply a custom built validator.
http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.customvalidationattribute.validatortype(v=vs.95).aspx
B) You can create a class that inherits from ValidationAttribute.
http://msdn.microsoft.com/en-us/library/cc668224.aspx
C) If you only want to do this on the MVC Action you can Create an ActionFilterAttribute as per gordatron's response.
I guess you are looking to create a custom filter.. Its been a while but from memory I think it would be something like:
public class Dependencyon : ActionFilterAttribute {
string field;
public Dependencyon (string field){
this.field = field;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
//check whether field is populated and redirect if not?
}
}
here is a starter on ActionFilters:
http://www.asp.net/mvc/tutorials/older-versions/controllers-and-routing/understanding-action-filters-cs
(I cannot remember details on constructor params for these so i may be way off.. sorry but i guess it wont take long to try)
When you decorate a model object's property with the Required attribute and don't specify ErrorMessage or ResourceType/Name you get the validation message in the interpolated form of "The {0} field is required.", where param 0 is the value of the DisplayName attribute of that property.
I want to change that default string to something else but I want to keep the generic nature of it, that is I don't want to specify ErrorMessage or ResourceType/Name for every property of the model object. Where is the default string stored and how can I change it?
Deriving your own attribute is a fair option and probably has the lowest overhead to get started, but you'll need to go back and change all your existing uses of [Required]. You (and any others on your team) will also need to remember to use (and teach newcomers to use) the right one going forward.
An alternative is to replace the ModelMetadataProviders and ModelValidatorProviders to return strings from a resource file. This avoids the drawbacks above. It also lays the groundwork for replacing messages for other attributes (e.g., MaxLengthAttribute) and for supporting additional languages.
protected void Application_Start()
{
var stringProvider = new ResourceStringProvider(Resources.LocalizedStrings.ResourceManager);
ModelMetadataProviders.Current = new LocalizedModelMetadataProvider(stringProvider);
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new LocalizedModelValidatorProvider(stringProvider));
}
Here is the full source, documentation, and a blog post describing the usage.
Have you tried creating a derived class of RequiredAttribute and overriding the FormatErrorMessage method? This should work:
public class MyRequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute
{
public override string FormatErrorMessage(string name)
{
return base.FormatErrorMessage(string.Format("This is my error for {0}", name));
}
}
I’m tracing down an unexpected behavior in MVC3, having to do with how it gets model metadata.
I had previously talked to one of my developers about using the same EditorTemplate for some data which is collected in two different areas of the system. The data fields are almost identical, except for the [Required] attribute. In one page certain fields are required, in the other page they are not. Theoretically this can be accomplished by using a base model which has the common attributes on each field, and inheriting those models, overriding the properties and adding additional validation attributes. For example:
class BaseModel
{
[Display(Name=”My Label”)]
public virtual string MyLabel { get; set ;}
}
class RequiredModel : BaseModel
{
[Required]
public override string MyLabel { get; set ;}
}
Then the View can be strongly typed to BaseModel, and calls to #Html.EditorFor(m=>m.MyLabel) in the view should pick up the correct attributes, depending on whether the actual instance of the model is a BaseModel or RequiredModel.
That’s the theory.
And in fact, it works well if you use the “old” HTML helper, e.g. #Html.TextBox(“MyLabel”). Those call ModelMetadata.FromStringExpression(field), which correctly gets the metadata from RequiredModel if the concrete model instance is RequiredModel. The newer helper methods call ModelMetadata.FromLambdaExpression(expression), which does NOT correctly get the metadata from the correct concrete instance.
Is this a bug in MVC? Intentional behavior? Is there a workaround, or a better way to address this problem?
This is of course a trivial example, the actual code we're dealing with has about 20 fields with some complex business rules and interaction, which is the same on both pages EXCEPT for which fields are required.
That's the theory.
No, that's not the theory. At least not mine.
My theory is to use separate view models for each views because the requirements of your views are different. So you would have this:
public class UpdateViewModel
{
[Display(Name = "My Label")]
public string MyLabel { get; set ;}
}
and:
public class CreateViewModel
{
[Display(Name = "My Label")]
[Required]
public string MyLabel { get; set ;}
}
Personally that's what I would do. I would totally sacrify DRY into designing view models because the requirements of my view change often and I want to have total control.
Obviously in practice I don't even bother with doing validation using declarative DataAnnotations attributes. They limit me. I use FluentValidation.NET which addresses problems like yours in a pretty elegant manner (by simply defining two different validators for the same view model - in case you decide to violate my theory and use the same view model in different views).
Now feel free to downvote my answer. I have just given my 2¢.
I've created some classes that will be used to provide data to stored procedures in my database. The varchar parameters in the stored procs have length specifications (e.g. varchar(6) and I'd like to validate the length of all string properties before passing them on to the stored procedures.
Is there a simple, declarative way to do this?
I have two conceptual ideas so far:
Attributes
public class MyDataClass
{
[MaxStringLength = 50]
public string CompanyName { get; set; }
}
I'm not sure what assemblies/namespaces I would need to use to implement this kind of declarative markup. I think this already exists, but I'm not sure where and if it's the best way to go.
Validation in Properties
public class MyDataClass
{
private string _CompanyName;
public string CompanyName
{
get {return _CompanyName;}
set
{
if (value.Length > 50)
throw new InvalidOperationException();
_CompanyName = value;
}
}
}
This seems like a lot of work and will really make my currently-simple classes look pretty ugly, but I suppose it will get the job done. It will also take a lot of copying and pasting to get this right.
I'll post this as a different answer, because it is characteristically different than Code Contracts.
One approach you can use to have declarative validation is to use a dictionary or hash table as the property store, and share a utility method to perform validation.
For example:
// Example attribute class for MaxStringLength
public class MaxStringLengthAttribute : Attribute
{
public int MaxLength { get; set; }
public MaxStringLengthAttribute(int length) { this.MaxLength = length; }
}
// Class using the dictionary store and shared validation routine.
public class MyDataClass
{
private Hashtable properties = new Hashtable();
public string CompanyName
{
get { return GetValue<string>("CompanyName"); }
[MaxStringLength(50)]
set { SetValue<string>("CompanyName", value); }
}
public TResult GetValue<TResult>(string key)
{
return (TResult)(properties[key] ?? default(TResult));
}
public void SetValue<TValue>(string key, TValue value)
{
// Example retrieving attribute:
var attributes = new StackTrace()
.GetFrame(1)
.GetMethod()
.GetCustomAttributes(typeof(MaxStringLengthAttribute), true);
// With the attribute in hand, perform validation here...
properties[key] = value;
}
}
You can get at the calling property using reflection by working up your stack trace as demonstrated here. Reflect the property attributes, run your validation, and voila! One-liner getter/setters that share a common validation routine.
On an aside, this pattern is also convenient because you can design a class to use alternative dictionary-like property stores, such as ViewState or Session (in ASP.NET), by updating only GetValue and SetValue.
One additional note is, should you use this approach, you might consider refactoring validation logic into a validation utility class for shared use among all your types. That should help prevent your data class from getting too bulky in the SetValue method.
Well, whatever way you go, what's executed is going to look like your second method. So the trick is getting your first method to act your second.
First of all, It would need to be [MaxStringLength(50)]. Next, all that's doing is adding some data to the Type object for this class. You still need a way of putting that data to use.
One way would be a binary re-writer. After compilation (but before execution), the rewriter would read the assembly, looking for that Attribute, and when finding it, add in the code for the check. The retail product PostSharp was designed to do exactly that type of thing.
Alternately, you could trigger it at run-time. SOmething like:
public class MyDataClass
{
private string _CompanyName;
[MaxStringLength(50)]
public string CompanyName
{
get {return _CompanyName;}
set
{
ProcessValidation()
_CompanyName = value;
}
}
}
That's still quite ugly, but it's a bit better if you have a number of validation attributes.
The first method using attribute sounds good.
Implement your attribute by inherit from the System.Attribute class and mark your class with AttributeUsage attribute to let your attribute being set on a field.
Then, using reflection, check for presence and value of the attribute before sending the value to the SP.
Thats provide you with lot more flexibility than the second method. If tomorow you decide to let your SP receive the first N chars of a too lengthly string, you won't have to modify all your code but only the one that interpret the attribute.
There are indeed some validation attribute in the framework but I wouldn't use those one because you could implies some behaviour you don't expect and because you won't be able to modify then in any way (liek if you want something like [MaxLength(50, true)] to specify that using the first 5O chars is OK.
It sounds like a business rule. So I would put it in a Company class (Since it is CompanyName), and do the validation there. I don't see why it would require copying and pasting if you have it encapsulated.
Either an attribute or your second example should be fine. The attribute allows for reuse in other classes with string length constraints, however.
Though not exactly the same thing, I recently became aware of .NET 4 Code Contracts in an MSDN article. They provide a convenient and elegant way of encoding and analyzing code assumptions. It's worth taking a look at.