How does one store a statement in C# such as the following way
string EmailBody = "Request no.- ('" + objUserModel.ID + "') has been raised for special
vehicle by requester-( '" + RequesterInfo + "'). " +
"ORG_Unit:'"+ objUserModel.OrgUnit + "'" +
"TDC:'"+ objUserModel.TDC + "'" +
"Customer Name:'"+ objUserModel.CustName + "'" +
"Supply Plant:'"+ objUserModel.CustName + "'";
I am trying to show this variable in multilines in the email for that I need to store it in multiline in the string.
I have seen variations of #$"" but it is not working for me.
Take a look at interpolated strings for including your field values.
For the new lines, there are three distinct items to be aware of: the Enivronment.NewLine constant, the \n character literal, and the HTML <br> element. The last is especially important for emails which use an HTML body.
In this case, I suggest a C# mult-line string literal, with an interpolated value for an extra end line you can set or not as needed based on the platform.
So you end up with this:
string br = ""; // set this to "<br>" for HTML emails
string EmailBody =
$#"Request no.- ('{objUserModel.ID}') has been raised for special{br}
vehicle by requester-( '{RequesterInfo}').{br}
{br}
ORG_Unit:'{objUserModel.OrgUnit}'{br}
TDC:'{objUserModel.TDC}'{br}
Customer Name:'{objUserModel.CustName}'{br}
Supply Plant:'{objUserModel.CustName}'";
The original code was having trouble because of the concatenation. Each line of code for the string was broken up at the end like this: " +, to continue again with a new string literal on the next line. In this way, the line breaks in the code were lost in the resulting string.
The code here addresses this issue by putting everything into the same string literal. There is only one set of double quotes defining the entire string, which now includes the line breaks built into the code. The one thing to be aware of with this technique is you want to shift your strings all the way to the left, regardless of any other indentation in the code.
I suggest joining lines with required delimiter, e.g.
// Set "<br/>" if you want HTML delimiter
// Put "\n" to have a new line,
// Use Environment.NewLine to have OS specific delimiter
string delimiter = "<br/>";
string EmailBody = string.Join(delimiter,
$"Request no.- ('{objUserModel.ID}') has been raised for special vehicle by requester-( '{RequesterInfo}'). ",
$"ORG_Unit:'{objUserModel.OrgUnit}'",
$"TDC:'{objUserModel.TDC}'",
$"Customer Name:'{objUserModel.CustName}'",
$"Supply Plant:'{objUserModel.CustName}'"
);
You can create a multiline string using a verbatim string, ie one starting with #. $ is used for string interpolation on both normal and verbatim strings. BUT that doesn't mean they'll appear as you expect in an email body.
Answering your specific question, this will create a multiline string:
string EmailBody = $#"Request no.- ('{objUserModel.ID}') has been raised for special
vehicle by requester-'({RequesterInfo}').
ORG_Unit:'{objUserModel.OrgUnit}'
TDC:'{objUserModel.TDC}'
Customer Name:'{objUserModel.CustName }'
Supply Plant:'{objUserModel.CustName}'";
Printing this produces:
Request no.- ('3') has been raised for special
vehicle by requester-'(123456').
ORG_Unit:'Blah'
TDC:'XYZ'
Customer Name:'Gone'
Supply Plant:'Gone'
All tabs and spaces were included in the string. To avoid this, each line should start without indenting:
string EmailBody = #$"Request no.- ('{objUserModel.ID}') has been raised for special
vehicle by requester-'({RequesterInfo}').
ORG_Unit:'{objUserModel.OrgUnit}'
TDC:'{objUserModel.TDC}'
Customer Name:'{objUserModel.CustName }'
Supply Plant:'{objUserModel.CustName}'";
This produces:
Request no.- ('3') has been raised for special
vehicle by requester-'(123456').
ORG_Unit:'Blah'
TDC:'XYZ'
Customer Name:'Gone'
Supply Plant:'Gone'
The order of the operators isn't significant. #$ behaves the same as $#.
Sending well formatted Emails
That's a different question, whose answer starts with Don't Use .NET's SmtpClient. The documentation page of the class warns :
We don't recommend that you use the SmtpClient class for new development because SmtpClient doesn't support many modern protocols. Use MailKit or other libraries instead. For more information, see SmtpClient shouldn't be used on GitHub.
The code needed to send a message with MailKit is similar to the old SmptClient.
using (var client = new SmtpClient ())
{
await client.ConnectAsync("smtp.gmail.com", 465, SecureSocketOptions.SslOnConnect);
await client.AuthenticateAsync("username", "password");
await client.SendAsync(message);
await client.DisconnectAsync(true);
}
The Create Messages page shows how to create plain text or HTML messages. Some older email clients don't support HTML so it's often necessary to create both a plain text and HTML message.
String interpolation and verbatim strings can be used to create the text for both parts:
string plainBody = #$"Request no.- ('{objUserModel.ID}') has been raised for special
vehicle by requester-'({RequesterInfo}').
ORG_Unit:'{objUserModel.OrgUnit}'
TDC:'{objUserModel.TDC}'
Customer Name:'{objUserModel.CustName }'
Supply Plant:'{objUserModel.CustName}'";
string htmlBody = #$"<div>Request no.- ('{objUserModel.ID}') has been raised for special
vehicle by requester-'({RequesterInfo}').
</div>
<dl>
<dt>ORG_Unit:</dt><dd>'{objUserModel.OrgUnit}'</dd>
<dt>TDC:</dt><dd>'{objUserModel.TDC}'</dd?
<dt>Customer Name:</dt><dd>'{objUserModel.CustName }'</dd?
<dt>Supply Plant:</dt><dd>'{objUserModel.CustName}'</dd>
</dl>";
These can be combined in a single email message with :
var message = new MimeMessage ();
message.From.Add (new MailboxAddress ("Blah Blah", "blah#gmail.com"));
message.Subject = "Special Request";
var builder = new BodyBuilder ();
builder.TextBody = plainBody;
builder.HtmlBody = htmlBody;
message.Body = builder.ToMessageBody ();
Try to use + Environment.NewLine where you need the newline.
+ "vehicle by requester - ('" + RequesterInfo + "'). " + "\n" + "ORG_Unit:'" + objUserModel.OrgUnit + "'" + "\n"
+ "TDC:'" + objUserModel.TDC + "'" + "\n" + "Customer Name:'" + objUserModel.CustName + "'" + "\n"
+ "Supply Plant:'" + objUserModel.CustName + "'";```
If i have understood it correctly you just add ```+ "\n" +```
using string interpolation you can achieve what you want to do here for example:
string EmailBody = $"Request no.- ('\"{objUserModel.ID}\"') has been raised
notice the \ before the "
if you would like to add a new line in the string you can just add
string1 $" this string is writen on one line";
string2 $" this string is \nwriten on two lines";
Related
I have code to display a vehicle by its Make and Model.
productName.Text = p.Make + p.Model
The above code displays the text as such: "BentleyContinental", how can I make the text display as such "Bentley Continental".
You can use string.Format():
productName.Text = string.Format("{0} {1}", p.Make, p.Model);
Or you can use string interpolation (if you are on C# 6 or higher):
productName.Text = $"{p.Make} {p.Model}";
Or you can do just as you have (string concatenation) but add in a space:
productName.Text = p.Make + " " + p.Model;
Use the string.concat method to concatenate string parts.
productName.Text = string.concat(p.Make, " ", p.Model);
In general, you use the string.concat when you know you'll add less than a dozen parts. More than that, or if you are in a loop, there is more benefits using the StringBuilder class.
productName.Text = p.Make + " " + p.Model
Just concatenate a space between two words. I think this is the easiest way.
I'm trying to code an email button into a program I use at the school where I work (Essentially, the program generates random passwords for a class I input, it then sets those passwords for that session, and changes them after the session finishes). The email button is so it sends the usernames and passwords to the teachers without me having to manually type it out.
I've got to the point where I can send the email via an SMTP relay, and I receive it. I've formatted the subject line which I'm happy with, I'm just stuck on the body now. Essentially, I have an ArrayList which holds each line as a value. I'm looking for a way to dump each value in the ArrayList to a new line in the body. So far I have this:
mailMsg.Body = ("Hi," + Environment.NewLine + Environment.NewLine + "Below are the usernames and passwords for the Controlled Assessment." + Environment.NewLine + Environment.NewLine + "Usernames Firstname Surname Passwords" + Environment.NewLine + "-----------------------------------------------------" + Environment.NewLine + );
My ArrayList is called SW, and I've parsed this into an Array too called aSW, using: String[] aSW = (String[]) SW.ToArray(typeof(string));
Can anyone give me pointers on how to do this? I apologise if more info is needed, only been coding in C# for about 3 weeks!
You can use LINQ
var arr = SW.OfType<string>().ToArray();
To concatenate all values with newline you can use string.Join
string.Join(Environment.NewLine, arr);
U can declare a stringbuilder and append each item in the arraylist
and after that assign body = sb.tostring()
I have a string variable called reason for failure which contains user added text for instance the following:
({0}) on arm ({1}} (82) Kits
Now this variable is part of a method where I am using string.format. I need the string.format to not confuse with {0} {1} in the text of the above variable because I am getting the the exception, Input string was not in correct format
The reason you're getting the exception, The input string is not in the correct format is due to the way you're constructing the string. In your variable you have two closing braces where string.Format expects only one: on arm ({1}}. If you add this variable as a parameter to String.Format as shown in the first example below, it should resolve this issue.
Otherwise, if you are saying that the variable serviceEntry.ReasonForFailure contains the characters {0} and {1}, and that when you place this variable inside a String.Format, those characters are being replaced by the String.Format arguments, then this is by design, at least the way you're constructing your string.
Instead of inserting your variable in the string using the + operator, include it as another parameter to the String.Format call. This way, the {0} in your variable will be preserved.
message.Body = string.Format(
"<html><body>Request is complete<br/>" +
"Service Request initiated by you is Complete<br/>" +
"Please use the following link to access " +
"{0}{1}<br/>" +
"Reason For Failure: {2}<br/></body></html>",
RunLogURL, runLogID, serviceEntry.ReasonForFailure);
Now, if you want to replace the {0} and {1} in serviceEntry.ReasonForFailure with some other values, you can nest a String.Format inside another:
serviceEntry.ReasonForFailure = "10003 Insufficient Liquid Level detected at " +
"pipettor channel ({0}) on arm ({1}) (82)";
var channelId = 87;
var armId = 42;
message.Body = string.Format(
"<html><body>Request is complete<br/>" +
"Service Request initiated by you is Complete<br/>" +
"Please use the following link to access " +
"{0}{1}<br/>" +
"Reason For Failure: {2}<br/></body></html>",
RunLogURL, runLogID,
String.Format(serviceEntry.ReasonForFailure, channelId, armId));
Or you can do it in two operations:
serviceEntry.ReasonForFailure = "10003 Insufficient Liquid Level detected at " +
"pipettor channel ({0}) on arm ({1}) (82)";
var channelId = 87;
var armId = 42;
var reasonForFailure = String.Format(serviceEntry.ReasonForFailure, channelId, armId);
message.Body = string.Format(
"<html><body>Request is complete<br/>" +
"Service Request initiated by you is Complete<br/>" +
"Please use the following link to access " +
"{0}{1}<br/>" +
"Reason For Failure: {2}<br/></body></html>",
RunLogURL, runLogID, reasonForFailure);
The problem is that your variable serviceEntry.ReasonForFailure contains a format item. If don't want them to be treated as format items you'll have to escape them with an extra set of braces. For instance: {0} becomes {{0}} as explained here.
The quick and dirty solution to your problem would be to replace all opening and closing braces by a double brace:
"Reason For Failure:" + serviceEntry.ReasonForFailure.Replace("{","{{").Replace("}","}}") + "<br/>"
A better solution would be to do the replacement using a regular expression:
public string EscapeCurlyBraces(string value)
{
string strRegex = #"(\{\d+\})";
Regex myRegex = new Regex(strRegex, RegexOptions.None);
string strReplace = #"{$1}";
return myRegex.Replace(value, strReplace);
}
And then use it like this:
"Reason For Failure:" + EscapeCurlyBraces(serviceEntry.ReasonForFailure) + "<br/>"
Update
I suggest you ditch the current solution and rewrite it using a StringBuilder:
var emailBody = new StringBuilder();
emailBody.Append("<html><body>RSLMS - Service Request is complete<br/>");
emailBody.Append("Service Request initiated by you is Complete <br/>");
emailBody.AppendFormat("Please use the following link to access Run Log Entry {0}{1}<br/>", RunLogURL, runLogID);
// ommited some lines
emailBody.AppendFormat("Service ID: {0}<br/><br/>", serviceEntry.ID.ToString());
// ommited some lines
emailBody.AppendFormat("Reason For Failure: {0}<br/><br/>", serviceEntry.ReasonForFailure);
emailBody.Append("Thank you <br/> RSLMS Administrator <br/></body></html>");
message.Body = emailBody.ToString();
Since you have two String.Format, you didnt provide parameter for the external , lets say you have x and y for the external Format, this is what you need to do. You need to do double curly braces for those you want to escape from the inner format as in :
var reasonForFailure = "({{0}}) on arm ({{1}}) (82) Kits should still have 50 tests left after run, but it seems like the instrument is not able to pipette anymore from the kits.";
var message = string.Format(string.Format(
"<html><body>Request is complete<br/>" +
"Service Request initiated by you is Complete" + " <br/> " +
"Please use the following link to access {0}{1} <br/>" +
"Reason For Failure: " + reasonForFailure+"<br/>" +
"</body></html>", RunLogURL, runLogID),x,y);
I need to put an adress into a appointment. The address is constructed out of several variables. Of course I also need some newlines. But "\n" doesnt result in an new line when i open the appointment in outlook.
Ok here is code snippet:
string address = name + "\n" + strasse + "\n" + plz.ToString() + " " + ort;
if ( telefon != "") {
address = address + "\nTelefon:: " + telefon;
}
if ( natel != "") {
address = address + "\nNatel: " + natel;
}
if ( mail != "") {
address = address + "\nE-Mail: " +mail;
}
Nothing special. The Problem is when i write this to the body of an appointment, then there aren't any actual newlines.
Its pretty hard to diagnose this without seeing at least an example of the string you are passing, but one thing that I tend to do in my C# code is to use the constant:
Environment.NewLine
Or I use the StringBuilder class with the AppendLine() call to add a newline.
Edit: Based on your code snippet, I would write it this way (it will be more performant as well). With your snippet, lots of strings are being allocated (because strings are immutable). The recommended approach in this case is to use StringBuilder.
StringBuilder address = new StringBuilder();
address.AppendLine(name);
address.AppendLine(strasse);
address.Append(plz.ToString()); // This may not be neccessary depending on the type of plz, StringBuilder has overloads that will convert base types to string for you
address.Append(" ");
address.Append(ort);
if (!string.IsNullOrEmpty(telefon))
{
address.AppendLine();
address.Append("Telefon:: ");
address.Append(telefon);
}
if (!string.IsNullOfEmpty(natel))
{
address.AppendLine();
address.Append("Natel: ");
address.Append(natel);
}
if (!string.IsNullOrEmpty(mail))
{
address.AppendLine();
address.Append("E-Mail: ");
address.Append(mail);
}
return address.ToString();
Note: If you are using .Net 4.0 you can use string.IsNullOrWhitespace instead of IsNullOrEmpty to check for not just an empty string, but one that contains only whitespace.
Edit 2 - Based on your answer of needing <br /> tags instead of newlines.
const string newLine = " <br /> ";
StringBuilder address = new StringBuilder();
address.Append(name);
address.Append(newLine);
address.Append(strasse);
address.Append(newLine);
address.Append(plz.ToString()); // This may not be neccessary depending on the type of plz, StringBuilder has overloads that will convert base types to string for you
address.Append(" ");
address.Append(ort);
if (!string.IsNullOrEmpty(telefon))
{
address.Append(newLine);
address.Append("Telefon:: ");
address.Append(telefon);
}
if (!string.IsNullOfEmpty(natel))
{
address.Append(newLine);
address.Append("Natel: ");
address.Append(natel);
}
if (!string.IsNullOrEmpty(mail))
{
address.Append(newLine);
address.Append("E-Mail: ");
address.Append(mail);
}
return address.ToString();
Ok i got it now. I found out that appointments are stored in html format.
So i tried to use the html entity for \r\n, .That didn't work. I finally solved the problem by using the br tag
While you're absolutely correct about using <br/>, newline is not the only thing Exchange eats in notes/appointment body.
I ended up with the following code:
Regex NewlineRegex = new Regex("(\r\n)|(\r)|(\n)");
string valueToWrite = NewlineRegex.Replace(
SecurityElement.Escape(fieldValue), "<br/>")
.Replace(" ", " ")
.Replace("'", "'"); // ' is not in HTML.
And even after that you will read back an extra "\r\n" in the end of the body/notes, so I have to .TrimEnd() them after reading.
you should try "\r\n"
See http://www.infinitec.de/post/2009/08/25/Exchange-WebServices-Bug-with-Lineendings.aspx
I don't know what is wrong with the following string:
"Report(" + System.DateTime.Now.ToString("dd-MMM-yyyy") + " to " + System.DateTime.Now.AddMonths(-1).ToString("dd-MMM-yyyy") + ")"
I can't get the concatenated string. I am getting Report(29-Dec-2009. That's all and
the rest gets left out from the string.
What is the reason?
Try this:
string filename =
String.Format(
"Report({0:dd-MMM-yyyy} to {1:dd-MMM-yyyy})",
System.DateTime.Now, System.DateTime.Now.AddMonths(-1));
EDIT: Since in your download box you got your filename broken in first whitespace, you could to try ONE of these:
filename = HttpUtility.UrlEncode(filename); // OR
filename = """" + filename + """";
Seems some browsers doesn't handles whitespaces very nicely: Filenames with spaces are truncated upon download. Please check it you can to download other filenames with whitespace in other sites.
You need to assign it to something:
string s = "Report(" + System.DateTime.Now.ToString("dd-MMM-yyyy") + " to " + System.DateTime.Now.AddMonths(-1).ToString("dd-MMM-yyyy") + ")"
Update: I just saw your update to the question. How are you displaying the string? I'm guessing that you are displaying it in a GUI and the label is too short to display the complete text.
Try this:
string newstring =
string.Format(
"Report ({0} to {1})",
System.DateTime.Now.ToString("dd-MMM-yyyy"),
System.DateTime.Now.AddMonths(-1).ToString("dd-MMM-yyyy")
);
What are you assigning the result to? It would be easier to read the code if you used string.Format
You are not assigning the concatenated result to anything, so can't use it:
string myConcatenated = "Report(" + System.DateTime.Now.ToString("dd-MMM-yyyy") + ")";
Using this code...
string test = "Report(" + System.DateTime.Now.ToString("dd-MMM-yyyy") + " to " +
System.DateTime.Now.AddMonths(-1).ToString("dd-MMM-yyyy") + ")";
I saw the following result.
Report(29-Dec-2009 to 29-Nov-2009)
It could be that the string is being truncated later on. Make sure that you set a breakpoint right after this code is run and check the value of the variable to which it is assigned (test in my case).
If, as in your previous question, you are using this value to create a file, it may be that it's the space before "to" that is causing the problem. Try to use:
"Report("
+ System.DateTime.Now.ToString("dd-MMM-yyyy")
+ "To"
+ System.DateTime.Now.AddMonths(-1).ToString("dd-MMM-yyyy")
+ ")"
instead and see if that fixes it.
If that does fix it, you'll probably need to either figure out how to quote the entire file name so it's not treated as the three separate arguments, "Report(29-Dec-2009", "to" and "29-Nov-2009)". Or simply leave your reports names without spaces.
I'd choose the latter but then I'm fundamentally opposed to spaces in filenames - they make simple scripts so much harder to write :-)