EmailTemplateDataSource.Load(), read-only?
- crockettdunn
- Lieutenant Commander (LCDR)
- Posts: 105
- Joined: Sun Oct 26, 2008 6:32 pm
- Contact:
EmailTemplateDataSource.Load(), read-only?
very basic question:
Is EmailTemplateDataSource.Load() supposed to be read-only, or read-write?
Here's my problem: A developer was trying to use an email template in the traditional sense of a “template,” to "fill in the blanks" (populate parameters with values), and send an email.
But when the values are set in the code as follows
mail.ToAddress = "email.yourdomain.xyx";
email.AddBccAddress("email.yourdomain.xyx ");
email.FromAddress = Email.Text;
These values are also updated to the SQL database and can be seen as the new Email Template settings.
It occurs to me that this may be working exactly as it's supposed to, and I just need to read more about how to use email template parameters. However, I'm scratching my head, because the problem I described is exhibited for a particular control on one site, but not the other (identical controls). So I'm wondering if the behavior of EmailTemplateDataSource.Load() has changed between CommerceBuilder versions, or if I have to chase down some customization to one of the code dependencies.
Thanks for your help,
Crockett
Is EmailTemplateDataSource.Load() supposed to be read-only, or read-write?
Here's my problem: A developer was trying to use an email template in the traditional sense of a “template,” to "fill in the blanks" (populate parameters with values), and send an email.
But when the values are set in the code as follows
mail.ToAddress = "email.yourdomain.xyx";
email.AddBccAddress("email.yourdomain.xyx ");
email.FromAddress = Email.Text;
These values are also updated to the SQL database and can be seen as the new Email Template settings.
It occurs to me that this may be working exactly as it's supposed to, and I just need to read more about how to use email template parameters. However, I'm scratching my head, because the problem I described is exhibited for a particular control on one site, but not the other (identical controls). So I'm wondering if the behavior of EmailTemplateDataSource.Load() has changed between CommerceBuilder versions, or if I have to chase down some customization to one of the code dependencies.
Thanks for your help,
Crockett
-
- Commodore (COMO)
- Posts: 436
- Joined: Tue May 07, 2013 1:59 pm
Re: EmailTemplateDataSource.Load(), read-only?
It is working as it is supposed to. If you want to set the the addresses to something different than what is stored in the database, I guess you could use the EmailTemplate.copy(...) function and not save the new template to the database.
Note that if the "To" address (for instance) contains "customer" in the database, and you add a customer (or order) to the template as a parameter (theTemplate.Parameters.Add("customer", aCustomer)), the template will look up the customer's email address and fill it in. Disclaimer: I didn't test this right now, but I'm pretty sure that's what I'm doing in some of my customizations.
Note that if the "To" address (for instance) contains "customer" in the database, and you add a customer (or order) to the template as a parameter (theTemplate.Parameters.Add("customer", aCustomer)), the template will look up the customer's email address and fill it in. Disclaimer: I didn't test this right now, but I'm pretty sure that's what I'm doing in some of my customizations.
Jay
- crockettdunn
- Lieutenant Commander (LCDR)
- Posts: 105
- Joined: Sun Oct 26, 2008 6:32 pm
- Contact:
Re: EmailTemplateDataSource.Load(), read-only?
Thanks, Jay.
Any idea why this behavior is not occurring on another copy of the site?
Crockett
Any idea why this behavior is not occurring on another copy of the site?
Crockett
- jmestep
- AbleCommerce Angel
- Posts: 8164
- Joined: Sun Feb 29, 2004 8:04 pm
- Location: Dayton, OH
- Contact:
Re: EmailTemplateDataSource.Load(), read-only?
I'm not sure if this is related, but older version(s) of Able had a bug where pieces of data like the to address were stored in the database. For example, every time someone placed an order, the to address that showed in the admin for the email template was populated with the order's email address. Then the next order changed it to that order's email address. The to email address that shows in the admin/is stored in the database should be populated with "customer". This was corrected, but I don't remember what build.
Judy Estep
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx
-
- Commodore (COMO)
- Posts: 436
- Joined: Tue May 07, 2013 1:59 pm
Re: EmailTemplateDataSource.Load(), read-only?
No idea, there must be some difference in the AC version and/or customizations.crockettdunn wrote:Thanks, Jay.
Any idea why this behavior is not occurring on another copy of the site?
Crockett
EDIT: After re-reading your original post and Judy's response, it does seem strange that if all you are doing is a .Load(), the changed values of the properties are getting written back to the database. Some code somewhere must be calling the template's .Save() method on the site that exhibits this behavior.
Jay
- crockettdunn
- Lieutenant Commander (LCDR)
- Posts: 105
- Joined: Sun Oct 26, 2008 6:32 pm
- Contact:
Re: EmailTemplateDataSource.Load(), read-only?
Thanks Judy/Jay,
Judy- that's exactly what's going on. Do you remember if that bug was in a Gold version?
I'm relieved to know there's a history of this occurring, and now I know to look for the .Save() method being called.
cd
Judy- that's exactly what's going on. Do you remember if that bug was in a Gold version?
I'm relieved to know there's a history of this occurring, and now I know to look for the .Save() method being called.
cd
- jmestep
- AbleCommerce Angel
- Posts: 8164
- Joined: Sun Feb 29, 2004 8:04 pm
- Location: Dayton, OH
- Contact:
Re: EmailTemplateDataSource.Load(), read-only?
It looks like it was R3 & R4 according to patch log.
http://help.ablecommerce.com/upgrades/a ... s_gold.htm
Issue ID AC8-1837
http://help.ablecommerce.com/upgrades/a ... s_gold.htm
Issue ID AC8-1837
Judy Estep
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx
Web Developer
jestep@web2market.com
http://www.web2market.com
708-653-3100 x209
New search report plugin for business intelligence:
http://www.web2market.com/Search-Report ... -P154.aspx
Re: EmailTemplateDataSource.Load(), read-only?
In Able 7.x, you could freely update the properties of a loaded object without fear of those changes being written back to the database. You knew the only way that could happen is if you called .Save().
But with email templates, by design, the only way to send them was to change the properties of the loaded template object.
However, in Able Gold you have to look at data objects a little differently. nHibernate is now involved and many of the rules change. The issue lies within how nHibernate works and how it is implemented inside AbleCommerce. At the end of the execution of the page code, nHibernate checks all data objects in memory. If a loaded data object is dirty (any values different from original load values), each of those objects are automatically persisted back to the database.
It's a bad practice to be changing loaded data objects in memory. But, you don't have much choice given how the old email template implementation was designed by Able.
The solution is simple:
When modifying an existing object and you do NOT want the modifications to persist to the database, you must evict the object from memory before the end of your code execution. It's a hassle, but necessary given the current implementation of nHibernate.
For example:
This will tell nHibernate to dump what it knows about the object in memory. Any changes to the object will not be persisted.
When I'm working with a specific email template, I follow these general steps:
Load the template
Set the properties
Call .Send()
session.Evict(template)
The email template design wasn't the greatest implementation in the world. It should have used a separate 'settings' class and handed the work off to a 'service' class. Able reworked it several versions ago. Now there is a whole Mail-Merge behavior implemented that works in a much cleaner way. You can see how this is done in ~/Admin/UserControls/SendEmail.ascx.cs. Works for any number of recipients, so you can use it just for 1 if you need.
Able's done a good job implementing the 'service' class concept in Gold. BasketService, CouponService etc. It's more work and adds more complexity to coding, but it separates responsibilities much better. I didn't like it at first because it was so different. Now I really enjoy how they did it. Just makes more sense.
But with email templates, by design, the only way to send them was to change the properties of the loaded template object.
However, in Able Gold you have to look at data objects a little differently. nHibernate is now involved and many of the rules change. The issue lies within how nHibernate works and how it is implemented inside AbleCommerce. At the end of the execution of the page code, nHibernate checks all data objects in memory. If a loaded data object is dirty (any values different from original load values), each of those objects are automatically persisted back to the database.
It's a bad practice to be changing loaded data objects in memory. But, you don't have much choice given how the old email template implementation was designed by Able.
The solution is simple:
When modifying an existing object and you do NOT want the modifications to persist to the database, you must evict the object from memory before the end of your code execution. It's a hassle, but necessary given the current implementation of nHibernate.
For example:
Code: Select all
ISession session = AbleContext.Current.Database.GetSession();
session.Evict(template);
When I'm working with a specific email template, I follow these general steps:
Load the template
Set the properties
Call .Send()
session.Evict(template)
The email template design wasn't the greatest implementation in the world. It should have used a separate 'settings' class and handed the work off to a 'service' class. Able reworked it several versions ago. Now there is a whole Mail-Merge behavior implemented that works in a much cleaner way. You can see how this is done in ~/Admin/UserControls/SendEmail.ascx.cs. Works for any number of recipients, so you can use it just for 1 if you need.
Able's done a good job implementing the 'service' class concept in Gold. BasketService, CouponService etc. It's more work and adds more complexity to coding, but it separates responsibilities much better. I didn't like it at first because it was so different. Now I really enjoy how they did it. Just makes more sense.
Joe Payne
AbleCommerce Custom Programming and Modules http://www.AbleMods.com/
AbleCommerce Hosting http://www.AbleModsHosting.com/
Precise Fishing and Hunting Time Tables http://www.Solunar.com
AbleCommerce Custom Programming and Modules http://www.AbleMods.com/
AbleCommerce Hosting http://www.AbleModsHosting.com/
Precise Fishing and Hunting Time Tables http://www.Solunar.com
- crockettdunn
- Lieutenant Commander (LCDR)
- Posts: 105
- Joined: Sun Oct 26, 2008 6:32 pm
- Contact:
Re: EmailTemplateDataSource.Load(), read-only?
Thanks, Joe!