Всем привет! столкнулся с проблемой, которая показалось мне интересной.
ЕСть ВФ пейдж с контроллером, которые создают запись, при этом к этой записи можно единомоментно прикрепись один или несколько аттачей.
В случе успешного или не успешного выполнения ДМЛ операций (а также при неудачной кастомной валидации) все аттачи вычищаются (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 {
Несовсем понял что тебе нужно, но может поможет 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]
на ВФ странице есть файловый инпут
<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
и - да - пишут что Transient
буду разбираться
вот нашел 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]
да вот так работает нормально. Шудо шудное. и нигде после вставки или не вставки аттача не нужно "затирать" поля 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.
вот это очень хорошо,
но вся штука в
вот если бы это страбатывало и для "до-контроллерной" валидации, то было просто прекрасно...
[quote="Dmitry Shnyrev"] return ApexPages.hasMessages();[/quote] вот это очень хорошо, но вся штука в [quote="Dmitry Shnyrev"]Но не уверен что это сработает если произойдет страничная валидация (без контроллера)[/quote] вот если бы это страбатывало и для "до-контроллерной" валидации, то было просто прекрасно...
[quote="Den Brown"]вот если бы это страбатывало и для "до-контроллерной" валидации, то было просто прекрасно...[/quote] Мы же уже поднимали эту тему - избавляемся от страничной валидации (это зло) и валидируем прямо в контроллере или в триггере.
да, Бог с тобой, как же если ты выводишь поле (записи) типа Емейл, чтож его заменять на временное текстовое поле и вручную валидировать в контроллере на емейльность?
[quote="Dmitry Shnyrev"]Мы же уже поднимали эту тему - избавляемся от страничной валидации (это зло) и валидируем прямо в контроллере или в триггере.[/quote] да, Бог с тобой, как же если ты выводишь поле (записи) типа Емейл, чтож его заменять на временное текстовое поле и вручную валидировать в контроллере на емейльность?
ты меня понял
:D ты меня понял
Подожди, а если попробовать невалидный email записать в поле типа email и попробовать сохранить в базу, разве не вернет Exception? Можно тогда принимать email в виде текста и просто пробовать пихать в базу. Но это конечно костыль Но лучше провалидировать и выдать человеческое предупреждение.
Подожди, а если попробовать невалидный email записать в поле типа email и попробовать сохранить в базу, разве не вернет Exception? Можно тогда принимать email в виде текста и просто пробовать пихать в базу. Но это конечно костыль :) Но лучше провалидировать и выдать человеческое предупреждение.
[quote="Dmitry Shnyrev"]Мы же уже поднимали эту тему - избавляемся от страничной валидации (это зло) и валидируем прямо в контроллере или в триггере.[/quote] Я, например, считаю, что валидация обязательно должна быть на клиенте.
[quote="Gres"]Я, например, считаю, что валидация обязательно должна быть на клиенте.[/quote] Если красивая валидация с помощью js, то я согласен, а если это страничная валидация Salesforce, которая один фиг проводится на сервере и еще лишает нас какой-либо гибкости (управлять процессом нельзя), то нафиг такая валидация нужна.
[quote="Dmitry Shnyrev"]Если красивая валидация с помощью js, то я согласен, а если это страничная валидация Salesforce, которая один фиг проводится на сервере и еще лишает нас какой-либо гибкости (управлять процессом нельзя), то нафиг такая валидация нужна.[/quote] Я использую принцип ненавящивого JS
JS это хорошо, но меня все равно напрягает по 2 раза писать валидацию. Поэтому если нет конкретных требований, то оставляю только серверную часть.
JS это хорошо, но меня все равно напрягает по 2 раза писать валидацию. Поэтому если нет конкретных требований, то оставляю только серверную часть.
[quote="Dmitry Shnyrev"]JS это хорошо, но меня все равно напрягает по 2 раза писать валидацию. Поэтому если нет конкретных требований, то оставляю только серверную часть. [/quote] Это долго и не юзер френдли
Знаешь, тут больше вопрос желания сделать красиво. Вот если проект нравится и еще не успел испортиться, то, согласен, можно и про юзера подумать. Но когда проект надоедеат и изменения требований льются как из рога изобилия, то тут уже юзеры уходят на второй план, а на первый план выходит "побыстрее сделать".
Знаешь, тут больше вопрос желания сделать красиво. Вот если проект нравится и еще не успел испортиться, то, согласен, можно и про юзера подумать. Но когда проект надоедеат и изменения требований льются как из рога изобилия, то тут уже юзеры уходят на второй план, а на первый план выходит "побыстрее сделать".
[quote="Dmitry Shnyrev"]Знаешь, тут больше вопрос желания сделать красиво. Вот если проект нравится и еще не успел испортиться, то, согласен, можно и про юзера подумать. Но когда проект надоедеат и изменения требований льются как из рога изобилия, то тут уже юзеры уходят на второй план, а на первый план выходит "побыстрее сделать".[/quote] Согласен, что все определяется отношением!