How to set/remove attributes dynamically in c#? - c#

I am using from attribute validation in my project.
[Required(ErrorMessage = "DepartmentCode is Required")]
public string DepartmentCode { get; set; }
In some case DepartmentCode isn't required. How can I dynamically ignore Validation in my case?

Take a look at: Remove C# attribute of a property dynamically
Anyway I think the proper solution is to inherit an attribute from RequiredAttribute and override the Validate() method (so you can check when that field is required or not). You may check CompareAttribute implementation if you want to keep client side validation working.

Instead of dynamically adding and removing validation, you would be better served to create an attribute that better serves this purpose.
The following article demonstrates this (MVC3 with client-side validation too):
http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx

I would remove the RequiredAttribute from your model and check it once you've hit your controller and check it against whatever causes it to not be required.
If it falls into a case where it is required and the value is not filled in, add the error to the ModelState manually
ModelState.AddModelError("DepartmantCode", "DepartmantCode is Required");
You would just lose the validation on the client side this way

I've got round this issue in the model, in some cases it's not ideal but it's the cheapest and quickest way.
public string NonMandatoryDepartmentCode
{
get
{
return DepartmentCode;
}
set
{
DepartmentCode = value;
}
}
I used this approach for MVC when a base model I inherited contained attributes I wanted to override.

Related

Handling multiple forms on the same Razor Page

Has anyone found a trick for handling multiple forms on a Razor Page?
My page has two forms, each with a corresponding model that is decorated with a BindProperty attribute.
[BindProperty]
public TripDetailsUpdateDto UpdateTrip { get; set; }
[BindProperty]
public TripNoteUpdateDto UpdateNote { get; set; }
The problem is that, although either one works fine on its own, having both of them causes ModelState.IsValid to return false. Both models are combined and when one model is submitted, the properties of the other model haven't been set.
Surely I'm not the first to struggle with this. Is there a way to deal with this case without writing manual code to remove the unused items from ModelState?
So, as suggested, the problem is that every property of every model decorated with the [BindProperty] is combined into the ModelState.
To resolve the issue, first remove all [BindProperty] attributes.
Then bind to your values with a parameter:
public async Task<IActionResult> OnPostUpdateNoteAsync(int noteId, TripNoteUpdateDto updateNote)
{
// ...
}
Notes:
You can still have the original model members (in my case, UpdateTrip and UpdateNote). You can still reference them from your markup. This allows your markup to consider validation attributes, and also lets you specify default values.
If your markup references your original model members, your model argument must have the same name in order to match.

Custom field validation error in ASP.NET Core 5.0 MVC

I somewhat can't wrap my head around it.
Lets assume simplest model possible:
public class Model
{
[Required]
[MaxLength(128)]
public string Name {get;set;}
}
If you now use it in form and declare validation, it will work. But default messages are not the most pleasant for average user (Field must be an array of length X etc).
And now comes my question, how to create custom validation error? I have seen one useful topic that I can't find anymore, but they were overriding some function and there was no info provided how to call it.
I'm mostly interested in MaxLength, because for Required you can just set Display, which won't work for MaxLength.
If you only want to change the default message try it with
[Required]
[MaxLength(128, ErrorMessage = "YourCustomMessageString")]
public string Name {get;set;}

Apply Required Attribute if the value was binded by Model Binder

I have to handle following validation scenario:
If Some condition is met then we're displaying textbox which should be mandatory
If not met value for the property should be optional
Model Looking kind of this:
public class Setting
{
[Required]
public string Domain { get; set; }
}
Is that possible to differentiate somehow when field value was omitted or it didn't bind? Cause as I know if the value was omitted or not bound the value of it would be a default(string). In this case, I'm not able to definite should Domain be provided or not
If you have situations where it may or may not be required, you're best bet may be to have your Setting class inherit from IValidatableObject and implement your own Validate() method. Do whatever checksyou need to to see if it's required or not and do a yield return new ValidationResult("Description", new[] { nameof(Domain ) }) to explain why it's not valid.
If you can't make that determination inside your Settings class, then you'll likely have to do it in your controller action, and use something like ModelState.AddModelError("Description", nameof(model.Domain))); followed by checking ModelState.IsValid to see if the action should kick out and return a redirect/view

MVC how to disable the required validation for some controls

I am creating a web application using MVC 4.
I have a few properties in my view model that has been decorated with the required attribute as shown,
[Required(ErrorMessageResourceName = "StateRequiredMessage", ErrorMessageResourceType = typeof(Resources.Agency.CreateEdit))]
public int? PostalAddressStateId { get; set; }
but then in my view, depending on what the user selects from a tick box, I disable some of the properties that have been tagged as required.
I disable the controls using jQuery:
$("#PostalAddressStateId").attr("disabled", true);
Then when I try to save, it says the value is required. How do I solve this?
Try
ModelState.Remove("PostalAddressStateId");
at your controller
Try this:
PostalAddressStateId.Attributes.Remove("Required");
You might need to set a boolean in javascript and send it back to the controller, the required attribute impacts your server side code as well.
In my opinion, a field like this shouldn't be marked as required unless it's always required. If this is in a viewmodel, then I'd probably remove the attribute and replace it with a custom attribute or some other way of determining that it's filled in when it must be and not filled in when it's not required.
More about attributecollections here:
http://msdn.microsoft.com/en-us/library/system.web.ui.attributecollection.remove(v=vs.110).aspx
I would check out MVC Foolproof Validation on CodePlex. You could use the RequiredIfTrue attribute that comes with Foolproof to solve the issue above.
http://foolproof.codeplex.com/

Mvc ModelState KeyFor property

Whenever there is some custom validation to do or any fiddling with ModelState I had to rely on magic strings (that reflect property names) so far. Surely there must be a better way.
say you have a form with 2 submit buttons. You've already set validation rules by adding Required attributes:
public class MyModel
{
[Required]
public string ValueOne { get; set; }
[Required]
public string ValueTwo { get; set; }
}
This will always validate both fields. But say I've added two buttons to the form showing and editor for above model. Button one only requires ValueOne and button two only required ValueTwo.
Typically I would have custom validation code that checks which button was clicked and do something along the lines:
private void ValidateViewModel(MyModel viewModel)
{
foreach (var key in ModelState.Keys)
ModelState[key].Errors.Clear();
if (Request[{ButtonOneName}] != null && string.IsNullOrEmpty(viewModel.ValueOne))
ModelState.AddModelError("ValueOne", "Required");
else if (Request[{ButtonTwoName}] != null && string.IsNullOrEmpty(viewModel.ValueTwo))
ModelState.AddModelError("ValueTwo", "Required");
}
Not very pretty, I know but ... My beef is with magic string "ValueOne" and "ValueTwo". Also with the way errors are cleared out. Is there a way to generate those keys? I'm looking for something like:
ModelState.KeyFor<MyModel>(m => m.ValueOne)
And then a logical extension:
ModelState.Get<MyModel>(m => m.ValueOne)
Before I start reinventing the wheel - is there something like this hidden somewhere already?
Before you ask, I normally define static class SubmitActions, containing constant strings that represent submit button names. And no, I can't split it up into multiple forms because of the was the view is rendered.
Thanks for any suggestions.
There is a Model Validation Improvements in MVC 3, which will make you be able to check validate based on property related to each other
So by using the IValidatableObject interface built-into .NET 4 to implement a custom validation method on a class. This method can apply validation rules across multiple properties and yield back multiple validation errors,
Have you look at it?
Model Validation Improvements part

Categories