7

I have code that sends an email message to users on registration:

await UserManager.SendEmailAsync(2, "Confirm your account", 
                "Please confirm your account by clicking this link: <a href=\"www.cnn.com\">link</a>");

This works but I want to do something a lot more advanced and I have seen many templates out there. However all templates out there are at least 100 lines long and have newlines after every line. Here's an example of when I tried adding just one new line.

await UserManager.SendEmailAsync(2, "Confirm your account", 
            "Please confirm your account by clicking this link: 

            <a href=\"www.cnn.com\">link</a>");

As soon as I have a new line then I get a message saying I cannot include a new line in a constant.

Can anyone suggest another way that I could include do this?

4 Answers4

15

There are three issues here. The first is that if you have a lot of text, you shouldn't be including that in the source code directly anyway. For small localizable pieces of text, you can use a resx/resources file - Visual Studio will present you with a grid so you can specify text for a particular resource name etc.

For lots of text, however, I'd strongly consider creating a .txt file which you embed into your assembly, and read with Assembly.GetManifestResourceStream. It's much easier to edit a text file than to manage large blocks of string literals.

The rest of the answer, however, addresses the question you actually asked, about string literals.

Second is getting a line break into the string, which can be done either by including it directly using escape sequences:

await UserManager.SendEmailAsync(2, "Confirm your account", 
    "Please confirm your account by clicking this link:\r\n<a href=\"www.cnn.com\">link</a>");

(Here \r\n is a carriage return and line feed. Sometimes you may want just \r or just \n. It depends on the context.)

Or a verbatim string literal:

await UserManager.SendEmailAsync(2, "Confirm your account", 
    @"Please confirm your account by clicking this link:
      <a href=""www.cnn.com"">link</a>");

Note that in a verbatim string literal, you need to escape double-quotes by doubling them, as a backslash is just a backslash.

But that will just give you a line break in your HTML. If you're trying to get a line break in the displayed text, you should use HTML. For example, you could use:

await UserManager.SendEmailAsync(2, "Confirm your account", 
    "Please confirm your account by clicking this link:<br /><a href=\"www.cnn.com\">link</a>");

... but I gather the <br> tag is mostly out of favour - you should look at other ways of controlling the layout of your HTML. Just remember that a linebreak in the HTML itself is unlikely to be relevant in your page.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I was just gonna suggest him to use embedded doc for his email content like your post [here](http://stackoverflow.com/a/3538535/1627271). – choz Feb 06 '16 at 08:17
  • 1
    @choz: I probably wouldn't do that for a single string like this... However, I've just read the rest of the question again, and see your point :) – Jon Skeet Feb 06 '16 at 08:18
  • Fair enough, I thought I read it that he was going to insert 100 lines long. – choz Feb 06 '16 at 08:19
  • @choz: You did, and I didn't - I'm editing my answer :) – Jon Skeet Feb 06 '16 at 08:20
  • @JonSkeet - Thanks for your answer. I am particularly interested in the idea of incorporating the text in a text file. This would be a very good solution as the application has multi-language support. I accepted this answer and I will post another question so that hopefully someone can give me a bit more advice on adding a .txt file to the assembly. –  Feb 06 '16 at 12:22
7

Use \n. This is escape sequence for new lines.

Also you can use Environment.NewLine

Konstantin Zadiran
  • 1,485
  • 2
  • 22
  • 35
2
  1. Bad solution, but better than now:

    var msg="Please confirm your account by clicking this link:\n"
    + "\n"
    + @"link"+"\n";

  1. Correct way: store your strings in resource files, text-files or any other files.
unconnected
  • 991
  • 1
  • 10
  • 21
  • I really don't think there's any need for the first line here... and I wouldn't say that your solution 1 (which includes two linebreaks between the first two lines, not one, and would be simpler as a verbatim string literal) is so much better... – Jon Skeet Feb 06 '16 at 08:21
  • I'm sorry if it sounds rude. But verbatim strings in code pain me much :) – unconnected Feb 06 '16 at 08:29
  • 1
    Why? What do you have against them? In many cases they're the simplest way of working. Do you object to them for regular expressions too, preferring to end up with quadruple backslashes in some cases, or regular expressions stored in resources, making it harder to read the code? – Jon Skeet Feb 06 '16 at 08:34
  • Thanx for pointing to regular expressions. I'm using 'em rearly and quite simple ones. I agree that in case of some complicated parsing code it might be helpfull. But in case of messages, alerts or some other string templates it's real pain to modify them. – unconnected Feb 06 '16 at 08:44
  • I don't see why it's *that* painful to modify short strings, to be honest. If we're talking many lines, then sure - put them in a text file or whatever. But using a verbatim string literal for (say) 3 lines is not "terrible" code that needs the sort of protest you've got at the start of your answer. Your answer would be better without that first line. (I would reserve that sort of thing for SQL injection attacks and the like.) – Jon Skeet Feb 06 '16 at 08:45
  • Ok, you've conviced me. But the TS talks about 100 lines limit :) – unconnected Feb 06 '16 at 08:55
  • Yes, so say that *that* is worth avoiding - not the code posted already. See if my answer says what you'd want to say... – Jon Skeet Feb 06 '16 at 09:01
1

You could use \n inline in the string to indicate a new line:

await UserManager.SendEmailAsync(2, "Confirm your account", 
            "Please confirm your account by clicking this link:\n\n<a href=\"www.cnn.com\">link</a>");

Alternatively, and probably better if you have a large piece of text to send, you can use StringBuilder to build up lines of text, then write that to your method.

var builder = new StringBuilder();
builder.AppendLine("Please confirm your account by clicking this link:");
builder.AppendLine("<a href=\"www.cnn.com\">link</a>")

await UserManager.SendEmailAsync(2, "Confirm your account", builder.ToString());
Steve
  • 9,335
  • 10
  • 49
  • 81