Регистрация  |  Вход

Как вычистить Attachment поля в случае отбоя с контроллера по required (на лейауте) полям

Всем привет! столкнулся с проблемой, которая показалось мне интересной.

ЕСть ВФ пейдж с контроллером, которые создают запись, при этом к этой записи можно единомоментно прикрепись один или несколько аттачей.

В случе успешного или не успешного выполнения ДМЛ операций (а также при неудачной кастомной валидации) все аттачи вычищаются (attachment = new Attachment();) так что бы их содерживаем не ушло в СТейт Вью и не завалило его.

Но на ВФ много полей с атрибутом required, а в случае если они пустые то сервер отбивает запрос до захода в Контроллер (?) и в результате заполненные attachment уходят в СТейт Вью и:
Maximum view state size limit (135KB) exceeded.

Сейчас попробую в
Attachment attachment {
get { всегда возвращать новый аттач }

PS: нет. не помогло

и не могу грамотно сформулировать проблему чтоб погуглить

неужели придется делать полность кастомную валидацию полей...

Всем привет! столкнулся с проблемой, которая показалось мне интересной.

ЕСть ВФ пейдж с контроллером, которые создают запись, при этом к этой записи можно единомоментно прикрепись один или несколько аттачей. 

В случе успешного или не успешного выполнения ДМЛ операций (а также при неудачной кастомной валидации) все аттачи вычищаются (attachment = new Attachment();) так что бы их содерживаем не ушло в СТейт Вью и не завалило его.

Но на ВФ много полей с атрибутом  required, а в случае если они пустые то сервер отбивает запрос до захода в Контроллер (?) и в результате заполненные attachment уходят в СТейт Вью и:
Maximum view state size limit (135KB) exceeded. 

Сейчас попробую в 
Attachment attachment {
        get { [b]всегда возвращать новый аттач[/b] }

PS: нет. не помогло

и не могу грамотно сформулировать проблему чтоб погуглить

неужели придется делать полность кастомную валидацию полей...

Несовсем понял что тебе нужно, но может поможет transient в етом случае.

transient Attachment {get {

Using the transient Keyword

Несовсем понял что тебе нужно, но может поможет transient в етом случае.

[code]
transient Attachment {get {
[/code]

[url=http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_keywords_transient.htm]Using the transient Keyword[/url]

Alex Tsitsura
Несовсем понял что тебе нужно, но может поможет transient в етом случае.

на ВФ странице есть файловый инпут
<apex:inputFile value="{!attachment.body}" filename="{!attachment.name}" />

которому соответствует свойство
public Attachment attachment {
get {
// if (attachment == null)
attachment = new Attachment();
return attachment;
}
set;
}

когда я выполняю вставку этого аттачмента - то после нее я вычищаю attachment поле
attachment = new Attachment();

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

Но в случае с стандарной валидацией полей, как я понимаю, страница с ошибками валидации уходит обратно клиента без захода в контроллер - и тот файл который был приаттачен уходит прямо в Стайт вью в виде поля attachment. имено поэтому я получаю Maximum view state size limit (135KB) exceeded. Я так понял проблему.

не понятно как ее решить

[quote="Alex Tsitsura"]Несовсем понял что тебе нужно, но может поможет transient в етом случае.[/quote]

на ВФ странице есть файловый инпут
<apex:inputFile value="{!attachment.body}" filename="{!attachment.name}" />

которому соответствует свойство
     public Attachment attachment {
        get {
             // if (attachment == null)
                attachment = new Attachment();
              return attachment;
            }
        set;
    }

когда я выполняю вставку этого аттачмента - то после нее я вычищаю attachment поле
attachment = new Attachment();

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

Но в случае с стандарной валидацией полей, как я понимаю, страница с ошибками валидации уходит обратно клиента без захода в контроллер - и тот файл который был приаттачен уходит прямо в Стайт вью в виде поля attachment. имено поэтому я получаю Maximum view state size limit (135KB) exceeded. Я так понял проблему.

не понятно как ее решить

попробуй <apex:actionRegion>

попробуй <apex:actionRegion>

Use the transient keyword to declare instance variables that can't be saved, and shouldn't be transmitted as part of the view state for a Visualforce page.

это может сработать, сейчас попробую

Use the [b]transient[/b] keyword to declare instance variables that can't be saved, and shouldn't be transmitted as part of the view state for a Visualforce page.

это может сработать, сейчас попробую

Нет transient не помогает, судя по всему с таким полем вообще не возможно работаь в контроллере:

System.NullPointerException: Attempt to de-reference a null object

Нет  transient не помогает, судя по всему с таким полем вообще не возможно работаь в контроллере:

System.NullPointerException: Attempt to de-reference a null object

хм, я попробовал вот так, и работает

// Page     
<apex:inputFile value="{!myBlob}" filename="{!myName}" id="file"/>

// Controller
public Transient String myName { get; set; }
public Transient Blob myBlob{ get; set; }

Потом в методе коетроллера делаеш

Attachment  attachment = new Attachment();
attachment.body = myBlob;
attachment.name = myName;

...


try {
insert attachment;
} catch (DMLException e) {
ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error uploading attachment'));
return null;
}

хм, я попробовал вот так, и работает

[code]// Page     
<apex:inputFile value="{!myBlob}" filename="{!myName}" id="file"/>

// Controller
public Transient String myName { get; set; }
public Transient Blob myBlob{ get; set; }
[/code]

Потом в методе коетроллера делаеш
[code]
Attachment  attachment = new Attachment();
attachment.body = myBlob;
attachment.name = myName;

...


try {
  insert attachment;
} catch (DMLException e) {
  ApexPages.addMessage(new ApexPages.message(ApexPages.severity.ERROR,'Error uploading attachment'));
  return null;
}
[/code]
вот нашел

http://forceguru.blogspot.com/2010/11/best-practise-to-write-apex.html

http://salesforce.stackexchange.com/questions/50404/viewstate-issue-unable-to-clear-attachments-if-there-are-any-failures-in-the-tr

и - да - пишут что Transient

буду разбираться

не пойму почему так не работает

Public transient Attachment attachment{get; set;}

и выпадает перед ставкой аттача на System.NullPointerException: Attempt to de-reference a null object

здесь

if(attachment.body!=null&& attachment.name!=null){

буду пробовать с

public Transient String myName { get; set; }
public Transient Blob myBlob{ get; set; }

не пойму почему так не работает

[code]Public transient Attachment attachment{get; set;}[/code]

и выпадает перед ставкой аттача на System.NullPointerException: Attempt to de-reference a null object

здесь  
[code]if(attachment.body!=null&& attachment.name!=null){[/code] 

буду пробовать с

[code]public Transient String myName { get; set; }
public Transient Blob myBlob{ get; set; }[/code]

Den Brown
public Transient String myName { get; set; }
public Transient Blob myBlob{ get; set; }

да вот так работает нормально. Шудо шудное. и нигде после вставки или не вставки аттача не нужно "затирать" поля myName и myBlob, а сам аттач переменная локальная... код стал короче. только я вывел инициацию Аттача из Трая иначе не смог обратиться к нему в Кетче (в связи с тем что там несколько аттачей, то уже вставленные Аттачи при необходимости должны удаляться в Кетче)

спасибо Alex

[quote="Den Brown"]public Transient String myName { get; set; }
public Transient Blob myBlob{ get; set; }[/quote]

да вот так работает нормально. Шудо шудное. и нигде после вставки или не вставки аттача не нужно "затирать" поля myName и myBlob, а сам аттач переменная локальная... код стал короче. только я вывел инициацию Аттача из Трая иначе не смог обратиться к нему в Кетче (в связи с тем что там несколько аттачей, то уже вставленные Аттачи при необходимости должны удаляться в Кетче)

спасибо Alex 

ну вот, теперь интересная ситуация.

так как в случае, если контроллер вернул страницу с ошибками по валидации, и все аттачменты не сохранились, сбросились, то юзеру нужно их заново приатачить.

и для этого ему нужно сообщить большими буквами об этом. Т.е. добавить этот тескт в шапку секции Error сообщений. Но сами эти сообщения могут быть разными по природе, в том числе и стандартная валидация по типу поля, где мы не может контроллировать собержание сообщения.

и я не вижу в <apex:messages styleClass="message"/> возможности воткнуть общий для всех сообщение текст...

придется JSсом цеплять этот див, хотя... можно попробовать и CSS content-ом воткнуть кусок текста...

ну вот, теперь интересная ситуация.

так как в случае, если контроллер вернул страницу с ошибками по валидации, и все аттачменты не сохранились, сбросились, то юзеру нужно их заново приатачить.

и для этого ему нужно сообщить большими буквами об этом. Т.е. добавить этот тескт в шапку секции Error сообщений. Но сами эти сообщения могут быть разными по природе, в том числе и стандартная валидация по типу поля, где мы не может контроллировать собержание сообщения.

и я не вижу в <apex:messages styleClass="message"/> возможности воткнуть общий для всех сообщение текст...

придется JSсом цеплять этот див, хотя... можно попробовать и CSS content-ом воткнуть кусок текста...

да,

.message:before {
content: "HELLO CONTENT";
}

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

да,
[code]             .message:before {
                    content: "HELLO CONTENT";
            }[/code] 

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

Я как-то придумал себе такую конструкцию
в контроллере:

public Boolean pageHasErrors { get{
return ApexPages.hasMessages();
} set;}

на странице
<apex:outputPanel layout="none" rendered="{!pageHasErrors}">
...
<apex:outputPanel>

Т.е. получается что блок рендерится если есть хотябы одно сообщение об ошибке.

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

А вообще, этот случай достаточно частый и никто не заморачивается с показом такого сообщения. Вроде даже можешь проверить на странице подгрузки Static Resources в Salesforce.

Я как-то придумал себе такую конструкцию
в контроллере:
[code]
  public Boolean pageHasErrors { get{
    return ApexPages.hasMessages();
  } set;}
[/code]
на странице
[code]
<apex:outputPanel layout="none" rendered="{!pageHasErrors}">
...
<apex:outputPanel>
[/code]
Т.е. получается что блок рендерится если есть хотябы одно сообщение об ошибке.

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

А вообще, этот случай достаточно частый и никто не заморачивается с показом такого сообщения. Вроде даже можешь проверить на странице подгрузки Static Resources в Salesforce.

Dmitry Shnyrev
return ApexPages.hasMessages();

вот это очень хорошо,

но вся штука в

Dmitry Shnyrev
Но не уверен что это сработает если произойдет страничная валидация (без контроллера)

вот если бы это страбатывало и для "до-контроллерной" валидации, то было просто прекрасно...

[quote="Dmitry Shnyrev"]   return ApexPages.hasMessages();[/quote]

вот это очень хорошо,

но вся штука в

[quote="Dmitry Shnyrev"]Но не уверен что это сработает если произойдет страничная валидация (без контроллера)[/quote]

вот если бы это страбатывало и для "до-контроллерной" валидации, то было просто прекрасно...

Den Brown
вот если бы это страбатывало и для "до-контроллерной" валидации, то было просто прекрасно...

Мы же уже поднимали эту тему - избавляемся от страничной валидации (это зло) и валидируем прямо в контроллере или в триггере.

[quote="Den Brown"]вот если бы это страбатывало и для "до-контроллерной" валидации, то было просто прекрасно...[/quote]
Мы же уже поднимали эту тему - избавляемся от страничной валидации (это зло) и валидируем прямо в контроллере или в триггере.

Dmitry Shnyrev
Мы же уже поднимали эту тему - избавляемся от страничной валидации (это зло) и валидируем прямо в контроллере или в триггере.

да, Бог с тобой, как же если ты выводишь поле (записи) типа Емейл, чтож его заменять на временное текстовое поле и вручную валидировать в контроллере на емейльность?

[quote="Dmitry Shnyrev"]Мы же уже поднимали эту тему - избавляемся от страничной валидации (это зло) и валидируем прямо в контроллере или в триггере.[/quote]

да, Бог с тобой, как же если ты выводишь поле (записи) типа Емейл, чтож его заменять на временное текстовое поле и вручную валидировать в контроллере на емейльность?

ты меня понял

:D ты меня понял

Подожди, а если попробовать невалидный email записать в поле типа email и попробовать сохранить в базу, разве не вернет Exception? Можно тогда принимать email в виде текста и просто пробовать пихать в базу. Но это конечно костыль Но лучше провалидировать и выдать человеческое предупреждение.

Подожди, а если попробовать невалидный email записать в поле типа email и попробовать сохранить в базу, разве не вернет Exception? Можно тогда принимать email в виде текста и просто пробовать пихать в базу. Но это конечно костыль :) Но лучше провалидировать и выдать человеческое предупреждение.

Dmitry Shnyrev
Мы же уже поднимали эту тему - избавляемся от страничной валидации (это зло) и валидируем прямо в контроллере или в триггере.

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

[quote="Dmitry Shnyrev"]Мы же уже поднимали эту тему - избавляемся от страничной валидации (это зло) и валидируем прямо в контроллере или в триггере.[/quote]
Я, например, считаю, что валидация обязательно должна быть на клиенте.

Gres
Я, например, считаю, что валидация обязательно должна быть на клиенте.

Если красивая валидация с помощью js, то я согласен, а если это страничная валидация Salesforce, которая один фиг проводится на сервере и еще лишает нас какой-либо гибкости (управлять процессом нельзя), то нафиг такая валидация нужна.

[quote="Gres"]Я, например, считаю, что валидация обязательно должна быть на клиенте.[/quote]
Если красивая валидация с помощью js, то я согласен, а если это страничная валидация Salesforce, которая один фиг проводится на сервере и еще лишает нас какой-либо гибкости (управлять процессом нельзя), то нафиг такая валидация нужна.

Dmitry Shnyrev
Если красивая валидация с помощью js, то я согласен, а если это страничная валидация Salesforce, которая один фиг проводится на сервере и еще лишает нас какой-либо гибкости (управлять процессом нельзя), то нафиг такая валидация нужна.

Я использую принцип ненавящивого JS

[quote="Dmitry Shnyrev"]Если красивая валидация с помощью js, то я согласен, а если это страничная валидация Salesforce, которая один фиг проводится на сервере и еще лишает нас какой-либо гибкости (управлять процессом нельзя), то нафиг такая валидация нужна.[/quote]
Я использую принцип ненавящивого JS

JS это хорошо, но меня все равно напрягает по 2 раза писать валидацию. Поэтому если нет конкретных требований, то оставляю только серверную часть.

JS это хорошо, но меня все равно напрягает по 2 раза писать валидацию. Поэтому если нет конкретных требований, то оставляю только серверную часть. 

Dmitry Shnyrev
JS это хорошо, но меня все равно напрягает по 2 раза писать валидацию. Поэтому если нет конкретных требований, то оставляю только серверную часть.

Это долго и не юзер френдли

[quote="Dmitry Shnyrev"]JS это хорошо, но меня все равно напрягает по 2 раза писать валидацию. Поэтому если нет конкретных требований, то оставляю только серверную часть. [/quote]
Это долго и не юзер френдли

Знаешь, тут больше вопрос желания сделать красиво. Вот если проект нравится и еще не успел испортиться, то, согласен, можно и про юзера подумать. Но когда проект надоедеат и изменения требований льются как из рога изобилия, то тут уже юзеры уходят на второй план, а на первый план выходит "побыстрее сделать".

Знаешь, тут больше вопрос желания сделать красиво. Вот если проект нравится и еще не успел испортиться, то, согласен, можно и про юзера подумать. Но когда проект надоедеат и изменения требований льются как из рога изобилия, то тут уже юзеры уходят на второй план, а на первый план выходит "побыстрее сделать".

Dmitry Shnyrev
Знаешь, тут больше вопрос желания сделать красиво. Вот если проект нравится и еще не успел испортиться, то, согласен, можно и про юзера подумать. Но когда проект надоедеат и изменения требований льются как из рога изобилия, то тут уже юзеры уходят на второй план, а на первый план выходит "побыстрее сделать".

Согласен, что все определяется отношением!

[quote="Dmitry Shnyrev"]Знаешь, тут больше вопрос желания сделать красиво. Вот если проект нравится и еще не успел испортиться, то, согласен, можно и про юзера подумать. Но когда проект надоедеат и изменения требований льются как из рога изобилия, то тут уже юзеры уходят на второй план, а на первый план выходит "побыстрее сделать".[/quote]
Согласен, что все определяется отношением!