ASP.net MVC - привязка модели исключает поля класса? - PullRequest
6 голосов
/ 17 октября 2011

В недавнем проекте - я попал в неожиданную загадку.
Класс с простыми открытыми полями (обратите внимание, не свойства), кажется, не хочет играть хорошо с Связующее для модели ASP.net MVC 3.0.

Это задумано?

кроме изменения полей в свойствах - есть ли здесь какие-либо опции?

обновление

Причина простых полей (вместо свойств) в том, что я работаю с общей библиотекой между MVC и проектом Script Sharp. Script Sharp поддерживает свойства - но он становится беспорядком с Javascript в представлении (используя knockout.js)

Так что, несмотря на то, что я хотел бы (а именно просто использовать свойства), я использую открытые поля в моих классах dto.

Я хотел избежать нескольких определений одних и тех же классов. Вздох

Ответы [ 2 ]

12 голосов
/ 17 октября 2011

Это задумано?

Да, только свойства с общедоступными средствами получения / установки работают со связывателем модели по умолчанию.

кроме изменения полей в свойствах - есть ли здесь какие-либо опции?

Это то, что вы должны делать, так или иначе, вы должны использовать модели представления. И модели представлений специально разработаны для представлений. Таким образом, изменение полей на свойства является правильным способом. Теперь, если вы не следуете передовым методам и пытаетесь использовать свои доменные модели в качестве ввода / вывода для действий, вам придется написать пользовательское связующее для моделей, которое работает с полями. Хотя работы будет много.

1 голос
/ 26 августа 2016

Я знаю, что это противоречит философии команды c #, но я думаю, что поля чисты в классах poco. Похоже, менее подвижные части для меня. Во всяком случае,

Вот модель подшивки, которая будет загружать поля. Это довольно тривиально. Обратите внимание, что вы можете использовать новый объект с Activator.CreateInsance или начать с существующего объекта в качестве отправной точки. Я использовал Да / Нет раскрывающихся списков для bool, у вас могут быть флажки, и в этом случае, к сожалению, вам придется циклически просматривать fieldinfos и искать пропущенные входные данные формы. B / c html не отправляет элементы формы, если установлен флажок false.

~ / Binders / FieldModelBinder.cs

using System;
using System.Reflection;
using System.Web.Mvc;

namespace MyGreatWebsite.Binders
{
  public class FieldModelBinder : DefaultModelBinder
  {
    public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
      var obj = controllerContext.HttpContext.Session["CurrentObject"];// Activator.CreateInstance(bindingContext.ModelType);
      var form = controllerContext.HttpContext.Request.Form;
      foreach (string input in form)
      {
        FieldInfo fieldInfo = obj.GetType().GetField(input);
        if (fieldInfo == null)
          continue;
        else if (fieldInfo.FieldType == typeof(bool))
          fieldInfo.SetValue(obj, form[input] == "Yes");
        else
          fieldInfo.SetValue(obj, Convert.ChangeType(form[input], fieldInfo.FieldType));
      }
      return obj;
    }
  }
}

Startup.cs

  public partial class Startup
  {
    public void Configuration(IAppBuilder app)
    {
      ConfigureAuth(app);
      ModelBinders.Binders.Add(typeof(FieldModelBinder), new FieldModelBinder());
    }
  }

Использование

[HttpPost]
public ActionResult MyGreatAction([ModelBinder(typeof(FieldModelBinder))] MyGreatProject.MyGreatNamespace.MyGreatType instance, string myGreatParameters)
{
  DoSomethingGreatWithMyInstance();
  return View();
}
...