Как я могу опубликовать контент формы, который не связан с моделью? - PullRequest
0 голосов
/ 07 октября 2019

У меня есть задание, в котором мне нужно собрать три значения в форме, отправить их, выполнить определенную операцию со значениями, основанными на некоторых условиях, которые приведут меня к индексу строки базы данных, извлекут строку из базы данныхс вычисленным индексом, а затем обновите представление.

Проблема заключается в том, что форма сама по себе не является моделью и не создает экземпляр / сущность / строку в таблице. Когда я создаю представление, я получаю ошибку от Razor, которая говорит, что дерево выражений может не содержать динамическую операцию, я знаю, что это потому, что форма не связана с какой-либо моделью (и поэтому я не добавляю директиву @model вфайл .cshtml). Я думаю, что мне нужно отправить содержимое в контроллер и с выбранным значением обновить содержимое (я попытался с помощью кнопки отправки, но он перенаправил меня на пустую страницу, я знаю, как обычно работают формы, но это не поведениеМне нужно).

Я попытался добавить директиву @model в файл Index.cshtml, содержащий форму, но поскольку модель, к которой я присоединяюсь, не содержит те же атрибуты, что и моииспользуя в форме, бритва выбрасывает ошибки. Я попытался создать класс Model для формы, и он каким-то образом работает, я получаю значения и все (он перенаправляет при отправке, это не то, что я хочу), но я не верю, что это правильно, поскольку сама форма недля создания сущности в таблице.

Это модель, из которой я буду получать значения из базы данных:

using System;
using System.Collections.Generic;

namespace PrototipoExploratorio.Models
{
    public partial class Factores
    {
        public int FactorId { get; }
        public int ValorUno { get; }
        public int ValorDos { get; }
        public int ValorTres { get; }
    }
}

Это форма, в данный момент находящаяся внутри папки Views. / Factores (как модель выше)

@{
    ViewData["Title"] = "Index";
}

<h2>Factores</h2>
<form method="post" asp-controller="FactoresForm" asp-action="ObtenerFactor">
    <div class="form-group">
        <label for="Estatura" class="control-label">Estatura en centímetros</label>
        <input asp-for="Estatura" name="estatura" type="number" id="estatura" placeholder="168, 190, 155...">
    </div>
    <div class="form-group">
        <label for="Edad" class="control-label">Edad</label>
        <input asp-for="Edad" name="edad" type="text" id="number" placeholder="15, 24, 50...">
    </div>
    <div class="form-group">
        <label for="Peso" class="control-label">Peso en kilogramos</label>
        <input asp-for="Peso" name="peso" type="number" id="peso" placeholder="80, 70.5, 55.40...">
    </div>
    <div class="form-group">
        <label for="EstadoCivil" class="control-label">Estado civil</label>
        <select id="EstadoCivil" asp-for="EstadoCivil" for="EstadoCivil" name="EstadoCivil">
            <option value="soltero">Soltero</option>
            <option value="casado">Casado</option>
        </select>
    </div>
    <div class="form-group">
        <div>
            <label class="control-label">Factor calculado: </label>
            <h6 id="FactorCalculado">{this is where I will update the value calculated from the values submitted here and the database row that I will fetch}</h6>
        </div>
        <div class="form-group">
            <button asp-controller="FactoresForm" asp-action="ObtenerFactor" class="btn btn-primary" type="submit">Obtener factor</button>
            <button asp-controller="FactoresForm" asp-action="LimpiarDatos" class="btn btn-primary" type="submit">Limpiar</button>
        </div>
    </div>
</form>

И это контроллер:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using PrototipoExploratorio.Models;

namespace PrototipoExploratorio.Controllers {
    public class FactoresForm : Controller {
        // GET: /<controller>/
        public IActionResult Index() {
            return View();
        }


        [HttpPost]
        [ValidateAntiForgeryToken]
        // I expect to reach this code on form submit
        // I know that right now this does not work given the explanation above
        public IActionResult ObtenerFactor() {
            Console.WriteLine("");
            return View("Index");
        }
    }
}

Я ожидаю отправки формы, выполните некоторые операции бизнес-логики, чтобы получить индексСтрока базы данных (которая сопоставлена ​​с моделью Factores), получить значение из строки и обновить представление.

1 Ответ

0 голосов
/ 07 октября 2019

Проблема в том, что форма сама по себе не является моделью и не создает экземпляр / сущность / строку в таблице

Вы неправильно поняли роль модели представления. Модель представления - это POCO (Простой старый объект CLR), который используется для визуализации представления . Это может быть любой простой объект. Объект обычно известен как Модель данных , представляющая строку в datatable.

Я попытался создать класс Model для формы, и он каким-то образом работает, я получаю значения и все(он перенаправляет при отправке, это не то, что я хочу), но я не верю, что это правильно, поскольку сама форма не предназначена для создания сущности в таблице.

На самом деле,это правильный путь. Просто помните:

  1. View Model используется для визуализации представления. Это не имеет ничего общего с моделью данных.
  2. DTO используется для передачи данных. DTO не должен совместно использовать тот же тип модели данных.
  3. Вы можете определить custom DTO / View Model, как вам нужно.

Как исправить

  1. В этом сценарии вы визуализируете представление, а затем отправите данные в контроллер. Чтобы избежать путаницы именования "модель", давайте создадим DTO для хранения данных.

    public class FactorDto
    {
        public int Estatura {get;set;}
        public int Edad {get;set;}
        public decimal Peso {get;set;}
        public string EstadoCivil {get;set;}
    }
    

    Имя FactorDto не имеет значения вообще. Не стесняйтесь менять имя по своему усмотрению.

  2. Чтобы отобразить вид формы с помощью этого DTO, вы можете добавить директиву @model в свой файл представления формы:

    @model FactorDto
    @{
        ViewData["Title"] = "Index";
    }
    
    <h2>Factores</h2>
    ...
    
  3. Наконец, измените ваш контроллер, как показано ниже, чтобы получать данные, отправленные из браузера:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public IActionResult ObtenerFactor(<strong>FactorDto dto</strong>)
    {
        // ... now you've got the data
    }
    

    Теперь все должно работать нормально.


Если у вас есть модель сложного вида MyComplexViewModel, вы можете объединить их следующим образом:

```csharp
public class MyComplexViewModel
{
    public FactorDto FactorDto{get;set;}
    public Abc Abc {get;set;}
    public string A {get;set;}
    // ... feel free to add other properties as you like
}
```

И объявить модель вида как MyComplexViewModel:

@model MyComplexViewModel
...
<th2>Factores&l;/h2>
...


 <input <b>asp-for="FactorDto.Estatura"</b> name="estatura" type="number" id="estatura" placeholder="168, 190, 155...">
 ...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...