Re[11]: [MVC] Post-Redirect-Get и автоматизация форм
От: mogadanez Чехия  
Дата: 27.08.10 11:02
Оценка:
Здравствуйте, cadet354, Вы писали:

M>> 2.2 — TempData — это конечно пц скажу я вам. во первых, они используют всегда один ключ, и пользователь работающий в нескольких вкладках имеет шанс получить облом. во вторых в случае

C>а зачем это хранить Tempdata, интересны ведь текущие данные на этой странице.

и где я их возьму если случился Redirect?
Re[12]: [MVC] Post-Redirect-Get и автоматизация форм
От: cadet354 Россия
Дата: 27.08.10 11:31
Оценка:
Здравствуйте, mogadanez, Вы писали:

M>Здравствуйте, cadet354, Вы писали:


M>>> 2.2 — TempData — это конечно пц скажу я вам. во первых, они используют всегда один ключ, и пользователь работающий в нескольких вкладках имеет шанс получить облом. во вторых в случае

C>>а зачем это хранить Tempdata, интересны ведь текущие данные на этой странице.

M>и где я их возьму если случился Redirect?

я про валидацию, а зачем при редиректе повторять эти данные? если очень надо, то можно в TempData c ключом guid, guid передавать в адресе.
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[13]: [MVC] Post-Redirect-Get и автоматизация форм
От: mogadanez Чехия  
Дата: 27.08.10 14:28
Оценка:
Здравствуйте, cadet354, Вы писали:

C>Здравствуйте, mogadanez, Вы писали:


M>>Здравствуйте, cadet354, Вы писали:


M>>>> 2.2 — TempData — это конечно пц скажу я вам. во первых, они используют всегда один ключ, и пользователь работающий в нескольких вкладках имеет шанс получить облом. во вторых в случае

C>>>а зачем это хранить Tempdata, интересны ведь текущие данные на этой странице.

M>>и где я их возьму если случился Redirect?

C>я про валидацию, а зачем при редиректе повторять эти данные?

и я про валидацию, где взять _пользовательские_ _неправильные_ данные после редиректа.
* данные ХХХ пришли постом
* мы решили что они не верны
* редирект
* рендерим форму
** нужно данные ХХХ отрендерить на форме.

C>если очень надо, то можно в TempData c ключом guid, guid передавать в адресе.


да так и приходится, но это уже костыли.
прыгающий гуид в урле как то не красиво совсем.
да и в случае с фермой теже проблемы что я описывал уже
Re[14]: [MVC] Post-Redirect-Get и автоматизация форм
От: cadet354 Россия
Дата: 27.08.10 15:32
Оценка:
Здравствуйте, mogadanez, Вы писали:


C>>я про валидацию, а зачем при редиректе повторять эти данные?


M>и я про валидацию, где взять _пользовательские_ _неправильные_ данные после редиректа.

M>* данные ХХХ пришли постом
M>* мы решили что они не верны
M>* редирект
зачем тут редирект, остаемся на этой же странице
M>* рендерим форму
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[15]: [MVC] Post-Redirect-Get и автоматизация форм
От: mogadanez Чехия  
Дата: 27.08.10 21:06
Оценка:
Здравствуйте, cadet354, Вы писали:

C>Здравствуйте, mogadanez, Вы писали:



C>>>я про валидацию, а зачем при редиректе повторять эти данные?


M>>и я про валидацию, где взять _пользовательские_ _неправильные_ данные после редиректа.

M>>* данные ХХХ пришли постом
M>>* мы решили что они не верны
M>>* редирект
C>зачем тут редирект, остаемся на этой же странице

это выше по стеку пункт 1.
Re[14]: [MVC] Post-Redirect-Get и автоматизация форм
От: mogadanez Чехия  
Дата: 27.08.10 22:07
Оценка:
Здравствуйте, mogadanez, Вы писали:

C>>если очень надо, то можно в TempData c ключом guid, guid передавать в адресе.


M>да так и приходится,


хотя не ни фига, так не работает, TempData _очищается_ при заборе из нее данных
так что если туда кладут данные две страницы вторая обламается даже с Guid'ом

так что либо в сессию прямо класть, либо свой TempDataProvider
Re[16]: [MVC] Post-Redirect-Get и автоматизация форм
От: cadet354 Россия
Дата: 30.08.10 08:24
Оценка:
Здравствуйте, mogadanez, Вы писали:

M>Здравствуйте, cadet354, Вы писали:


C>>Здравствуйте, mogadanez, Вы писали:



C>>>>я про валидацию, а зачем при редиректе повторять эти данные?


M>>>и я про валидацию, где взять _пользовательские_ _неправильные_ данные после редиректа.

M>>>* данные ХХХ пришли постом
M>>>* мы решили что они не верны
M>>>* редирект
C>>зачем тут редирект, остаемся на этой же странице

M>это выше по стеку пункт 1.

не понятно,
1.пользователь ввел данные,отправил POST, они не валидные, мы вернули ошибки валидации (тут F5 хоть ужамкайся)
2.пользователь ввел данные,отправил POST, они валидные, записали,отправили redirect на страницу где об этом ему и сказали.
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[17]: [MVC] Post-Redirect-Get и автоматизация форм
От: Ocenochka  
Дата: 30.08.10 19:39
Оценка:
Здравствуйте, cadet354, Вы писали:

M>>это выше по стеку пункт 1.

C>не понятно,
C>1.пользователь ввел данные,отправил POST, они не валидные, мы вернули ошибки валидации (тут F5 хоть ужамкайся)

Если тут нажать F5, то появится окно браузера с сообшением о перепосылки формы — я так понимаю, что именно об этом сообщении речь.

C>2.пользователь ввел данные,отправил POST, они валидные, записали,отправили redirect на страницу где об этом ему и сказали.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Люблю ставить оценки.
Re[18]: [MVC] Post-Redirect-Get и автоматизация форм
От: cadet354 Россия
Дата: 31.08.10 06:44
Оценка:
Здравствуйте, Ocenochka, Вы писали:


O> Если тут нажать F5, то появится окно браузера с сообшением о перепосылки формы — я так понимаю, что именно об этом сообщении речь.

вот как , ИМНО это борьба с ветренными мельницами
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[19]: [MVC] Post-Redirect-Get и автоматизация форм
От: mogadanez Чехия  
Дата: 31.08.10 21:51
Оценка:
Здравствуйте, cadet354, Вы писали:

C>Здравствуйте, Ocenochka, Вы писали:



O>> Если тут нажать F5, то появится окно браузера с сообшением о перепосылки формы — я так понимаю, что именно об этом сообщении речь.

C>вот как , ИМНО это борьба с ветренными мельницами

а вот ИМХО, считать это это за норму устаревшие стереотипы "ну все же так делают".
но можно же и себе и пользователю облегчит жизнь... так нет... 100 лет ТАК делали и будем продолжать
Re[20]: [MVC] Post-Redirect-Get и автоматизация форм
От: cadet354 Россия
Дата: 01.09.10 07:51
Оценка:
Здравствуйте, mogadanez, Вы писали:


M> а вот ИМХО, считать это это за норму устаревшие стереотипы "ну все же так делают".

M>но можно же и себе и пользователю облегчит жизнь... так нет... 100 лет ТАК делали и будем продолжать
на то оно и ИМНО, зачем жать F5 когда тебе показывают, что на странице в полях ошибки
... << RSDN@Home 1.2.0 alpha 4 rev. 1270>>
Re[21]: [MVC] Post-Redirect-Get и автоматизация форм
От: mogadanez Чехия  
Дата: 01.09.10 12:42
Оценка:
Здравствуйте, cadet354, Вы писали:

C>Здравствуйте, mogadanez, Вы писали:



M>> а вот ИМХО, считать это это за норму устаревшие стереотипы "ну все же так делают".

M>>но можно же и себе и пользователю облегчит жизнь... так нет... 100 лет ТАК делали и будем продолжать
C>на то оно и ИМНО, зачем жать F5 когда тебе показывают, что на странице в полях ошибки

ты лучше скажи почему как пользователь я должен ждать пока уйдет запрос, перерисуется страница, дернется скроллер на нужное место( в худшем случае вообще останется на верху )
чтобы просто увидеть что у меня поля с ошибками
Re[4]: [MVC] Post-Redirect-Get и автоматизация форм
От: A_HREF Россия  
Дата: 03.05.11 05:52
Оценка:
Здравствуйте, mogadanez, Вы писали:

M>* Post надо делать _только_ через Ajax.

M>* при этом показывать "крутяшку"
M>* назад прилетает :
M> ** либо структура с ошибками ( например те которые нельзя просто проверить на клиенте )
M> ** либо разрешение сделать редирект( напрмиер просто url )

Полностью согласен, делается это не сложно, а результат красивый. Только добавлю свои пять копеек.
* Оно должно корректно отрабатывать если нет ява скрипта (есть придурки, которые бегают с NoScript в Фаерфоксе)
* Оно должно работать с валидацией (клиентская и серверная)

Давайте рассмотрим простейший пример типа «форма логина на сайте».

Вьюшка:
<fieldset class="smallest">
    <% using (Html.BeginForm("login", "account", FormMethod.Post, new{id="loginForm"})) { %>
    <%= Html.HiddenFor(m => Model.ReturnUrl)%>
    <ol>
        <li>
            <%= Html.LabelFor(model => Model.LoginOrEmail)%>
            <%= Html.TextBoxFor(model => Model.LoginOrEmail, new { @class = "text bigest", id = "login", tabindex = "1" })%>
            <%= Html.ValidationMessageFor(model => Model.LoginOrEmail)%>
        </li>
        <li>
            <%= Html.LabelFor(model => Model.Password)%>
            <%= Html.PasswordFor(model => Model.Password, new { @class = "text big", tabindex = "2" })%>
            <%= Html.ValidationMessageFor(model => Model.Password)%>
        </li>
        <li class="checkbox">
            <%= Html.CheckBoxFor(m => Model.Persist, new {tabindex = "3"})%>
            <%= Html.LabelFor(m => Model.Persist)%>
        </li>
        <li>            
            <%= Html.Button("Войти") %>
        </li>
    </ol>
    <% } %>
    <script type="text/javascript">
        $(document).ready(function () { tryAjaxFormSubmit('loginForm'); });
    </script>
</fieldset>


Обычная такая вьюшка, но если у чувака есть JS, то вызовется функция tryAjaxFormSubmit, которая выглядит так:

function tryAjaxFormSubmit(formId) {
    var f = $("#" + formId);
    f.submit(function () {                
        var validator= f.validate();
        if (validator.valid()) {
            var action = f.attr("action");
            var serializedForm = f.serialize();
            $.ajax({
                type: 'POST',
                url: action,
                dataType: 'json',
                data: serializedForm,
                beforeSend: function () { setFormStateLoading('loginForm', true); },
                success: function (result) {
                    if (result.RedirectUrl != null && result.RedirectUrl != '')
                        window.location = result.RedirectUrl;
                    else {
                        validator.showErrors(result.Errors);
                        setFormStateLoading('loginForm', false);
                    }
                }
            });
        }
        return false;
    });
}

Эта функция перехватывает сабмит формы, валидирует ее с помощью jQuery.validation, если валидация на клиенте прошла, то форма сабмитится на сервер.

Метод контроллера:


[HttpPost, OutputCache(Duration = 60), HandleAjaxRequest]
public ActionResult Login(UserLoginInput input)
{
    if (!ModelState.IsValid)
    {
        return View();
    }

    var user = _userService.GetByLoginOrEmail(input.LoginOrEmail);
    

    FormsAuthentication.SetAuthCookie(user.Login, input.Persist);
    if (!String.IsNullOrEmpty(input.ReturnUrl))
        return Redirect(input.ReturnUrl);
            
    return RedirectToAction("Index", "Pages");
}


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

HandleAjaxRequest:
public class HandleAjaxRequestAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAjaxRequest()) return;

        var state = filterContext.Controller.ViewData.ModelState;
        if (!state.IsValid)
        {
            var response = new JsonResponse
                            {
                                   Status = Status.Error,
                                   Errors = state.ToJson()
                            };
            filterContext.Result = new JsonResult() { Data = response };
            return;
        }

        if ((filterContext.Result is RedirectToRouteResult || filterContext.Result is RedirectResult))
        {
            string url;
            if (filterContext.Result is RedirectResult)
            {
                url = (filterContext.Result as RedirectResult).Url;
            }
            else
            {
                var result = (RedirectToRouteResult)filterContext.Result;
                url = UrlHelper.GenerateUrl(result.RouteName, null, null, result.RouteValues, RouteTable.Routes, filterContext.RequestContext, false);
            }

            var response = new JsonResponse
                                {
                                       Status = Status.Ok,
                                       RedirectUrl = url
                                   };
            filterContext.Result = new JsonResult { Data = response };
        }
    }
}


Суть атрибута в том, чтобы проверить какой был запрос, через Аякс или нет. Если через аякс, то перезаписываем результат экшена на JSON. Если были ошибки, то конвертим их массив строк ключ-значение, который с удовольствием кушает jquery.validation.

Вот в принципе и все. У кого есть JS то все происходит красиво, у кого нет — тоже не плохо
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.