ASP.NET Core MVC отправить форму в частичном представлении / ViewComponent - PullRequest
0 голосов
/ 12 октября 2018

У меня есть меню и область содержимого, в которой отображается содержимое на основе выбранного элемента в меню.Поскольку пользователю разрешено изменять структуру главного меню, я решил, что все будет на странице / home / index и будет назначен указатель на контент, который необходимо показать.Я начал с идеи представления частичных представлений, но понял, что в ASP.NET Core больше нет RenderAction и его заменили ViewComponents.Поэтому я использовал ViewComponents, и все работает нормально, за исключением того, что я наткнулся на ситуацию, когда мне нужно иметь компонент в качестве формы отправки.

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

Поскольку работа ViewComponents заключается в отображении представления, как мне следует подойти к этой проблеме?Я ищу указатели в правильном направлении.У меня мало опыта в этой области, поэтому любая помощь будет оценена.

ОБНОВЛЕНИЕ

In Index.cshtml :

<tbody>
    @foreach (string item in Model.Components)
    {
        <tr>
            <td>
                <div class="col-md-3">
                    @await Component.InvokeAsync(@item)
                </div>
            </td>
        </tr>
    }
</tbody>

Это внутри области содержимого. Компоненты - это строковые имена компонентов, которые я хотел бы отобразить в области содержимого (в настоящее время перечислены один за другим).

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

public class TestFormViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync()
    {
        return View("_TestForm", new TestModelPost());
    }
}

Мой _TestForm.cshtml компонент:

@model TestModelPost
<form asp-controller="Home" asp-action="TestPost" method="post">
    <label asp-for="Name"></label>
    <input asp-for="Name" /><br />
    <label asp-for="Surname"></label>
    <input asp-for="Surname" /><br />
    <button type="submit">Go</button>
</form>

И действие TestPost вызвано:

[HttpPost]
public IActionResult TestPost(TestModelPost model)
{
    // Save model data, etc
    // !ModelState.IsValid -> go back to form

    // Success -> go to specific id
    return RedirectToAction("Index", new { id = 1 });
}

Как мне подойти к этому?Или, скорее, я даже на правильном пути?Я не уверен, как мне вернуться "назад" к тому представлению, которое я создал в моем компоненте _TestForm, если ввод был неправильным.

Ответы [ 2 ]

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

Просмотр компонентов, как и дочерние действия перед ними в ASP.NET MVC, не поддерживают POST.Вам нужно полноценное действие для обработки формы сообщения, которое необходимо будет вернуть полный вид.По сути, вам просто нужно подумать об этом более абстрактно.

Компонент представления - это, в конечном счете, средство добавления некоторого HTML-кода в возможный ответ.Когда полный ответ возвращается клиенту, нет понятия, что было компонентом представления, частичным представлением и т. Д. Это просто документ HTML.Часть этого HTML-документа - это ваша форма.Эта форма будет иметь действие, которое в конечном итоге должно быть маршрутом, который обрабатывается одним из ваших действий контроллера.Традиционная публикация формы приводит к изменению всего представления браузера, поэтому ответом на это действие должно быть либо полное представление, либо перенаправление на действие, которое возвращает полное представление.Перенаправление является более подходящим путем, следуя шаблону PRG.В этом случае ответственность за это представление в конечном итоге возвращается, чтобы определить, как создается контент, используя компоненты представления, частичные компоненты и т. Д. В зависимости от ситуации.

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

Для таких форм, которые являются частью макета, обычно лучше включить в форму скрытый ввод, содержащий «обратный URL».Действие, которое обрабатывает форму, затем может перенаправить обратно на этот URL-адрес после выполнения того, что ему нужно сделать, чтобы создать видимость того, что пользователь остался в том же месте.

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

Пожалуйста, обратитесь к следующей ссылке:

https://andrewlock.net/an-introduction-to-viewcomponents-a-login-status-view-component/

это может помочь

public class LoginStatusViewComponent : ViewComponent
{
    private readonly SignInManager<ApplicationUser> _signInManager;
    private readonly UserManager<ApplicationUser> _userManager;

    public LoginStatusViewComponent(SignInManager<ApplicationUser> signInManager, UserManager<ApplicationUser> userManager)
    {
        _signInManager = signInManager;
        _userManager = userManager;
    }

    public async Task<IViewComponentResult> InvokeAsync()
    {
        if (_signInManager.IsSignedIn(HttpContext.User))
        {
            var user = await _userManager.GetUserAsync(HttpContext.User);
            return View("LoggedIn", user);
        }
        else
        {
            return View();
        }
    }
}

Наш метод InvokeAsync довольно понятен.Мы проверяем, выполнил ли текущий пользователь вход в систему с помощью SignInManager <>, и если это так, мы извлекаем связанный ApplicationUser из UserManager <>.Наконец, мы вызываем вспомогательный метод View, передавая шаблон для визуализации и пользователя модели.Если пользователь не вошел в систему, мы вызываем вспомогательное представление без аргумента шаблона.

В соответствии с вашим сегментом кода вы можете попытаться изменить его следующим образом:

public class TestFormViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync()
    {
      if (_signInManager.IsSignedIn(HttpContext.User))
        {
       //user list display
        return View("_TestForm", new TestModelPost());
        }
      else
        {
          return View();
        }
    }
}
...