简体   繁体   中英

Entity Framework Required with Default Value

I have a EF Code First setup, I have a particular column that is marked as Required via annotation. This column has a default value constraint specified in the database.

What I'm trying to do is allow the user to enter the value on a form but if they omit it, use the default value from the database. I'm not having any luck.

If I don't enter anything, the Required error shows on the form. If I add [DatabaseGenerated(DatabaseGeneratedOption.Computed)] annotation, the value the user enters is ignored and it always uses the database default.

What you can do is perform the magic while parsing form values .

When checking for the specific column's user input from the form, check the column using

if (!String.IsNullOrWhiteSpace(value))
    //set the value in the database entry based on user's input

The above piece of code only enters a value into the database if something has been entered on the form .

This solution only works if you are able to parse the form's values after user 'submits'.

This was my solution to this issue, which is not great, but manageable.

In my model, I annotated the property with:

[DefaultValueSql("'A'")]
[DefaultValue("A")]
[Required]

The DefaultValueSql is a custom attribute that handles the creation of SQL default column values when doing migrations. The DefaultValue matches that value. I'm aware this is a violation of DRY, but using this solution removes the need for the default in the database anyway (I'll probably remove it in the future).

In my Controller, on the Create/Edit ActionResult post handlers I added this:

    if (model.ActiveIndicator == null)
    {
        model.ActiveIndicator = ((DefaultValueAttribute)(model.GetType().GetProperty("ActiveIndicator").GetCustomAttributes(typeof(DefaultValueAttribute), true).First())).Value.ToString();
        ModelState["ActiveIndicator"].Errors.Clear(); // Removes Model Error
    }

This sets the default to the DefaultValue listed in the annotation and removes the ModelState error for this property allowing the ModelState.IsValid to be true.

This solution works well for string defaults, however non-string (types that can't be null), should probably be done differently, perhaps in the model class constructor.

Edit: If you are using TryUpdateModel, you must set the ModelState value instead of the submitted model value:

    if (model.ActiveIndicator == null)
    {
        var defValue = ((DefaultValueAttribute)(model.GetType().GetProperty("ActiveIndicator").GetCustomAttributes(typeof(DefaultValueAttribute), true).First())).Value.ToString();
        ModelState.SetModelValue("ActiveIndicator", new ValueProviderResult(defValue, "", CultureInfo.InvariantCulture));
        ModelState["ActiveIndicator"].Errors.Clear(); // Removes Model Error
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM