Is there any way to tell DropDownListFor to post back an object instead of an Id? I have the following code:
public class Foo
{
public int SelectedProductId { get; set; }
public decimal MonthlyIncome { get; set; }
public IEnumerable<Product> Products { get; set; }
}
@using(Html.BeginForm())
{
@Html.DropDownListFor(x => x.SelectedProductId, new SelectList(Model.Products, "Id", "Name"))
<input type="submit" value="Submit"/>
}
and this works fine. But in my model, I want to have SelectedProduct instead of SelectedProductId. Is it possible to tell MVC to pass back an object instance instead of it's id?
Thanks.
Yes, sure, first you need to make sure SelectedProduct has Id and Name properties, and then you must make Model.Products return a list of SelectedProduct and override few methods on SelectedProduct like below:
public override bool Equals(object obj)
{
var other = obj as ClientLookup;
if (other == null)
return false;
return Id.Equals(other.Id);
}
public override int GetHashCode()
{
return Id.GetHashCode();
}
public override string ToString()
{
return Id.ToString();
}
By overriding these methods, and ToString especially, you are making sure that internally DropDownListFor will match the SelectedProduct in your Model.Products with the current SelectedProduct in Foo.
The last piece is the ModelBinder, with this mechanism you will be able to convert a http parameter into a object to bet set in your target model, for SelectedProduct you must do this:
public class SelectedProductModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
ValueProviderResult value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
SelectedProduct selectedProduct = new SelectedProduct();
if (value.AttemptedValue != null && ! "".Equals(value.AttemptedValue))
selectedProduct.Id = (int)value.ConvertTo(typeof(int));
else
selectedProduct.Id = null;
return selectedProduct;
}
}
Now don't forget to register the ModelBinder during app initialization:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ModelBinders.Binders.Add(typeof(SelectedProduct), new SelectedProductModelBinder());
}
}
Hope this helps.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments