У меня есть веб-страница, на которой мне нужно вернуть список строк и заполнить объект. Мне придется сделать некоторую пользовательскую обработку для дублирования на основе целых чисел без идентификатора. (не включен в пример).
У меня есть связыватель модели, который анализирует строки, когда я вызываю его явно из списка параметров контроллера, но UpdateModel всегда дает сбой.
UPDATE
Если я изменяю тег на workerRequests2, он работает. Итак, как мне переопределить defaultmodelbinder
для свойства объекта workerRequests
, которое определено как дочерний элемент основного объекта контроллера?
Исключение, которое видно в ModelState, таково:
Exception = {"The parameter conversion from type 'System.String' to type
'Machete.Domain.WorkerRequest' failed because no type converter
can convert between these types."}
Объекты:
public DbSet<WorkOrder> WorkOrders { get; set; }
public DbSet<WorkerRequest> WorkerRequests { get; set; }
Объекты домена:
public class WorkOrder : Record
{
// ID (comes from Record)
public int EmployerID { get; set; } //included for context
public virtual Employer Employer { get; set; } //included for context
...
public virtual ICollection<WorkerRequest> workerRequests { get; set; }
//
}
UPDATE
public class WorkerRequest : Record
{
//public int ID { get; set; }
public int WorkOrderID { get; set; }
public virtual WorkOrder workOrder { get; set; }
public int WorkerID { get; set; }
public virtual Worker workerRequested { get; set; }
public string fullName
{
get {
Person p = this.workerRequested.Person;
return p.firstname1 + " " +
p.firstname2 + " " +
p.lastname1 + " " +
p.lastname2;
}
}
}
Global.asax:
protected void Application_Start()
{ ...
ModelBinders.Binders.Add(typeof(List<WorkerRequest>), new workerRequestBinder());
...
}
ОБНОВЛЕНИЕ Я использую список выбора и планирую сделать что-нибудь на JavaScript, чтобы автоматически выбирать все опции. Мне нужен браузер для построения списка целочисленных ключей (что я и делаю с другими объектами js), и я планирую передать частично заполненные объекты workerRequest на уровень Service для синхронизации списков.
HTML создание списка:
<select id="workerRequests" multiple="multiple" name="workerRequests" tabindex="12" class="valid">
<option value="32">Van</option>
<option value="29">Worker buses</option>
<option value="30">Worker drives</option>
<option value="31">Employer Picks up</option>
<option value="86">Worker walks</option>
</select>
Вот действие Controller:
public ActionResult Edit(int id,
FormCollection collection,
string userName,
List<WorkerRequest> workerRequests)
{
//At this point, workerRequests is populated.
WorkOrder workOrder = workOrderService.GetWorkOrder(id);
TryUpdateModel(workOrder);
//Update model is failing
if (ModelState.IsValid) //Found the exception in here
{
workOrderService.SaveWorkOrder(workOrder, userName);
return RedirectToAction("Index", new { EmployerID = workOrder.EmployerID });
}
else
{
levent.Level = LogLevel.Error; levent.Message = "TryUpdateModel failed";
levent.Properties["RecordID"] = workOrder.ID; log.Log(levent);
return PartialView("Edit", workOrder);
}
}
Пользовательская модель Binder:
public class workerRequestBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
// see if there is an existing model to update and create one if not
List<WorkerRequest> model = (List<WorkerRequest>)bindingContext.Model ?? new List<WorkerRequest>();
// find out if the value provider has the required prefix
bool hasPrefix = bindingContext.ValueProvider.ContainsPrefix(bindingContext.ModelName);
string searchPrefix = (hasPrefix) ? bindingContext.ModelName + "." : "";
// Get the raw attempted value from the value provider
ValueProviderResult vpr = bindingContext.ValueProvider.GetValue("workerRequests");
var incomingData = vpr.AttemptedValue;
if (incomingData != null)
{
model = incomingData.Split(new char[1] { ',' }).Select(data => new WorkerRequest
{
//workerRequested = workerService.GetWorkerByNum(int.Parse(data)),
WorkerID = int.Parse(data)
}).ToList();
}
bindingContext.ModelState.SetModelValue(bindingContext.ModelName, vpr);
return model;
}
}
Вопросы:
[10000 футов] Что я делаю не так? Что я неправильно использую в парадигме MVC?
[1000 футов] Как я могу проанализировать, что UpdateModel делает, чтобы выяснить здесь?
[100 футов] Чего не хватает, чтобы UpdateModel использовал мое пользовательское связующее?