Элегантный способ сделать это - создать собственную модель подшивки и отдельный класс для хранения Kind
и RecordId
в качестве свойств .Вам нужно будет указать связующий элемент модели для вашего класса с атрибутом, и тогда вы сможете использовать класс в качестве параметра метода действия.
[ModelBinder (typeof (RecordIdentityBinder))]
public class RecordIdentity
{
// Your types may be different
public RecordKind Kind { get; set; }
public int RecordId { get; set; }
//TODO: replace this with your formatting algorithm
public override string ToString ()
{
return string.Format ("{0}_{1}", Kind, RecordId);
}
//TODO: replace this with your parsing algorithm
public static RecordIdentity Parse (string s)
{
string[] fragments = s.Split('_');
if (fragments.Length != 2)
return null;
// Your object creation may be different
return new MessagePartyIdentity {
Kind = (RecordKind) Enum.Parse (typeof (RecordKind), fragments [0]),
PartyID = int.Parse (fragments [1])
};
}
}
public class RecordIdentityBinder : IModelBinder
{
public object BindModel (ControllerContext controllerContext, ModelBindingContext bindingContext)
{
string key = bindingContext.ModelName;
ValueProviderResult value = bindingContext.ValueProvider.GetValue (key);
if (value == null || string.IsNullOrEmpty (value.AttemptedValue))
return null;
return RecordIdentity.Parse (value.AttemptedValue);
}
}
public class MyController : Controller
{
// ?identity=Foo_42 will become RecordIdentity { Kind = RecordKind.Foo, RecordId = 42 }
public ActionResult DoSomethingWith (RecordIdentity selectedIdentity)
{
// ...
}
}
В коде шаблона представления вы будетенеобходимо вызвать Html.DropDownListFor()
со своим составным свойством :
@Html.DropDownListFor(m => m.SelectedIdentity, Model.RowList)
Для каждого значения в RowList
или любого другого источника данных, который вы называете, убедитесь, что SelectListItem
'Свойство s Value
установлено для класса ToString()
output.
Имя свойства RecordIdentity
-типа объекта, указанного в Html.DropDownListFor
, должно соответствовать имени параметра действия.В противном случае вам нужно будет указать раскрывающееся имя в атрибуте Bind
Prefix
, как показано здесь :
public ActionResult DoSomethingWith ([Bind(Prefix="SelectedIdentity")] RecordIdentity identity)
{
// do something you need
}
Также обратите вниманиечто он также будет работать, если вы хотите, чтобы RecordIdentity
было свойством модели формы или любого класса, который вы хотели бы принять в качестве параметра для вашего метода действия. Связыватель будет вызываться в любом случае.
Следуя этому подходу, вы возлагаете ответственность за форматирование и анализ на один класс, который в значительной степени невидим и обеспечивает абстракцию над действительными полями .Однако я должен отметить, что такая проблема также может быть вызвана плохой организацией базы данных или организаций.Возможно, лучшим решением было бы снабдить каждый из перечисленных вами предметов собственным уникальным собственным ключом.