Rectangle 27 40

You can create a custom Editor Template for the enum Airlines that will render a radio button list. In your Model you will have a property of type Airlines and tag this property with the Required attribute and set ErrorMessage = "select one item". Don't forget to include the jQuery validation for client side validation if you want it, usually just have to add @Scripts.Render("~/bundles/jqueryval") on your Layout or View. If you don't use the jQuery validation you will need to make the property nullable on the model because enums are just set to the first value by default so MVC will not see it as invalid. Remember if you change the property to nullable you will also need to change the Model type of your Editor Template to nullable as well.

To enable the Editor Template to render a radio button list for any enum, change the template to the following:

@model Enum
@foreach (var value in Enum.GetValues(Model.GetType()))
{
    @Html.RadioButtonFor(m => m, value)
    @Html.Label(value.ToString())
}
@model MvcTest.Models.Airlines
@foreach (var value in Enum.GetValues(typeof(MvcTest.Models.Airlines)))
{
    @Html.RadioButtonFor(m => m, value)
    @Html.Label(value.ToString())
}
public class TestModel
{
    [Required(ErrorMessage = "select one item")]
    public Airlines Airline { get; set; }
}
public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return View(new TestModel());
    }

    [HttpPost]
    public ActionResult Index(TestModel model)
    {
        if (ModelState.IsValid)
        {
            return RedirectToAction("Index");
        }

        return View(model);
    }
}
@model MvcTest.Models.TestModel
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
    @Html.EditorFor(m => m.Airline)
    <input type="submit" value="Submit" />
    @Html.ValidationSummary(false)
}

Thank you! I will try this and get back to you soon. What should I do if I don't want a certain enum to be shown in the list? Lets say all enums I am dealing with will have "Unknown". how can I make sure that it does not get rendered but also making sure that a value is selected in the list?

OK trying this does not quite work for me. I don't get the radio button list but instead just a textbox. how can I make a partial view perhaps and give it the enum and have that partial view take the enum and generically spit out the radio buttons for each item in the enums but also having the postback/submit bind the selected value to the view model?

If you want to keep a certain value out of the list simply place an if statement in the loop and check for it. Creating a partial view instead of an editor template should be fairly easy, the difference is just semantics really because editor templates are partial views. Simply create a partial view in whatever view\controller directory you want, though putting it in the shared directory may make more sense, then copy the code from the editor template into it. Than use @Html.Partial("partialViewName", model) and pass the enum from your main view model in as the model.

I don't know why you are getting a textbox instead of the radio button list. The code I posted worked for me when I ran it locally. Try checking your code and make sure it exactly matches what I posted.

also i get text box, how would the editorfor know that it should use that editortemplate(one with @model Enum)?

asp.net mvc - MVC4 enum and radio button list - Stack Overflow

asp.net-mvc asp.net-mvc-4
Rectangle 27 24

public class HttpPostedFileExtensionsAttribute : DataTypeAttribute, IClientValidatable
{
    private readonly FileExtensionsAttribute _innerAttribute =
        new FileExtensionsAttribute();

    /// <summary>
    ///     Initializes a new instance of the <see cref="HttpPostedFileExtensionsAttribute" /> class.
    /// </summary>
    public HttpPostedFileExtensionsAttribute()
        : base(DataType.Upload)
    {
        ErrorMessage = _innerAttribute.ErrorMessage;
    }

    /// <summary>
    ///     Gets or sets the file name extensions.
    /// </summary>
    /// <returns>
    ///     The file name extensions, or the default file extensions (".png", ".jpg", ".jpeg", and ".gif") if the property is not set.
    /// </returns>
    public string Extensions
    {
        get { return _innerAttribute.Extensions; }
        set { _innerAttribute.Extensions = value; }
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata,
        ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ValidationType = "extension",
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
        };
        rule.ValidationParameters["extension"] = _innerAttribute.Extensions;
        yield return rule;
    }

    /// <summary>
    ///     Applies formatting to an error message, based on the data field where the error occurred.
    /// </summary>
    /// <returns>
    ///     The formatted error message.
    /// </returns>
    /// <param name="name">The name of the field that caused the validation failure.</param>
    public override string FormatErrorMessage(string name)
    {
        return _innerAttribute.FormatErrorMessage(name);
    }

    /// <summary>
    ///     Checks that the specified file name extension or extensions is valid.
    /// </summary>
    /// <returns>
    ///     true if the file name extension is valid; otherwise, false.
    /// </returns>
    /// <param name="value">A comma delimited list of valid file extensions.</param>
    public override bool IsValid(object value)
    {
        var file = value as HttpPostedFileBase;
        if (file != null)
        {
            return _innerAttribute.IsValid(file.FileName);
        }

        return _innerAttribute.IsValid(value);
    }
}

Yes it should, since it is IClientValidatable it should emit the unobstrusive jquery attributes in the html

@bzlm - This works as expected with ASP.NET MVC5 and the newer JQuery Validation Unobtrusive Native library - this uses the more up-to-date JQuery Valdiation libraries.

Trying to use a localized error message with this wrapper but even when ErrorMessageResourceType and ErrorMessageResourceName is set on HttpPostedFileExtensionsAttribute it still uses the default error message. Any ideas how to localize error message?

Thanks for this, it works well, but I had an issue with client validation. I found that the method extension found in jQuery.Validation additional-methods.js already includes the '.' before the extension, therefore the client validation needs to pass in the extensions without the '.'. I have addressed it by changing the line rule.ValidationParameters["extension"] = _innerAttribute.Extensions; to rule.ValidationParameters["extension"] = _innerAttribute.Extensions.Replace(".","");

ASP.NET MVC 3: DataAnnotations.FileExtensionsAttribute not working - S...

asp.net-mvc-3
Rectangle 27 1

As to why, when form values are posted back to a controller, the DefaultModelBinder first binds the value to the property (using the SetValue() method of PropertyDescriptor). As the property is int and the value is string, it cant be set and the default value is assigned. It is not until this binding is complete that the validation process starts.

Not sure how you could achieve want you want, but creating a custom ModelBinder might be an option

You may also need a CustomModelBinderAttribute applied to the property NumberOfItems, which tells the ModelBinder to use only your custom ModelBinder for this property (you probably would not want to apply it to all properties of type int)

Sorry not for this case, but ModelBinder has lots of methods you can override such as OnModelUpdating() where you should be able to get the posted value before its bound and OnPropertyValidating() which occurs before validation that may allow you to alter the behaviour

asp.net mvc - Custom Validation Attribute - Valid Integer - Stack Over...

asp.net-mvc asp.net-mvc-4
Rectangle 27 0

public class HttpPostedFileExtensionsAttribute : DataTypeAttribute, IClientValidatable
{
    private readonly FileExtensionsAttribute _innerAttribute =
        new FileExtensionsAttribute();

    /// <summary>
    ///     Initializes a new instance of the <see cref="HttpPostedFileExtensionsAttribute" /> class.
    /// </summary>
    public HttpPostedFileExtensionsAttribute()
        : base(DataType.Upload)
    {
        ErrorMessage = _innerAttribute.ErrorMessage;
    }

    /// <summary>
    ///     Gets or sets the file name extensions.
    /// </summary>
    /// <returns>
    ///     The file name extensions, or the default file extensions (".png", ".jpg", ".jpeg", and ".gif") if the property is not set.
    /// </returns>
    public string Extensions
    {
        get { return _innerAttribute.Extensions; }
        set { _innerAttribute.Extensions = value; }
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata,
        ControllerContext context)
    {
        var rule = new ModelClientValidationRule
        {
            ValidationType = "extension",
            ErrorMessage = FormatErrorMessage(metadata.GetDisplayName())
        };
        rule.ValidationParameters["extension"] = _innerAttribute.Extensions;
        yield return rule;
    }

    /// <summary>
    ///     Applies formatting to an error message, based on the data field where the error occurred.
    /// </summary>
    /// <returns>
    ///     The formatted error message.
    /// </returns>
    /// <param name="name">The name of the field that caused the validation failure.</param>
    public override string FormatErrorMessage(string name)
    {
        return _innerAttribute.FormatErrorMessage(name);
    }

    /// <summary>
    ///     Checks that the specified file name extension or extensions is valid.
    /// </summary>
    /// <returns>
    ///     true if the file name extension is valid; otherwise, false.
    /// </returns>
    /// <param name="value">A comma delimited list of valid file extensions.</param>
    public override bool IsValid(object value)
    {
        var file = value as HttpPostedFileBase;
        if (file != null)
        {
            return _innerAttribute.IsValid(file.FileName);
        }

        return _innerAttribute.IsValid(value);
    }
}

Yes it should, since it is IClientValidatable it should emit the unobstrusive jquery attributes in the html

@bzlm - This works as expected with ASP.NET MVC5 and the newer JQuery Validation Unobtrusive Native library - this uses the more up-to-date JQuery Valdiation libraries.

ASP.NET MVC 3: DataAnnotations.FileExtensionsAttribute not working - S...

asp.net-mvc-3
Rectangle 27 0

As to why, when form values are posted back to a controller, the DefaultModelBinder first binds the value to the property (using the SetValue() method of PropertyDescriptor). As the property is int and the value is string, it cant be set and the default value is assigned. It is not until this binding is complete that the validation process starts.

Not sure how you could achieve want you want, but creating a custom ModelBinder might be an option

You may also need a CustomModelBinderAttribute applied to the property NumberOfItems, which tells the ModelBinder to use only your custom ModelBinder for this property (you probably would not want to apply it to all properties of type int)

Sorry not for this case, but ModelBinder has lots of methods you can override such as OnModelUpdating() where you should be able to get the posted value before its bound and OnPropertyValidating() which occurs before validation that may allow you to alter the behaviour

asp.net mvc - Custom Validation Attribute - Valid Integer - Stack Over...

asp.net-mvc asp.net-mvc-4
Rectangle 27 0

I think the validation still assumes that you want to work with a valid model. Even though you just bind 2 properties now, the default values of the other properties could still ensure a valid model. If you want to work with this partly invalid model and ignore the other fields you can also check specifically for those 2 properties, if you use the IsValidField method where you can pass the name of the property:

What I don't fully understand is why you get such a validation error if you have no required attribute on that property. Or is it just truncated in your question?

Alternatively, you could have a model class for this scenario that has just those 2 fields. It would probably better describe the situation, and also the update of the database entry would be more clear (looking up an existing entity by id (btw where is the id coming from currently?), and setting the properties of the persistent entity with the model properties coming with the post. I still wonder whether the code in the "if valid" branch would really save something as you expect it...)

The myString1 field had already been marked as required, but I removed that, so I don't understand why it is still required. I even made it nullable in the database. Concerning the id field, I put a hidden field for MyObjectId in the view. However, I think I event tried without the hidden field, and I had the same result, so I don't really understand how the application "new" which myObject I was updating. As I still don't understand how "Bind" works and what it is supposed to do. I will try your solution with a View Model (is that what it is?). It looks like a good solution.

binding - ASP.Net MVC 3 - Bind Include/Exclude and validation - Stack ...

asp.net-mvc-3 binding
Rectangle 27 0

The DropDownListFor doesn't support this. You will need to write a custom helper or do it with javascript. This being said setting a value for the default choice wouldn't make sense as it will also break validation logic for required properties.

c# - Possible to give Html.DropDownListFor() option label a value? - S...

c# asp.net-mvc asp.net-mvc-3
Rectangle 27 0

It doesn't matter if the database accepts nulls. The ModelState will not return valid if the value does not pass the validation. Add a default value that will pass the validation.

c# - why can not disable datetime required attributes MVC model? - Sta...

c# asp.net-mvc asp.net-mvc-3 data-annotations
Rectangle 27 0

The issue you are facing might be because of the behaviour of the default configuration when it comes to data validation. You have a Required attributed on a non-nullable type and since int can't be null, it will always have a value (the default of 0) if the incoming request does not provide the value.

In these cases, the model validator will throw an exception because it doesn't make sense to have a Required attribute on a property that can't be null.

The straightforward way you would be to change a setting on your MVC application:

DataAnnotationsModelValidatorProvider
    .AddImplicitRequiredAttributeForValueTypes = false;

This will get rid of the error that is thrown by the framework. This introduce the problem that you will get a value of 0 even when the request does not include the property. It makes more sense to have your integer be of Nullable<int>. The Required attribute will be able to handle a null value and you will know whether or not the incoming request included the property

public sealed class Test    
{
    [Required]
    public int? Id { get; set; }
    [Required]
    public string Name { get; set; }
}

.AddImplicitRequiredAttributeForValueTypes = false; is good to know, but actual problem is not public int? in my case. I converted my Project from 4 to 4.5 and the problem is gone. Previous project with framework 4, malfunctioning some how. (surprisingly but it is true)

asp.net mvc 4 - How to work with [Required] attribute & Model State Va...

api asp.net-mvc-4 asp.net-web-api web-api wcf-web-api
Rectangle 27 0

It appears the error was being triggered when binding on postback. If the date was invalid, it would recognise there was an error, and would set the value of DateOfBirth to null, which would pass the custom validation. However, it had already failed, hence the default message being returned.

The solution I implemented was to change DateOfBirth to be a string, this would then bind correctly. I then overrode the IsValid method to validate if the string was in fact a valid date.

public class DobViewModel
{
   [DateTypeWithPhrase()]
   public string DateOfBirth { get; set; }    
}

public class DateTypeWithPhraseAttribute : DataTypeAttribute
{
    public DateTypeWithPhraseAttribute() : base(DataType.Date)
    {
         ErrorMessageResourceName = null;
         ErrorMessage = ErrorPhrase;
    }

    public string ErrorPhrase = "Invalid Date";

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        DateTime myDate;
        if (value == null || DateTime.TryParse(value.ToString(), out myDate))
        {
            return ValidationResult.Success;
        }
        return new ValidationResult(ErrorMessage);
    }
 }

A colleague of mine has since found a link to an article that raises the possibility of creating a custom model binder, which I will look into at a future date. The article is here and was originally found here.

c# - Custom DataAnnotations ValueAttribute suppling different error me...

c# asp.net-mvc validation data-annotations
Rectangle 27 0

Ok so the problem was in the dropdown template for the line

@Html.DropDownListFor(model => model, new SelectListItem[] { new SelectListItem() { Text = "Yes", Value = "true", Selected = Model == true ? true : false }, new SelectListItem() { Text = "No", Value = "false", Selected = Model == false ? true : false }, **new SelectListItem() { Text = "Select", Value = "null", Selected = Model == null ? true : false}** }, new { @tabindex = intTabIndex, @onchange = strOnChange })

When the default model binder tries to bind the form data back to the model the string "null" is not equal to null (empty object)

new SelectListItem() { Text = "Select", Value = ""}

Everything work happily and the Validation attrribute gets to do its job

asp.net mvc - MVC Custom Validation Attribute being overwritten by Def...

asp.net-mvc validation
Rectangle 27 0

You can create a custom Editor Template for the enum Airlines that will render a radio button list. In your Model you will have a property of type Airlines and tag this property with the Required attribute and set ErrorMessage = "select one item". Don't forget to include the jQuery validation for client side validation if you want it, usually just have to add @Scripts.Render("~/bundles/jqueryval") on your Layout or View. If you don't use the jQuery validation you will need to make the property nullable on the model because enums are just set to the first value by default so MVC will not see it as invalid. Remember if you change the property to nullable you will also need to change the Model type of your Editor Template to nullable as well.

To enable the Editor Template to render a radio button list for any enum, change the template to the following:

@model Enum
@foreach (var value in Enum.GetValues(Model.GetType()))
{
    @Html.RadioButtonFor(m => m, value)
    @Html.Label(value.ToString())
}
@model MvcTest.Models.Airlines
@foreach (var value in Enum.GetValues(typeof(MvcTest.Models.Airlines)))
{
    @Html.RadioButtonFor(m => m, value)
    @Html.Label(value.ToString())
}
public class TestModel
{
    [Required(ErrorMessage = "select one item")]
    public Airlines Airline { get; set; }
}
public class HomeController : Controller
{
    [HttpGet]
    public ActionResult Index()
    {
        return View(new TestModel());
    }

    [HttpPost]
    public ActionResult Index(TestModel model)
    {
        if (ModelState.IsValid)
        {
            return RedirectToAction("Index");
        }

        return View(model);
    }
}
@model MvcTest.Models.TestModel
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
@using (Html.BeginForm())
{
    @Html.EditorFor(m => m.Airline)
    <input type="submit" value="Submit" />
    @Html.ValidationSummary(false)
}

Thank you! I will try this and get back to you soon. What should I do if I don't want a certain enum to be shown in the list? Lets say all enums I am dealing with will have "Unknown". how can I make sure that it does not get rendered but also making sure that a value is selected in the list?

OK trying this does not quite work for me. I don't get the radio button list but instead just a textbox. how can I make a partial view perhaps and give it the enum and have that partial view take the enum and generically spit out the radio buttons for each item in the enums but also having the postback/submit bind the selected value to the view model?

If you want to keep a certain value out of the list simply place an if statement in the loop and check for it. Creating a partial view instead of an editor template should be fairly easy, the difference is just semantics really because editor templates are partial views. Simply create a partial view in whatever view\controller directory you want, though putting it in the shared directory may make more sense, then copy the code from the editor template into it. Than use @Html.Partial("partialViewName", model) and pass the enum from your main view model in as the model.

I don't know why you are getting a textbox instead of the radio button list. The code I posted worked for me when I ran it locally. Try checking your code and make sure it exactly matches what I posted.

also i get text box, how would the editorfor know that it should use that editortemplate(one with @model Enum)?

asp.net mvc - MVC4 enum and radio button list - Stack Overflow

asp.net-mvc asp.net-mvc-4
Rectangle 27 0

You could write custom a validation attribute and perform this validation logic in the IsValid method where you have access to the value and could check whether the value is not null or empty and only then proceed with the default validation.

Thank you. Absolutely, the only issue, I would have to rewrite pretty much every attribute out there to do those checks. Right, and also for every attribute, write the client-side version. Wondering if could use some naming convention (naming the step with some refix of Required or Optional) and then via the client-side validator either validate or skip.

asp.net mvc 3 - How do you validate only if there's input? - Stack Ove...

asp.net-mvc-3