简体   繁体   中英

Check for null in enum property

I've got an enum property that I'm using to populate a dropdown as part of my form that looks like this:

 public class MyModel
{
    [Required]
    [DisplayName("Type of Enum")]
    public EnumType? Type { get; set; }
}

public enum EnumType
{
    option1 = 1,
    option2 = 2,
    option3 = 3,
    option4 = 4
}

The form submits to another controller, where I'm trying to check for null in the enum type:

 public class ResultController : Controller
{
    // GET: Result
    [AllowAnonymous]
    public ActionResult Index(MyModel model)
    {
        if(!Enum.IsDefined(typeof(MyEnum), model.EnumType))
        {
            return RedirectToAction("Index", "Home");
        }           
        return View();
    }
}

When I try ..../result?Type=5 RedirectToAction works, but when I try ..../result?Type= I get ArgumentNullException .

Note: Adding None=0 in the Enum is not an option for me, I don not want none to show up in the dropdown list.

How can I check for null in the controller? Is there a best practice in this regard?

Explicitly check whether the value is null before using it in IsDefined() .

public ActionResult Index(MyModel model)
{
    if(!model.EnumType.HasValue)
    {
        return RedirectToAction("Index", "Home");
    }           
    if(!Enum.IsDefined(typeof(MyEnum), model.EnumType))
    {
        return RedirectToAction("Index", "Home");
    }           
    return View();
}

A shorter version is to use the null-coalesce operator to use 0 instead of null in the call to IsDefined() :

public ActionResult Index(MyModel model)
{
    if(!Enum.IsDefined(typeof(MyEnum), model.EnumType ?? 0))
    {
        return RedirectToAction("Index", "Home");
    }           
    return View();
}

First, based on your model the Type property is required.

public class MyModel
{
    [Required]
    [DisplayName("Type of Enum")]
    public EnumType? Type { get; set; }
}

Second, you need to check that the enum value is really defined on the EnumType declaration, then you don't need to call Enum.isDefined method in your action. Just decorate your Type property with data annotation attribute EnumDataType(typeof(EnumType)) which will do that job. So your model will look like this:

public class MyModel
{
    [Required]
    [EnumDataType(typeof(EnumType))]
    [DisplayName("Type of Enum")]
    public EnumType? Type { get; set; }
}

Finally, in your controller action just clean it so it look this:

// GET: Result
[AllowAnonymous]
public ActionResult Index(MyModel model)
{
    // IsValid will check that the Type property is setted and will exectue 
    // the data annotation attribute EnumDataType which check that 
    // the enum value is correct.
    if (!ModelState.IsValid) 
    {
        return RedirectToAction("Index", "Home");
    }
    return View();
}

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