Подтвердить что ты не робот

Отправка на другую модель из формы в ASP.NET MVC

Если у меня есть представление с моделью, скажем Car..

@model Project.Car

внутри этого представления Я хочу создать форму, которая отправляет данные в новую модель

    @using (Html.BeginForm("Add", "Controller"))
    {
        @Html.Hidden("ID", "1")
        @Html.Hidden("UserID", "44")
        @Html.TextArea("Description")
    }

Я заметил, что если мое действие определено с моим ViewModel, оно не работает (модель всегда равна нулю):

    [HttpPost]
    public PartialViewResult Add(ViewModels.NewModel model)

Однако, если я использую FormCollection, он работает:

    [HttpPost]
    public PartialViewResult Add(FormCollection formCollection)

Вот модель ViewModel:

public class NewModel
{
    public int ID { get; set; }
    public int UserID { get; set; }
    public string Description { get; set; }
}

Мой вопрос: могу ли я отправить данные в NewModel из моей формы? Вид, на котором он сидит, правильно привязан к Project.Car. Его небольшая форма на странице, на которой должен размещаться другой набор данных, не имеющий ничего общего с Project.Car.

4b9b3361

Ответ 1

У вас есть несоответствие между именем вашей модели и вашим действием. В примере, который вы показали, модель называется Add, тогда как в вашем действии вы используете ViewModels.NewModel. Хуже того, ваш взгляд строго типизирован на модель под названием Car. Беспощадно все это.

Итак, начните с определения правильной модели представления:

public class CarViewModel
{
    public int ID { get; set; }
    public int UserID { get; set; }
    public string Description { get; set; }
}

а затем контроллер:

public class CarsController: Controller
{
    public ActionResult Add()
    {
        var model = new CarViewModel
        {
            // don't ask me, those are the values you hardcoded in your view
            ID = 1,
            UserID = 44,
        };
        return View(model);
    }   

    [HttpPost]
    public PartialViewResult Add(CarViewModel model)
    {
        ...
    }
}

и соответствующий строго типизированный вид вашей модели представления:

@model CarViewModel
@using (Html.BeginForm())
{
    @Html.HiddenFor(x => x.ID)
    @Html.HiddenFor(x => x.UserID)
    @Html.TextAreaFor(x => x.Description)
    <button type="submit">Add</button>
}

Ответ 2

My question is can I post data to NewModel from my form? 

Короткий ответ: да, вы можете отправить форму любому действию контроллера на любом контроллере, связанном с любой моделью в вашем приложении.

Например, для вашей формы для сообщения в действие "Add" на контроллере NewModel:

@using (Html.BeginForm("Add", "NewModel"))
    {
        @Html.Hidden("ID", "1")
        @Html.Hidden("UserID", "44")
        @Html.TextArea("Description")
    }

Поскольку ваше представление строго типизировано для вашей модели Car, вы можете либо изменить это, либо отправить ViewModel в ваше представление, тип которого соответствует модели вашего обновления (в качестве Дарин продемонстрировал), или вам нужно будет отобразить данные сообщения из Car на NewModel в вашем контроллере:

В CarController Add action (Post):

[HttpPost]
public PartialViewResult Add(Car model)
{
    //now map attribute values from the Car model onto 
    //corresponding attributes of an instance of NewModel
    NewModel new = new NewModel();
    new.ID = model.ID;
    new.UserID = model.UserID;
    new.Desc = model.Description;
    //etc...

    //update your model/db
    _db.Add(new);

    //Redirect however you wish...
}

Кроме того, проверьте AutoMapper, объект-объект mapper, который автоматизирует отображение ViewModels на Модели и наоборот.

Ответ 3

Да, вы можете сильно набрать представление одной модели и отправить ее в другую модель.

При этом у вас есть два варианта:

  • Вручную укажите правильные имена для каждого поля ввода, чтобы связующее по умолчанию понимало его и создавало модель (пример).

    В то время как это работает, это также означает, что вы должны следить за опечатками, и вы не получите ошибок во время компиляции, если вы пропустили имя свойства.

  • Вручную создайте HTML-помощник в представлении, связанного с новым типом модели. Затем он будет правильно генерировать HTML для вас.

    Чтобы создать помощник, вам понадобится объект-оболочка, который выведет экземпляр вашей модели в виде интерфейса IViewDataContainer. Вы можете определить эту оболочку в любом месте, включая сама модель:

    public class NewModel
    {
      public int ID { get; set; }
      public int UserID { get; set; }
      public string Description { get; set; }
    
      public class WrapperForHtmlHelper : System.Web.Mvc.IViewDataContainer
      {
        public System.Web.Mvc.ViewDataDictionary ViewData { get; set; }
    
        public WrapperForHtmlHelper(NewModel value)
        {
            this.ViewData = new System.Web.Mvc.ViewDataDictionary<NewModel>(value);
        }
      }
    }
    

    Затем в представлении создается помощник, связанный с экземпляром NewModel:

    var ModelToPost = new YourApp.Models.NewModel() { ID = 1, UserID = 43, Description = "" }
    
    var hlp = new HtmlHelper<YourApp.Models.NewModel>
             (this.ViewContext,
              new YourApp.Models.NewModel.WrapperForHtmlHelper(ModelToPost)
             );
    

    И затем вы используете помощника, как обычно:

    @hlp.HiddenFor(m => m.ID)
    @hlp.HiddenFor(m => m.UserID)
    @hlp.TextAreaFor(m => m.Description)
    

    Затем ваш PartialViewResult Add(ViewModels.NewModel model) будет правильно получать данные.

Ответ 4

В вашем представлении используется модель типа Project.Car однако, в вашем методе действий используется модель типа ViewModels.NewModel, , а также опубликованный класс модели имеет тип Add?

Измените все, чтобы они совпадали (при условии, что Add правильный):

Вид:

@model Add

Контроллер:

[HttpPost]
public PartialViewResult Add(Add model)

Ответ 5

Для этой цели также можно создать настраиваемое связующее устройство.