Привязка модели не работает с маршрутизацией атрибутов в .net Core 2.1 - PullRequest
0 голосов
/ 03 октября 2018

Я могу заставить работать привязку модели без маршрутизации атрибута - например:

/// <summary>
/// Collect user details
/// </summary>
public IActionResult RegisterDetails(Guid CustomerId)
{
    var Details = new Details()
    {
        CustomerID = CustomerId
    };

    return View(Details);
}

/// <summary>
/// Save user details in Db if valid
/// </summary>
[HttpPost]
public IActionResult RegisterDetails(Details Details)
{
    if (ModelState.IsValid)
    {
        // Do stuff
    }

    // Error, return ViewModel to view
    return View(RegisterDetails);
}

Но я не уверен, как передать модель в метод, который ее обрабатывает.Когда я отправляю форму, он запускает оригинальный метод, а не тот, который находится под [HttpPost] - он продолжает публиковать в исходном методе снова и снова (где // Делать вещи - когда я делаю это:

/// <summary>
/// Collect user details
/// </summary>
[Route("Register/Details/{CustomerId}")]
public IActionResult RegisterDetails(Guid CustomerId)
{
    var Details = new Details()
    {
        CustomerID = CustomerId
    };

    return View(Details);
}

/// <summary>
/// Save user details in Db if valid
/// </summary>
[HttpPost]
[Route("Register/Details")]
public IActionResult RegisterDetails(Details Details)
{
    if (ModelState.IsValid)
    {
        // Do stuff
    }

    // Error, return ViewModel to view
    return View(RegisterDetails);
}

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

Я искал в Google - я нашел вещи, которые не помогли, например, это: https://www.red -gate.com / simple-talk /dotnet / asp-net / улучшенная привязка модели-asp-net-core /

thx

Обновление

Имеютакже заметил, что CustomerId добавляется к URL, даже после публикации формы. Я не думаю, что это произошло в MVC 5 и не требует этого, CustomerId скрыт на странице.

Как я могу удалить это (это приводит к тому, что маршрут не соответствует оформленному методу [HttpPost].

Ответы [ 3 ]

0 голосов
/ 03 октября 2018

Вопрос в два раза.Во-первых, у вас есть действие RegisterDetails(Guid CustomerId) с маршрутом, установленным через атрибут Route.Это открывает его для принятия всех HTTP-глаголов: GET, POST и т. Д. Во-вторых, хотя вы не опубликовали свое представление, я могу предположить, что у вас, скорее всего, есть форма с пустым действием, например:

 <form method="post">
     ...
 </form>

По умолчанию будет отправляться обратно на ту же страницу, что здесь в этом сценарии будет /Register/Details/{CustomerId}.Так как этот маршрут не соответствует вашему действию, явно помеченному как HttpPost и , действующее действие принимает POST (из-за использования Route), действие, которое принимает идентификатор клиента, вызывается снова.Поскольку в нем нет кода, который действительно обрабатывает сообщение, он просто перезагружает вашу страницу.

Прежде всего, вы должны использовать явные атрибуты HTTP-глагола вместо Route в своих действиях, то есть:

[HttpGet("Register/Details/{CustomerId}")]
public IActionResult RegisterDetails(Guid CustomerId)

[HttpPost("Register/Details")]
public IActionResult RegisterDetails(Details Details)

Тогда, если вы хотите сохранить эту схему маршрутов, вам нужно четко указать свою форму.Однако, поскольку оба действия имеют одно и то же имя, это немного сложно сделать.ASP.NET Core попытается выполнить обратную засыпку части CustomerId маршрута, поскольку она уже существует в данных маршрута.У вас есть три варианта:

  1. Использовать разные имена действий.Затем вы можете явно привязать свою форму к действию публикации:

    [HttpPost("Register/Details")]
    public IActionResult RegisterDetailsPost(Details Details)
    

    Затем:

    <form asp-action="RegisterDetailsPost" method="post">
    
  2. Использовать названия маршрутов:

    [HttpPost("Register/Details", Name = "RegisterDetailsPost")]
    public IActionResult RegisterDetails(Details Details)
    

    Тогда:

    <form asp-route="RegisterDetailsPost" method="post">
    
  3. Не включайте идентификатор клиента в начальный маршрут.Если два маршрута на самом деле совпадают, то будет выбран правильный путь, основанный на действующем глаголе HTTP.Другими словами:

    [HttpGet("Register/Details")]
    public IActionResult RegisterDetails(Guid CustomerId)
    

    Вы все еще можете указать идентификатор клиента, но вам нужно использовать строку запроса, например, /Register/Details?CustomerId=123456.Генерация URL в ваших ссылках и тому подобное не будет отличаться.ASP.NET Core автоматически присоединяет любые включенные данные маршрута, которые явно не являются параметром маршрута, в качестве параметра строки запроса.Другими словами, вы все равно можете просто сделать что-то вроде:

    <a asp-action="RegisterDetails" asp-route-customerId="123456">Click me</a>
    
0 голосов
/ 14 ноября 2018

попробуйте использовать атрибут FromBody.

public IActionResult RegisterDetails([FromBody]Details Details)
0 голосов
/ 03 октября 2018

Обычно вы можете добавить атрибут «маршрут» через контроллер класса API в качестве базового пути, а затем добавить параметры.Я также пытался всегда добавлять глагол для контроллера для лучшего понимания ...

[Route("Register/Details/")]
public class RegistrerExampleController : ControllerBase
{

    /// <summary>
    /// Collect user details
    /// </summary>
    [HttpGet("{CustomerId}", Name = nameof(RegisterDetails))]
    public IActionResult RegisterDetails(Guid CustomerId)
    {
        var Details = new Details()
        {
            CustomerID = CustomerId
        };

        return View(Details);
    }

    /// <summary>
    /// Save user details in Db if valid
    /// </summary>
    [HttpPost]
    public IActionResult RegisterDetails(Details Details)
    {
        if (ModelState.IsValid)
        {
            // Do stuff
        }

        // Error, return ViewModel to view
        return View(RegisterDetails);
    }
}

Вы пробовали это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...