andrewdavey / postal Goto Github PK
View Code? Open in Web Editor NEWEmail sending for asp.net mvc using the view engine system to render emails.
Home Page: http://aboutcode.net/postal
License: MIT License
Email sending for asp.net mvc using the view engine system to render emails.
Home Page: http://aboutcode.net/postal
License: MIT License
Postal - A handy email sending library for ASP.NET MVC. by Andrew Davey ( http://aboutcode.net , http://twitter.com/andrewdavey ) Postal uses the MVC view engine infrastructure to render emails. Read the introduction: http://aboutcode.net/postal The wiki has documentation: https://github.com/andrewdavey/postal/wiki See the MvcSample project for a basic overview of usage.
What do I need to implement in my custom view engine so that Postal will work? It works fine with the default ASP.NET MVC 4 Razor view engine but not with mine which inherits from RazorViewEngine.
When it's trying to build an email, it says:
The method or operation is not implemented.
@blowdart on twitter is asking for a strong name
Allow setting the email priority.
You can get the generated MailMessage, without sending it, using this method.
Hi,
I think it would be nice if we could use some conventions to localize e-mails. For example if we could create views with names similar to *.resx files:
Or:
I prefer the second approach. What do you think?
Thank you!
I have a class library where I need to send emails with images.
I get the following error when using @Html.EmbedImage. I'm using the MultiPart example but in a class library.
Unable to compile template. The name 'Html' does not exist in the current context.
Is this possible?
Why would you want to reference the unreleased version of MVC in the source? It really breaks in all my projects using MVC 3.0.
I get the following error when trying to send an email through postal 0.8.2 (asp.net mvc 4, .net 4.5):
2013-03-25 12:52:13.4430 DealerHub.Services.EventConsumer.EConsumer ERROR System.MissingMethodException: Method not found: 'Void System.Web.Razor.RazorEngineHost..ctor(System.Web.Razor.RazorCodeLanguage, System.Func1<System.Web.Razor.Parser.ParserBase>)'. at RazorEngine.Compilation.RazorEngineHost..ctor(RazorCodeLanguage language, Func
1 markupParserFactory)
at RazorEngine.Compilation.CompilerServiceBase.CreateHost(Type templateType, Type modelType, String className) in c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Compilation\CompilerServiceBase.cs:line 110
at RazorEngine.Compilation.CompilerServiceBase.GetCodeCompileUnit(String className, String template, ISet`1 namespaceImports, Type templateType, Type modelType) in c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Compilation\CompilerServiceBase.cs:line 177
at RazorEngine.Compilation.DirectCompilerServiceBase.Compile(TypeContext context) in c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Compilation\DirectCompilerServiceBase.cs:line 53
at RazorEngine.Compilation.DirectCompilerServiceBase.CompileType(TypeContext context) in c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Compilation\DirectCompilerServiceBase.cs:line 102
at RazorEngine.Templating.TemplateService.CreateTemplateType(String razorTemplate, Type modelType) in c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line 256
at RazorEngine.Templating.TemplateService.GetTemplate[T](String razorTemplate, Object model, String cacheName) in c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line 374
at RazorEngine.Templating.TemplateService.GetTemplate(String razorTemplate, Object model, String cacheName) in c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line 352
at RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName) in c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:line 437
at RazorEngine.Razor.Parse(String razorTemplate, Object model, String cacheName) in c:\Users\Matthew\Documents\GitHub\RazorEngine\src\Core\RazorEngine.Core\Razor.cs:line 302
at Postal.FileSystemRazorView.Render(ViewContext viewContext, TextWriter writer)
at Postal.EmailViewRenderer.RenderView(IView view, ViewDataDictionary viewData, ControllerContext controllerContext)
at Postal.EmailViewRenderer.Render(Email email, String viewName)
at Postal.EmailService.CreateMailMessage(Email email)
at Postal.EmailService.Send(Email email)
at CallSite.Target(Closure , CallSite , IEmailService , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2[T0,T1](CallSite site, T0 arg0, T1 arg1)
What am I doing wrong?
Tests are ran as MSpec + Machine.Fakes
Web App is MVC3, inside is RegistrationOrchestrator which is the class I'm testing. The orchestrator initiates the send email with the view located in Views/Emails/ and this works correctly when ran as a web app.
When this is executed from the unit test:
exception {"Object reference not set to an instance of an object."} System.Exception {System.NullReferenceException}
InnerException null System.Exception
Source "System.Web" string
StackTrace
at System.Web.VirtualPath.GetCacheKey()
at System.Web.Compilation.BuildManager.GetCacheKeyFromVirtualPath(VirtualPath virtualPath, Boolean& keyFromVPP)
at System.Web.Compilation.BuildManager.GetVPathBuildResultFromCacheInternal(VirtualPath virtualPath, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)
at System.Web.Compilation.BuildManager.GetVirtualPathObjectFactory(VirtualPath virtualPath, HttpContext context, Boolean allowCrossApp, Boolean throwIfNotFound)
at System.Web.Compilation.BuildManager.GetObjectFactory(String virtualPath, Boolean throwIfNotFound)
at System.Web.Mvc.BuildManagerWrapper.System.Web.Mvc.IBuildManager.FileExists(String virtualPath)
at System.Web.Mvc.BuildManagerViewEngine.FileExists(ControllerContext controllerContext, String virtualPath)
at System.Web.Mvc.VirtualPathProviderViewEngine.GetPathFromGeneralName(ControllerContext controllerContext, List1 locations, String name, String controllerName, String areaName, String cacheKey, String[]& searchedLocations) at System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext, String[] locations, String[] areaLocations, String locationsPropertyName, String name, String controllerName, String cacheKeyPrefix, Boolean useCache, String[]& searchedLocations) at System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext controllerContext, String viewName, String masterName, Boolean useCache) at System.Web.Mvc.ViewEngineCollection.<>c__DisplayClassc.<FindView>b__b(IViewEngine e) at System.Web.Mvc.ViewEngineCollection.Find(Func
2 lookup, Boolean trackSearchedPaths)
at System.Web.Mvc.ViewEngineCollection.Find(Func2 cacheLocator, Func
2 locator)
at System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext controllerContext, String viewName, String masterName)
at Postal.EmailViewRenderer.CreateView(String viewName, ControllerContext controllerContext)
at Postal.EmailViewRenderer.Render(Email email, String viewName)
at Postal.EmailService.CreateMailMessage(Email email)
at Postal.EmailService.Send(Email email)
at Postal.Email.Send()
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
at Orchestrators.RegistrationOrchestrator.TrySendEmail(RegistrationViewModel newRegistration) in C:\Projects..Orchestrators\RegistrationOrchestrator.cs:line 97
When not in asp.net we don't need the _viewstart.cshtml to be added to the project. So maybe have a separate "baseline" Postal package with just the library and then a Postal.Web package with the content, etc.
When installing the MVC postal nuGet package I get a warning during the build process.
"Found conflicts between different versions of the same dependent assembly."
I tried searching the internets and messing with the web.config. It got to the ponit where even when I uninstalled the package, I was still getting the issue. I had create a brand new project.
I think it has something to do with the clash or Razor engines?
seems the problem is here:
string RenderView(IView view, ViewDataDictionary viewData, ControllerContext controllerContext)
{
using (var writer = new StringWriter())
{
var viewContext = new ViewContext(controllerContext, view, viewData, new TempDataDictionary(), writer);
view.Render(viewContext, writer);
return writer.GetStringBuilder().ToString();
}
}
view.Render throws a The method or operation is not implemented.
Any idea?
This page has a nice writeup:
http://www.systemnetmail.com/faq/4.4.aspx
So, instead of linking to images using I'd like to embed them and use .
Is this possible using Postal?
It would be nice to have the GetLocalResourceObject and GetGlobalResourceObject methods available in EmailHttpContext to make multilanguage Emails
First off, stellar product. Been using this since your session in mvcConf 2 and love the ease of use and feature set.
I recently started a project where I use Postal to send emails for certain parts of the site. Postal worked fine before I add 51Degrees.mobi to the mix. I use 51Degrees.mobi to detect if the browser is a mobile browser, and set the Layout according in a ASP.NET MVC 3 project, like so:
Layout = Request.Browser.IsMobileDevice
? "~/Views/Shared/_LayoutMobile.cshtml"
: "~/Views/Shared/_Layout.cshtml";
51Degrees.mobi (as stated here: http://51degrees.codeplex.com) uses an HttpModules to intercept the HttpRequests. Took me a little while to work out that Postal is presenting Postal.EmailHttpRequest
as the HttpRequest, which does not implement the Browser
property, which then throws an Exception that the method is not implemented.
Since I can't reflect on the type since Postal.EmailHttpRequest
is internal or protected, I can't detect the different HttpRequest, or at least I don't know how. The immediate workaround I see is putting a try{}catch{}
block around, but that doesn't sit write long term.
What do you recommend I do? This isn't Postal's fault, but I confess I don't know where to go to fix this.
EmailHttpRequest currently builds a URI using HTTP. Perhaps we need to add an HTTPS option here.
I've been watching your screencast and I've read the wiki's and blog but can't seem to find how to support display names. Now the .NET's MailAddress class does support proving both the display name and the email address to the constructor.
I would like to be able to specify the display name for the emails I sent because it looks better and friendlier and it might even bypass a bit higher number of antispam filters than when just specifying the email address.
Is it possible?
If there are some accentuated (àäéèç...) characters in an email view, then the Content-Transfer-Encoding switches to base64 (instead of quoted-printable), and the email becomes unreadable.
You can do a test with the following view:
To: [email protected]
From: [email protected]
Subject: Grüß Dich!
Comment ça va?
Hence it is not possible to send plain text emails in languages using accentuated characters (basically languages other than English).
A workaround is to provide the email in both plain text and html, as specified on https://github.com/andrewdavey/postal/wiki/Multiple-Alternative-Views, and to specify utf-8 as character set in the views:
Content-Type: text/plain charset=utf-8
and
Content-Type: text/html; charset=utf-8
Beware also of the syntax. In the examples, Viewbag should be spelled ViewBag with a capital B.
If the charset is not specified, the charset that will appear in the email messages will be utf-16, and the messages won't be readable. All I see are chinese characters in that case.
UPDATE: However, I just discovered that this workaround won't fix subject lines. If a subject line contains accentuated characters, it won't get encoded properly, and it will be garbled.
I'd like to migrate to Postal. My old approach has the SMTP server in config which is fine for me. However it's not clear where to put this in code.
Before I had (in essence): new SmtpClient(Config.SmtpServer).Send(new MailMessage{...});
It's not clear where I use this config setting in the documentation. The config you show doesn't mention an SMTP server at all.
Here's the error message:
System.InvalidOperationException: The SMTP host was not specified.
at System.Net.Mail.SmtpClient.CheckHostAndPort()
at System.Net.Mail.SmtpClient.get_ServicePoint()
at System.Net.Mail.SmtpClient.Dispose(Boolean disposing)
at System.Net.Mail.SmtpClient.Dispose()
at Postal.EmailService.Send(Email email)
at Postal.Email.Send()
This'd be handy to have published in your docs.
Thanks for a great approach to sending emails with the MVC framework.
When adding Postal to a console application, required assemblies such as System.Web are not added automatically.
Adding the postal NuGet package to a MVC 4 project causes Windows Azure to complain, "Could not load file or assembly 'System.Web.Razor''. The project stems from the NuGet package overwriting the project's reference to System.Web.Razor with an old version. See this SO Q&A for details.
If specifying both Text and Html views such as described at https://github.com/andrewdavey/postal/wiki/Multiple-Alternative-Views, errors occur under Mono that do not on Windows with Microsoft's .NET runtime.
Here is an example stacktrace showing the issue. I've yet to find time to dig into this, but if anyone else has suggestions they would be greatly appreciated.
System.FormatException: Invalid format. at System.Net.Mime.ContentType.set_MediaType (string) <0x00103> at System.Net.Mail.AttachmentBase..ctor (System.IO.Stream,string) <0x00078> at System.Net.Mail.AlternateView..ctor (System.IO.Stream,string) <0x0005e> at Postal.EmailParser.CreateAlternativeView (Postal.Email,string) <0x00290> at Postal.EmailParser/<>c__DisplayClass21.b__20 (string) <0x00029> at System.Linq.Enumerable/c__Iterator272<string, System.Net.Mail.AlternateView>.MoveNext () <0x0011f> at Postal.EmailParser.ProcessHeader (string,string,System.Net.Mail.MailMessage,Postal.Email) <0x000c0> at Postal.EmailParser/<>c__DisplayClass2.<InitializeMailMessage>b__0 (string,string) <0x00037> at Postal.ParserUtils.ParseHeaders (System.IO.TextReader,System.Action
2<string, string>) <0x0017a> at Postal.EmailParser.InitializeMailMessage (System.Net.Mail.MailMessage,string,Postal.Email) <0x000e5> at Postal.EmailParser.Parse (string,Postal.Email) <0x00060> at Postal.EmailService.CreateMailMessage (Postal.Email) <0x00043> at Postal.EmailService.Send (Postal.Email) <0x00034> at (wrapper dynamic-method) object.CallSite.Target (System.Runtime.CompilerServices.Closure,System.Runtime.CompilerServices.CallSite,Postal.IEmailService,object) <0x000c6> at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid2<Postal.IEmailService, object> (System.Runtime.CompilerServices.CallSite,Postal.IEmailService,object) <0x004bc> at www.Controllers.ContactController.Index (www.Models.Contact) <0x002db>
Once again, exact same Views function properly on windows... :(
Here's the stack trace
System.NotImplementedException was unhandled by user code
Message=The method or operation is not implemented.
Source=System.Web
StackTrace:
at System.Web.HttpResponseBase.get_Cookies()
at System.Web.WebPages.CookieBrowserOverrideStore.GetOverriddenUserAgent(HttpContextBase httpContext)
at System.Web.WebPages.BrowserHelpers.GetOverriddenUserAgent(HttpContextBase httpContext)
at System.Web.WebPages.BrowserHelpers.GetOverriddenBrowser(HttpContextBase httpContext, Func2 createBrowser) at System.Web.WebPages.BrowserHelpers.GetOverriddenBrowser(HttpContextBase httpContext) at System.Web.WebPages.DisplayModes.<.cctor>b__b(HttpContextBase context) at System.Web.WebPages.DefaultDisplayMode.CanHandleContext(HttpContextBase httpContext) at System.Web.WebPages.DisplayModes.<>c__DisplayClass2.<GetAvailableDisplayModesForContext>b__1(IDisplayMode mode) at System.Linq.Enumerable.WhereListIterator
1.MoveNext()
at System.Web.Mvc.VirtualPathProviderViewEngine.GetPath(ControllerContext controllerContext, String[] locations, String[] areaLocations, String locationsPropertyName, String name, String controllerName, String cacheKeyPrefix, Boolean useCache, String[]& searchedLocations)
at System.Web.Mvc.VirtualPathProviderViewEngine.FindView(ControllerContext controllerContext, String viewName, String masterName, Boolean useCache)
at System.Web.Mvc.ViewEngineCollection.<>c__DisplayClassc.b__a(IViewEngine e)
at System.Web.Mvc.ViewEngineCollection.Find(Func2 lookup, Boolean trackSearchedPaths) at System.Web.Mvc.ViewEngineCollection.FindView(ControllerContext controllerContext, String viewName, String masterName) at Postal.EmailViewRenderer.CreateView(String viewName, ControllerContext controllerContext) at Postal.EmailViewRenderer.Render(Email email, String viewName) at Postal.EmailService.CreateMailMessage(Email email) at Postal.EmailService.Send(Email email) at Postal.Email.Send() at XY.Controllers.MailController.Index() in c:\dev\xy\Controllers\MailController.cs:line 55 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary
2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClass15.<InvokeActionMethodWithFilters>b__12() at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func
1 continuation)
InnerException:
postal has a hard reference on mvc3 (assembly references) which makes impossible to add filesystemrazorengie or resourcerazorviewEngine in a aspnet mvc 4 app.
My specific use case is i'm running a light background job in a mvc4 app (using web-backgrounder) that sends emails with a resourcerazorviewEngine, but failing given that the ViewEngineCollection checks that ResourceRazorViewEngine inherits from IViewEngine from asp.net.mvc 4.0.0.0 which is not.
I propose to make a postal.core (no references to mvc) and postal.mvc3 + postal.mvc4
MVC4 on .NET 4.0 framework. - vs2012
getting the "System.NotImplementedException: The method or operation is not implemented." message that has been reported before.
During debugging it's in the RenderView method as described in issue 40 (#40)
I've verified that I am using v0.8.0
I attempted to use the latest source from github and I'm receiving the same error.
Switching the sample site over to dotnet 4 seems to work OK however so it must be something isolated to the project in question, I'm assuming the incorrect assemble is being referenced somewhere.
The only thing that I did notice was that the demo is targeting MVC3 where my site is MVC4
EDIT: Created fresh MVC4 application, set framework to DOTNET 4, added Postal from nuget.
Copied controllers/views from demo site and get the same error.
Def seems to be an issue w/ MVC4
I'm working on a site and I need to send attachments to iphone/ipad users because safari doesn't support the file type for download. The issue I have, is that the attachments show up inline at the end of the message. I don't know if it's something I'm doing wrong, or a bug of some kind. On my desktop I use Outlook with Exchange, I've tested in windows phone 7, andriod, windows live, and Gmail. All receive the attachement correctly. Anyone else run into this, or have any suggestions?
The "To" header written like:
To: @ViewBag.ToDisplayName @ViewBag.ToEmail
will not work with an email address such as:
"Smith, Bob" [email protected]
It appears that the comma in "Smith, Bob" is parsed as if this is multiple email addresses throwing an exception:
The specified string is not in the form required for an e-mail address.
I like what you have created, looks cool. Few issues.
It is tied to the 'email' view folder. I may want to provide the 'view' from a database or something dynamic - so, the email service needs to be uncoupled from where it gets the view.
The header in the email are a neat concept, but has problems. I would rather this 'email' actually just return the formatted email object (with list of alternate views, etc) and then using that I can send the email myself. What if I want the email to go out to 100 people - same email - no need to run this code 100 times - just add the people as a 'to' in the regular email object. What about email priority, bcc, cc, etc? While you can have something that just sends the email (nice feature), I think this should have the ability to be 'uncoupled' from that, so the email can be sent 'manually', but still rendered by you, etc.
Anyway, those are just my thoughts - nice work!
Postal has XML docs for many classes, but they do not show up in IntelliSense since the Postal.xml file is not included in the NuGet package.
When I'm sending emails through postal they are being displayed with a wrong encoding, I get a bunch of chinnese characters.
Is there a way to set the encoding?
Thanks
As far as I can tell, the _ViewStart.cshtml that lives next to the .cshtml files for the email messages serves no purpose and can be removed.
Hey Andrew,
let's suppose we have the following structure of an Email razor view:
To: @ViewBag.ToDisplayName @ViewBag.To
CC: @ViewBag.Cc
From: @ViewBag.FromDisplayName @ViewBag.From
Subject: @ViewBag.Subject
Now, if our controller/service code doesn't set the CC in the ViewBag, the sending will fail because the EmailParser will try to add an empty string to the MailMessage.CC collection (inside the AssignEmailHeaderToMailMessage() method). I mean, not that the sending will fail but the request will end up in an exception:
The parameter 'addresses' cannot be an empty string.
Parameter name: addresses
On quite a few occasions I want to be able to set BCC or CC recepients but sometimes those fields might even be empty in my application. In that case, we should not be adding them to the collection.
What do you suggest to correct that or should I just fork it and correct the AssignEmailHeaderToMailMessage() method myself?
I'm using Postal in a class library project (being called from a MVC app, but shared by several MVC apps) and the email content files are in a separate /Templates folder. It seems to work fine if I have just a HTML OR Text only view (UserInviteNew.cshtml), but when I attempt to do the multi-part MIME, it goes haywire.
File structure:
Sample code:
public static bool SendNewUserInvite(HttpContextBase context, NewUserInvite modelData)
{
try
{
var viewsPath = GetEmailTemplatesPath(context);
var engines = new ViewEngineCollection();
engines.Add(new FileSystemRazorViewEngine(viewsPath));
var service = new EmailService(engines);
dynamic email = new Email("UserInviteNew");
email.Values = modelData;
service.Send(email);
return true;
}
catch (Exception ex)
{
Logger.Fatal(ex.Message, ex);
return false;
}
}
private static string GetEmailTemplatesPath(HttpContextBase context)
{
var root = context.Server.MapPath("~/");
if (root.EndsWith(@"\")) root = root.Substring(0, root.Length - 1);
var upOne = root.Substring(0, root.LastIndexOf('\\'));
return upOne + @"\Templates";
}
Views:
UserInviteNew.cshtml:
To: @Model.Values.Email
From: [email protected]
Subject: You've been invited to Pathway!
Views: Text, Html
UserInviteNew.Html.cshtml
Content-Type: text/html; charset=utf-8
<h2>Hey there, @Model.Values.FirstName!</h2>
<p>You've been invited to use Pathway -- the leading church communication tool!!!</p>
<p>To accept your invitation and set up your profile, please visit the following link: <a href="http://test.com/pathway/web/accounts/[email protected]">Accept Invitation</a>.</p>
<p>See you soon!</p>
UserInviteNew.Text.cshtml
Content-Type: text/plain; charset=utf-8
Hey there, @Model.Values.FirstName!
You've been invited to use Pathway -- the leading church communication tool!
To accept your invitation and set up your profile, please visit the following link: http://jslaybaugh.homeip.net/pathway/web/accounts/[email protected]
See you soon!
And here is the output of the mail message:
X-Sender: [email protected]
X-Receiver: [email protected]
MIME-Version: 1.0
From: [email protected]
To: [email protected]
Date: 23 Aug 2011 17:05:20 -0500
Subject: You've been invited to Pathway!
Content-Type: multipart/alternative;
boundary=--boundary_0_570ffc34-3d93-4836-8f44-065fc11742d4
----boundary_0_570ffc34-3d93-4836-8f44-065fc11742d4
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64
SGV5IHRoZXJlLCBKb3JpbiENCg0KWW91J3ZlIGJlZW4gaW52aXRlZCB0byB1c2Ug
UGF0aHdheSAtLSB0aGUgbGVhZGluZyBjaHVyY2ggY29tbXVuaWNhdGlvbiB0b29s
IQ0KDQpUbyBhY2NlcHQgeW91ciBpbnZpdGF0aW9uIGFuZCBzZXQgdXAgeW91ciBw
cm9maWxlLCBwbGVhc2UgdmlzaXQgdGhlIGZvbGxvd2luZyBsaW5rOiBodHRwOi8v
anNsYXliYXVnaC5ob21laXAubmV0L3BhdGh3YXkvd2ViL2FjY291bnRzL0FjY2Vw
dEludml0ZT9jb2RlPWpvcmlubWljaGFlbHNsYXliYXVnaDMNCg0KU2VlIHlvdSBz
b29uIQ0K
----boundary_0_570ffc34-3d93-4836-8f44-065fc11742d4
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64
PGgyPkhleSB0aGVyZSwgSm9yaW4hPC9oMj4NCg0KPHA+WW91J3ZlIGJlZW4gaW52
aXRlZCB0byB1c2UgUGF0aHdheSAtLSB0aGUgbGVhZGluZyBjaHVyY2ggY29tbXVu
aWNhdGlvbiB0b29sISEhPC9wPg0KDQo8cD5UbyBhY2NlcHQgeW91ciBpbnZpdGF0
aW9uIGFuZCBzZXQgdXAgeW91ciBwcm9maWxlLCBwbGVhc2UgdmlzaXQgdGhlIGZv
bGxvd2luZyBsaW5rOiA8YSBocmVmPSJodHRwOi8vanNsYXliYXVnaC5ob21laXAu
bmV0L3BhdGh3YXkvd2ViL2FjY291bnRzL0FjY2VwdEludml0ZT9jb2RlPWpvcmlu
bWljaGFlbHNsYXliYXVnaDMiPkFjY2VwdCBJbnZpdGF0aW9uPC9hPi48L3A+DQoN
CjxwPlNlZSB5b3Ugc29vbiE8L3A+DQo=
----boundary_0_570ffc34-3d93-4836-8f44-065fc11742d4--
(in windows mail viewer, this renders as a bunch of chinese characters).
Not sure what I could be doing wrong here. I've even specified the encoding charset. Somehow, its gets base64 encoded and the Content-Transfer-Encoding
header gets set to base64
!
My only guess is that it has something to do with the FileSystemRazorViewEngine
but I'm trying to implement this in a production project that is getting close to wrapping up and going live, so hopefully there is a solution.
Thanks,
Jorin
Hi Andrew, thanks for the help.
I'm trying to send out an email from my gmail acccount:
dynamic email = new Email("Appointment");
email.EnableSsl = true;
email.To = "[email protected]";
email.Send();
And I get this error:
System.Net.Mail.SmtpException: {"The SMTP server requires a secure connection or the
client was not authenticated.The server response was: 5.7.0 Must issue a STARTTLS command first.
Any ideas what I need to do to send this email out?
Here's my web.config setting:
<system.net>
<mailSettings>
<smtp deliveryMethod="Network" from="[email protected]">
<network host="smtp.gmail.com" port="587" defaultCredentials="false" userName="[email protected]" password="newyear2012" />
</smtp>
</mailSettings>
</system.net>
Using a header more than once works as expected.
I loved Postal. It worked fine. But just after defining a custom layout for a section, Postal kept giving The view at '~/Views/Emails/RegEmail.cshtml' must derive from WebViewPage, or WebViewPage error. I tried lots of things,with no success.
no matter if I set the content-type: text/html the email message always reverts to text/plain. Is there a way to force text/html?
I used your article about creating a plain text and html view in the email and it all seemed to work fine.
However, when I started emailing an address that I was accessing via MS Outlook 2010, it all went a bit squiffy.
A decision appears to have been made to set the default CharacterSet to UTF-16 if one is not included in the MIME type, this works fine in gmail, but not in Outlook (Pretty impressive looking in Chinese glyphs, but alas not very useful to me!).
Is this the right decision? I doubt I've ever saved a cshtml file as UTF-16, so for me this will never be correct.
Anyway, to fix this (as a consumer of Postal) you need to change your Content-Type header to be:
text/html;charset=utf-8 and text/plain;charset=utf-8
Other than that, I think that Postal is a pretty awesome addition to RazorEngine and Razor, thanks!
seems the problem is here:
string RenderView(IView view, ViewDataDictionary viewData, ControllerContext controllerContext)
{
using (var writer = new StringWriter())
{
var viewContext = new ViewContext(controllerContext, view, viewData, new TempDataDictionary(), writer);
view.Render(viewContext, writer);
return writer.GetStringBuilder().ToString();
}
}
view.Render throws a The method or operation is not implemented.
Any idea?
Important to set the Layout to null, otherwise the main web page layout will be used.
Investigate why Spark isn't working (emailViewOutput is empty string, hangs in ParseHeaders).
Hi, I am using Postal in my mailing application and I encountered a problem with the encoding of special characters.
is it possible to use special characters into a Postal application and how ?
thanks
Not so much an issue as a question... I'm using Postal with a site hosted on ec2, but have just discovered that the app breaks when I put the config section in the web.config on ec2. I don't know why, but I'm trying to get something working fast.
Is it possible to send mail message from Postal using a 3rd party api like amazon SES?
Thanks
This service reject email sent with postal using SMTP.
I have an "not implemented exception" with Razor3 and MVC5 if view use RouteUrl like :
@Url.RouteUrl(...);
Resolution :
Override GetService in MockHttpContext
public override object GetService(Type serviceType)
{
var result = System.Web.Mvc.DependencyResolver.Current.GetService(serviceType);
return result;
}
It resolve the System.Web.HttpWorkerRequest service required
Good work on this project - it seems to do everything I am looking for - multi-part emails, sending from class libraries, rendering the views as strings. There is only one exception - I have Model classes implemented in the CSLA framework, which means they must inherit from one of the CSLA base classes. And C# doesn't allow multiple inheritance, so I am stuck having to copy all of my data to another object just to send the email so I can inherit from Email.
At least I think - I don't see a way to attach an external model like you can in MvcMailer or FluentEmail, but both of those packages have other limitations as well.
I like postal the best of the 3 because you seem to have separated concerns better and allowed for DI support, but I need to be able to use my existing model classes rather than reinvent the wheel.
FluentEmail uses a [template driven system] that I really like (that has both a razor and markdown parser), but no multi-part support is a deal breaker.
In case I missed it, is using a custom model supported without requiring any inheritance? If not, what is your opinion of adding some support similar to FluentEmail to supply a model?
I'm using Postal in a class library project (being called from a MVC app, but shared by several MVC apps) and the email content files are in a separate /Templates folder and when I change the .cshtml view files and then save, I have to change a line of code and re-compile and then change it back before the changes are picked up. I assume there is some filewatcher or something there that caches the templates, but it doesnt appear to be working properly if its not within the MVC App (although since I'm not using it inside the MVC app, i can't say that definitively).
NOTE, in the current scenario, i'm using Multi-part (text/html) views, but it appears to not be specific to that model. I went back to just a pure single HTML view and the changes are still not picked up on save.
File structure:
Sample code:
public static bool SendNewUserInvite(HttpContextBase context, NewUserInvite modelData)
{
try
{
var viewsPath = GetEmailTemplatesPath(context);
var engines = new ViewEngineCollection();
engines.Add(new FileSystemRazorViewEngine(viewsPath));
var service = new EmailService(engines);
dynamic email = new Email("UserInviteNew");
email.Values = modelData;
service.Send(email);
return true;
}
catch (Exception ex)
{
Logger.Fatal(ex.Message, ex);
return false;
}
}
private static string GetEmailTemplatesPath(HttpContextBase context)
{
var root = context.Server.MapPath("~/");
if (root.EndsWith(@"\")) root = root.Substring(0, root.Length - 1);
var upOne = root.Substring(0, root.LastIndexOf('\\'));
return upOne + @"\Templates";
}
Hi,
after upgrading from MVC3 to MVC4 (I think thats the time where
the issue came up...) I got an error when I want to send the mail.
Here my test code:
dynamic email = new Email("PrivateMessage");
email.To = "[email protected]";
email.Message = "asdf";
email.mailFrom = i.mailFrom;
email.BenutzerID = i.BenutzerID;
email.mailFromAddress = "[email protected]";
email.Subject = "Subject"
email.mailTo = i.mailTo;
email.Date = DateTime.Now.ToString("g");
emailServ.Send(email);
It looks like the error is here
EmailViewRenderer.cs - viewEngines.FindView(controllerContext <-- is null)
IView CreateView(string viewName, ControllerContext controllerContext)
{
var result = viewEngines.FindView(controllerContext, viewName, null);
if (result.View != null)
return result.View;
throw new Exception(
"Email view not found for " + viewName +
". Locations searched:" + Environment.NewLine +
string.Join(Environment.NewLine, result.SearchedLocations)
);
}
~/Views/Emails/Test.cshtml with Views: Text, Html resolves to ~/Views/Emails/Test.cshtml.Html and ~/Views/Emails/Test.cshtml.Text
My work around is overriding the FindView of RazorViewEngine and creating a EmailService() with this viewengine
private class MyRazorViewEngine : RazorViewEngine
{
public override ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
{
if (viewName.Contains(".cshtml.") && !viewName.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase))
viewName = viewName.Replace(".cshtml.", ".") + ".cshtml";
return base.FindView(controllerContext, viewName, masterName, useCache);
}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.