ASP.NET MVC - Custom Model Binder for ID fields

2019-07-16 05:46发布

问题:

i have the following entities:

public class Category
{
    public virtual int CategoryID { get; set; }

    [Required(ErrorMessage = "Section is required")]
    public virtual Section Section { get; set; }

    [Required(ErrorMessage = "Category Name is required")]
    public virtual string CategoryName { get; set; }
}

public class Section
{
    public virtual int SectionID { get; set; }
    public virtual string SectionName { get; set; }
}

Now within my add category view i have a textbox to enter the SectionID eg:

<%= Html.TextBoxFor(m => m.Section.SectionID) %>

I'd like to create a custom model binder to have the following logic:

If the model key ends with ID and has a value (a value was inserted into the textbox) then set the parent object (Section in this example) to Section.GetById(value entered) else set the parent object to null.

I'd really appreciate the help here as this has been baffling me for a while. Thanks

回答1:

I posted a model binder on this question that uses an IRepository to fill foreign keys if they are present. you could modify it to suit your purpose better.



回答2:

Using the solution posted by dave thieben i have come up with the following:

public class CustomModelBinder : DefaultModelBinder
{
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        if (bindingContext.ModelType.Namespace.EndsWith("Models.Entities") && value != null && (Utilities.IsInteger(value.AttemptedValue) || value.AttemptedValue == ""))
        {
            if (value.AttemptedValue != "")
                return Section.GetById(Convert.ToInt32(value.AttemptedValue));
            else
                return null;
        }
        else
            return base.BindModel(controllerContext, bindingContext);
    }
}

This works nicely, however it doesn't select the right value when the form is posted back and using a drop down list. I can see why but so far my attempts to fix it have been in vain. I'd appreciate it once more if you could help.