Как к RedirectToAction в ASP.NET MVC без потери запрашивают данные

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

Почему этот ответ большой и медленный

Предлагаемое решение состоит в создании динамического массива указателей, а затем инициализации каждого указателя на собственный независимый динамический массив. Преимущество этого подхода состоит в том, что он дает вам синтаксис индексации, к которому вы привыкли, поэтому, если вы хотите найти значение матрицы в позиции x, y, вы скажете:

int val = matrix[ x ][ y ];

работает, потому что матрица [x] возвращает указатель на массив, который затем индексируется с помощью [y]. Разрушение:

int* row = matrix[ x ];
int  val = row[ y ];

Удобно, да? Нам нравится наш синтаксис [x] [y].

Но решение имеет большой недостаток, который заключается в том, что он как жирный, так и медленный.

Почему?

Причина, по которой это как жир, так и медленный, на самом деле то же самое. Каждая «строка» в матрице представляет собой отдельно распределенный динамический массив. Создание распределения кучи является дорогостоящим как во времени, так и в пространстве. Распределитель занимает время, чтобы сделать выделение, иногда выполняя алгоритмы O (n), чтобы сделать это. И распределитель «прокладывает» каждый из ваших массивов строк с дополнительными байтами для бухгалтерии и выравнивания. Это дополнительное пространство стоит ... ну ... дополнительное пространство. Освобождение будет также взять дополнительное время, когда вы идете на освобождение матрицы, тщательно освобождая каждое выделение каждой строки. Получает меня в поту, просто думая об этом.

Есть еще одна причина, по которой это медленно. Эти отдельные распределения, как правило, живут в прерывистых частях памяти. Одна строка может быть по адресу 1000, другая по адресу 100 000 - вы получите эту идею. Это означает, что когда вы проходите матрицу, вы прыгаете через память, как дикий человек. Это, как правило, приводит к промахам в кеше, которые значительно замедляют время обработки.

Итак, если вы абсолютный должен иметь свой симпатичный синтаксис [x] [y], используйте это решение. Если вы хотите быстроту и малость (и если вам все равно, почему вы работаете на C ++?), Вам нужно другое решение.

Другое решение

Лучшее решение состоит в том, чтобы выделить всю вашу матрицу в виде единого динамического массива, а затем использовать (слегка) умную математическую индексацию для доступа к ячейкам. Матрица индексирования только немного умна; nah, это не умно: это очевидно.

class Matrix
{
    ...
    size_t index( int x, int y ) const { return x + m_width * y; }
};

Учитывая эту функцию index() (которую я представляю, является членом класса, потому что он должен знать m_width вашего матрица), вы можете получить доступ к ячейкам в матричном массиве. Матричный массив выделяется следующим образом:

array = new int[ width * height ];

Таким образом, эквивалент этого в медленном, жирном решении:

array[ x ][ y ]

... это в быстрой, малой Решение:

array[ index( x, y )]

Грустный, я знаю. Но вы привыкнете к этому. И ваш процессор поблагодарит вас.

120
задан SpaceDog 15 August 2016 в 02:03
поделиться

4 ответа

Решение состоит в том, чтобы использовать свойство TempData для хранения желаемых компонентов Запроса.

, Например:

public ActionResult Send()
{
    TempData["form"] = Request.Form;
    return this.RedirectToAction(a => a.Form());
}

Затем в Вашем действии "Формы" можно пойти:

public ActionResult Form()
{
    /* Declare viewData etc. */

    if (TempData["form"] != null)
    {
        /* Cast TempData["form"] to 
        System.Collections.Specialized.NameValueCollection 
        and use it */
    }

    return View("Form", viewData);
}
80
ответ дан 24 November 2019 в 01:41
поделиться

Следует иметь в виду, что TempData хранит набор формы на сессии. Если Вам не нравится то поведение, можно реализовать новый интерфейс ITempDataProvider и использовать некоторый другой механизм для того, чтобы хранить временные данные. Я не сделал бы этого, если Вы не знаете для факта (через измерение и представляющий), что использование Состояния сеанса причиняет Вам боль.

37
ответ дан 24 November 2019 в 01:41
поделиться

Существует иначе, который избегает tempdata. Шаблон, который я люблю, включает создание 1 действия и для исходного рендеринга и для перерендеринга недопустимой формы. Это проходит примерно так:

var form = new FooForm();

if (request.UrlReferrer == request.Url)
{
     // Fill form with previous request's data
}

if (Request.IsPost())
{
     if (!form.IsValid)
     {
         ViewData["ValidationErrors"] = ...
     } else {
         // update model
         model.something = foo.something;
         // handoff to post update action
         return RedirectToAction("ModelUpdated", ... etc);
     }
}

// By default render 1 view until form is a valid post
ViewData["Form"] = form;
return View();

Это - шаблон более или менее. Немного pseudoy. С этим можно создать 1 представление для обработки рендеринга формы, восстановления изображения значений (так как форма будет заполнена предыдущими значениями), и показывающий сообщения об ошибках.

, Когда регистрация на это действие, если его допустимое это передает управление другому действию.

я пытаюсь сделать этот шаблон легким в платформа проверки .NET , поскольку мы пристраиваем поддержку MVC.

8
ответ дан 24 November 2019 в 01:41
поделиться

Смотрите на MVCContrib, можно сделать это:

using MvcContrib.Filters;

[ModelStateToTempData]
public class MyController : Controller {
    //
    ...
}
13
ответ дан 24 November 2019 в 01:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: