Saving form data and sending email

Dec 23, 2010 at 2:20 AM

I'm trying to write some simple forms on orchid. The user will enter data into a few fields and click submit.  Orchid will then save the fields and email them to someone.  I want to do this the "proper" way instead of bootlegging it with SqlConnection and System.Net.Smtp.

For saving the fields, I was thinking of using a Custom Type created by the admin panel, but looking into that more, I'm not sure if that's the appropriate method.

So I created a module (currently hello worlds just fine).  I made a data migration to create my table (also works fine).  Now I'm trying to save some form data from an object created by doing a Services.ContentManager.New<ContractRequestPart>("ContractRequest");.  The model class is ContractRequest, but can't seem to find an appropriate method to save it (and not publish it).

For email  I looked at Orchard.Email.  I saw from a post here to look at UserService.cs in Orchard.Users to send email.  However that has an object which implements IMessageService passed to it.  I can't seem to find a way to instantiate a DefaultMessageManager due to what the constructor requires.

Sorry for the silly questions, but there isn't all that much information out on the web for Orchard yet.

Coordinator
Dec 23, 2010 at 2:59 AM

I think what you want to create is a content item, not just a part. There are examples of that in SetupService.

As for the dependency injection of IMessageService, the framework is taking care of that for you. You just need a constructor that takes the right interface type as a parameter.

Dec 23, 2010 at 3:23 AM

I got the saving part working, thanks.  I made a mistake and didn't setup a handler properly.

I'm looking into email again.

Dec 23, 2010 at 5:39 AM

I was able to get it working with a little more poking at it.

Thanks for the help.

Dec 23, 2010 at 8:09 AM
Post your code and show us what you did

Sent from my iPhone

On 23/12/2010, at 5:39 PM, "Revision17"<notifications@codeplex.com> wrote:

From: Revision17

I was able to get it working with a little more poking at it.

Thanks for the help.

Dec 23, 2010 at 2:57 PM

So I'm sure this isn't the best way of doing it, but I just needed to get a demo out of the way and haven't gotten it cleaned up the right way.  For email I needed to create a class to cover IMessageEventHandler:

 

 public class MyMessagingEventHandler : IMessageEventHandler
    {
        public ContractRequestPart request = new ContractRequestPart();

        
        public void Sending(MessageContext context)
        {
            context.MailMessage.To.Add(new System.Net.Mail.MailAddress("me@example.com"));
            context.MailMessage.Subject = "Contract Request";
            context.MailMessage.Body = string.Format(@"
First Name: {0}
Last Name: {1}
Email: {2}
Fax #: {3}
",
                request.Record.FirstName,
                request.Record.LastName,
                request.Record.Email,
                request.Record.FaxNumber);
            
        }
        public void Sent(MessageContext context)
        {
            
        }
    }

So then in an action in my controller I did this:

public ActionResult SaveContracts(string FirstName, string LastName, string FaxNumber, string Email)
        {

            var request = Services.ContentManager.New<ContractRequestPart>("ContractRequest");
            request.Record.FirstName = FirstName;
            request.Record.LastName = LastName;
            request.Record.FaxNumber = FaxNumber;
            request.Record.Email = Email;
            Services.ContentManager.Create(request);


            Messaging.Events.MyMessagingEventHandler handler = new Messaging.Events.MyMessagingEventHandler();
            handler.request = request;
            DefaultMessageManager boo = new DefaultMessageManager(handler,
                new IMessagingChannel[] { new Orchard.Email.Services.EmailMessagingChannel(Services) });
            ContentItemRecord asdf = new ContentItemRecord();
            asdf.Data = "<Boo>request.Record.FirstName</Boo>";
            SecurityProtocolType oldSecurityProtocol = ServicePointManager.SecurityProtocol;        //Since this is a framework-wide change, it's important to be able to undo it so programs that may be expecting different settings to break
            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
            boo.Send(asdf, "ContractNotification", "email");
            ServicePointManager.SecurityProtocol = oldSecurityProtocol;        //restore default security protocol
            return this.Redirect("~");
        }

Not really sure what the ContentItemRecord was for, other than Data needed to be some XML element.  I also couldn't make the constructor to  MyMessagingEventHandler take a ContractRequestPart since orchard didn't like that, so I passed it in via a property.

Orchard doesn't seem to support setting TLS in smtp settings so I had to set that manually (yes there's a race condition here, but this is demo code).

I highly doubt this follows the best practices of Orchard, so please criticize. 

 

 

Feb 16, 2011 at 12:40 AM

Are you going create another module for messaging in the purpose to send body , subject and email content? I found that the current messaging module is only functioning to send email to the recipient. How we are going to use current messaging module and add some dynamic parameters for contents?

 

Thanks.

 

Dec 7, 2011 at 1:41 AM
vteck328 wrote:

Are you going create another module for messaging in the purpose to send body , subject and email content? I found that the current messaging module is only functioning to send email to the recipient. How we are going to use current messaging module and add some dynamic parameters for contents?

 

Thanks.

 

That is how Handler working, you can create your own email handler, but only send with your channel.