Ответ. Перенаправление с POST вместо Добирается?

Это вызвано использованием , свойства которого зависят от текущего итерационного элемента .

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

Итак, в вашем случае, когда получает синтаксический анализ и выполняется, #{field} недоступен в текущей области EL и, следовательно, оценивается как null .

Существует несколько способов заставить его работать.

  • Переместить валидатор в класс, представляющий Field, и ссылаться на него следующим образом:
    
    
    с классом Field, в котором вы его вручную создаете:
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        if (pattern != null) {
            RegexValidator regexValidator = new RegexValidator();
            regexValidator.setPattern(pattern);
            regexValidator.validate(context, component, value);
        }
    }
    
  • Или оберните #{eventMgmt.eventFields} в ListDataModel и привяжите валидатор к компоненту #{eventMgmt}. Таким образом, вы сможете установить свойства валидатора на основе данных строки:
    
    
    в классе базового компонента позади #{eventMgmt}:
    private DataModel model;
    private RegexValidator regexValidator;
    
    @PostConstruct
    public void init() {
        regexValidator = new RegexValidator();
    }
    
    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
        String pattern = model.getRowData().getPattern();
    
        if (pattern != null) {
            regexValidator.setPattern(pattern);
            regexValidator.validate(context, component, value);
        }
    }
    
  • Или создать пользовательский Validator, который расширяет RegexValidator и устанавливает шаблон как пользовательский атрибут компонента и позволяет перехватить Validator. в основном добавляет новый атрибут к компоненту с неоцененным ValueExpression, поэтому он будет переоценен при его вызове. Например:
    
        
        
    
    
    с
    @FacesValidator("extendedRegexValidator")
    public class ExtendedRegexValidator extends RegexValidator {
    
        @Override
        public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
            String pattern = (String) component.getAttributes().get("pattern");
    
            if (pattern != null) {
                setPattern(pattern);
                super.validate(context, component, value);
            }
        }
    
    }
    
  • Или, если вы используете библиотеку служебных программ JSF OmniFaces , используйте ее . Например.
    
        
    
    
    Да, вот и все. будет следить за тем, чтобы все атрибуты оценивались как отложенные выражения вместо непосредственных выражений.

См. Также:

242
задан Community 9 September 2008 в 21:13
поделиться

11 ответов

Выполнение этого требует понимания, как HTTP перенаправляет работу. Когда Вы используете Response.Redirect(), Вы отправляете ответ (к браузеру, который выполнил запрос) с Код состояния HTTP 302 , который говорит браузер, куда пойти затем. По определению браузер сделает это через GET запрос, даже если исходный запрос был POST.

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

public void PageLoad(object sender, EventArgs e)
{
    // Process the post on your side   

    Response.Status = "307 Temporary Redirect";
    Response.AddHeader("Location", "http://example.com/page/to/post.to");
}

, К сожалению, это будет не всегда работать. Различные браузеры реализуют это по-другому , так как это не общий код статуса.

увы, в отличие от Opera и разработчиков FireFox, разработчики IE никогда не читали спецификацию, и даже последний, самый безопасный IE7 перенаправит запрос POST от домена к домену B без любых предупреждений или диалоговых окон подтверждения! Safari также действует интересным способом, в то время как он не повышает диалоговое окно подтверждения и выполняет перенаправление, он выбрасывает данные POST, эффективно изменение 307 перенаправлений в более общие 302.

Так, насколько я знаю, единственный способ реализовать что-то вроде этого состоял бы в том, чтобы использовать JavaScript. Существует две опции, о которых я могу думать первое, что пришло на ум:

  1. Создают форму и имеют action точка атрибута к стороннему серверу. Затем добавьте событие щелчка к кнопке отправки, которая сначала выполняет запрос Ajax к Вашему серверу с данными, и затем позволяет форме быть отправленной стороннему серверу.
  2. Создают форму для регистрации на сервер. Когда форма отправлена, покажите пользователю страницу, которая имеет форму в ней со всеми данными, которые Вы хотите передать, все в скрытых исходных данных. Просто покажите сообщение как "Перенаправление...". Затем добавьте событие JavaScript к странице, которая отправляет форму стороннему серверу.

Из этих двух, я выбрал бы второе по двум причинам. Во-первых, это более надежно, чем первое, потому что JavaScript не требуется для него работать; для тех, кому не включили его, можно всегда делать кнопку отправки для скрытой формы видимой, и давать им команду нажимать его, если требуется больше чем 5 секунд. Во-вторых, можно решить, какие данные передаются к стороннему серверу; если Вы используете, просто обрабатывают форму, как она проходит, Вы будете проводить все данные сообщения, которые являются не всегда, что Вы хотите. То же для 307 решений, принимая его работало на всех Ваших пользователей.

Hope это помогает!

223
ответ дан Siyual 4 November 2019 в 12:48
поделиться

Я предлагаю создать HttpWebRequest, чтобы программно выполнить Ваш POST и затем перенаправить после чтения Ответа если применимо.

1
ответ дан Ben Griswold 4 November 2019 в 12:48
поделиться

В PHP, можно отправить данные POST с ЗАВИХРЕНИЕМ. Действительно ли там что-то сопоставимо для.NET?

Да, HttpWebRequest, см. мое сообщение ниже.

2
ответ дан FlySwat 4 November 2019 в 12:48
поделиться

Вот то, что я сделал бы:

Помещенный данные в стандартную форму (без runat = атрибут "сервера") и набор действие формы для регистрации на целевую удаленную страницу. Прежде, чем отправить я отправил бы данные своему серверу использование XmlHttpRequest и проанализировал бы ответ. Если бы ответ означает, что необходимо продолжить удаленную РЕГИСТРАЦИЮ тогда, я (JavaScript) возобновил бы сообщение иначе, я перенаправлю к странице на моем сайте

2
ответ дан Andrei Rînea 4 November 2019 в 12:48
поделиться

@Matt,

можно все еще использовать HttpWebRequest, затем направить ответ, который Вы получаете к фактическому outputstream ответу, это служило бы ответу назад пользователю. Единственная проблема - то, что были бы повреждены любые относительные URL.

однако, который может работать.

2
ответ дан FlySwat 4 November 2019 в 12:48
поделиться

HttpWebRequest используется для этого.

На обратной передаче, создайте HttpWebRequest своему третьему лицу и отправьте данные формы, тогда как только это сделано, Вы можете Ответ. Перенаправление везде, где Вы хотите.

Вы получаете добавленное преимущество, которое Вы не должны называть все свое управление сервером, чтобы заставить третьи стороны сформировать, можно сделать этот перевод при создании строки POST.

string url = "3rd Party Url";

StringBuilder postData = new StringBuilder();

postData.Append("first_name=" + HttpUtility.UrlEncode(txtFirstName.Text) + "&");
postData.Append("last_name=" + HttpUtility.UrlEncode(txtLastName.Text));

//ETC for all Form Elements

// Now to Send Data.
StreamWriter writer = null;

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";                        
request.ContentLength = postData.ToString().Length;
try
{
    writer = new StreamWriter(request.GetRequestStream());
    writer.Write(postData.ToString());
}
finally
{
    if (writer != null)
        writer.Close();
}

Response.Redirect("NewPage");

Однако при необходимости в пользователе для наблюдения страницы ответа от этой формы, единственная опция состоит в том, чтобы использовать Сервер. Передача, и это может или не может работать.

31
ответ дан FlySwat 4 November 2019 в 12:48
поделиться

PostbackUrl может быть установлен на Вашей кнопке asp отправить на различную страницу.

, если необходимо сделать это в codebehind, попробуйте Сервер. Передача.

3
ответ дан Jimmy 4 November 2019 в 12:48
поделиться

ПОЛУЧАТЬ (и ГОЛОВА) метод никогда не должен использоваться, чтобы сделать что-либо, что имеет побочные эффекты. Побочный эффект мог бы обновлять состояние веб-приложения, или это могло бы заряжать Вашу кредитную карту. Если действие имеет побочные эффекты, другой метод (POST) должен использоваться вместо этого.

Так, пользователь (или их браузер) не должен считаться ответственный за что-то сделанное ТЕМ, ЧТОБЫ ПОЛУЧАТЬ. Если бы некоторый вредный или дорогой побочный эффект произошел как результат ТОГО, ЧТОБЫ ПОЛУЧАТЬ, которое было бы отказом веб-приложения, не пользователем. Согласно спецификации, агент пользователя не должен автоматически следовать за перенаправлением, если это не ответ на ТО, ЧТОБЫ ПОЛУЧАТЬ или ГЛАВНЫЙ запрос.

, Конечно, много из ДОБИРАЕТСЯ, запросы действительно имеют некоторые побочные эффекты, даже если это просто добавляет к файлу журнала. Важная вещь состоит в том, что приложение, не пользователь, должно считаться ответственное за те эффекты.

соответствующие разделы спецификации HTTP 9.1.1 и 9.1.2 , и 10.3 .

2
ответ дан erickson 4 November 2019 в 12:48
поделиться

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

Set-Cookie: name=value; Max-Age=120; Path=/redirect.html

Имея этот файл cookie, вы можете в следующем запросе /redirect.html получить информацию name = value, вы можете хранить любую информацию в этой строке пары имя / значение, вплоть до 4К данных (типичное ограничение для файлов cookie). Конечно, вам следует избегать этого и вместо этого хранить коды состояния и биты флагов.

Получив этот запрос, вы в ответ ответите запросом на удаление этого кода состояния.

Set-Cookie: name=value; Max-Age=0; Path=/redirect.html

Мой HTTP немного ржавый, я прошел через RFC2109 и RFC2965, чтобы понять, насколько это действительно надежно, желательно, чтобы cookie отправлялся туда и обратно ровно один раз, но это кажется невозможным. Кроме того, сторонние файлы cookie могут быть проблемой для вас, если вы переезжаете в другой домен. Это все еще возможно, но не так безболезненно, как когда вы делаете что-то в своем собственном домене.

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

Это способ

Я предоставляю этот код как профессионал концепция: если этот код запускается в контексте, с которым вы не знакомы, я думаю, вы можете решить, какая часть есть что.

Идея состоит в том, что вы вызываете Relocate с некоторым состоянием при перенаправлении, а URL, который вы переместили, вызывает GetState для получения данных (если есть).

const string StateCookieName = "state";

static int StateCookieID;

protected void Relocate(string url, object state)
{
    var key = "__" + StateCookieName + Interlocked
        .Add(ref StateCookieID, 1).ToInvariantString();

    var absoluteExpiration = DateTime.Now
        .Add(new TimeSpan(120 * TimeSpan.TicksPerSecond));

    Context.Cache.Insert(key, state, null, absoluteExpiration,
        Cache.NoSlidingExpiration);

    var path = Context.Response.ApplyAppPathModifier(url);

    Context.Response.Cookies
        .Add(new HttpCookie(StateCookieName, key)
        {
            Path = path,
            Expires = absoluteExpiration
        });

    Context.Response.Redirect(path, false);
}

protected TData GetState<TData>()
    where TData : class
{
    var cookie = Context.Request.Cookies[StateCookieName];
    if (cookie != null)
    {
        var key = cookie.Value;
        if (key.IsNonEmpty())
        {
            var obj = Context.Cache.Remove(key);

            Context.Response.Cookies
                .Add(new HttpCookie(StateCookieName)
                { 
                    Path = cookie.Path, 
                    Expires = new DateTime(1970, 1, 1) 
                });

            return obj as TData;
        }
    }
    return null;
}
0
ответ дан 23 November 2019 в 03:14
поделиться

Что-то новое в ASP.Net 3.5 - это свойство "PostBackUrl" кнопок ASP. Вы можете установить его на адрес страницы, на которую хотите отправить сообщение напрямую, и при нажатии этой кнопки вместо отправки на ту же страницу, как обычно, он отправляет сообщение на страницу, которую вы указали. Удобно. Убедитесь, что UseSubmitBehavior также имеет значение TRUE.

5
ответ дан 23 November 2019 в 03:14
поделиться

Вы можете использовать этот подход:

Response.Clear();

StringBuilder sb = new StringBuilder();
sb.Append("<html>");
sb.AppendFormat(@"<body onload='document.forms[""form""].submit()'>");
sb.AppendFormat("<form name='form' action='{0}' method='post'>",postbackUrl);
sb.AppendFormat("<input type='hidden' name='id' value='{0}'>", id);
// Other params go here
sb.Append("</form>");
sb.Append("</body>");
sb.Append("</html>");

Response.Write(sb.ToString());

Response.End();

В результате сразу после того, как клиент получит весь HTML-код с сервера, происходит событие onload , которое запускает отправку формы и публикацию все данные в определенный postbackUrl.

118
ответ дан 23 November 2019 в 03:14
поделиться
Другие вопросы по тегам:

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