So recently I've been working on code in C#/ASP.NET that throws an error during selections of large parameters:
Exception of type 'System.OutOfMemoryException' was thrown. at
System.Text.StringBuilder.ToString()
General Overview:
Code queries a bunch of data from a database based on a selection by the user and puts in into an Excel document to be then be exported/downloaded by the user. It first uses StringBuilder to append the Prefix of the XML with:
const string startExcelXML = "<xml version>\r\n<Workbook " +
"xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n " +
"xmlns:x=\"urn:schemas- microsoft-com:office:" +
"excel\"\r\n xmlns:ss=\"urn:schemas-microsoft-com:" +
"office:spreadsheet\">\r\n <Styles>\r\n " +
"<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " +
"<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" +
"\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" +
"\r\n <Protection/>\r\n </Style>\r\n " +
"<Style ss:ID=\"BoldColumn\">\r\n <Font " +
"x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " +
"<Style ss:ID=\"StringLiteral\">\r\n <NumberFormat" +
" ss:Format=\"#\"/>\r\n </Style>\r\n <Style " +
"ss:ID=\"Decimal\">\r\n <NumberFormat " +
"ss:Format=\"0.0000\"/>\r\n </Style>\r\n " +
"<Style ss:ID=\"Integer\">\r\n <NumberFormat " +
"ss:Format=\"0\"/>\r\n </Style>\r\n <Style " +
"ss:ID=\"DateLiteral\">\r\n <NumberFormat " +
"ss:Format=\"mm/dd/yyyy;#\"/>\r\n </Style>\r\n " +
"</Styles>\r\n ";
It then goes through a loop that goes through and appends </Data></Cell> and the like as required before finally appending with:
const string endExcelXML = "</Workbook>";
After that it then return contentSB.ToString(); Since this is the only ToString() in the method the exception references, it has to be this piece of code.
Similar StackOverflow Issue:
interesting OutOfMemoryException with StringBuilder
Thoughts:
I've tried using the following code to get a general idea of how big the string is, which works for smaller selections, but doesn't output anything for larger selections and where contentSB is the StringBuilder object:
System.Diagnostics.Debug.WriteLine("String:", contentSB);
System.Diagnostics.Debug.WriteLine("String length:", contentSB.Length);
The referenced other StackOverflow issue occurs when appending, whereas mine is when returning a ToString(), so the cause of the issue might be different as it occurs not in the middle of Appending in the loop, but in the conversion process/return. What is the root cause and how do I fix it?
Look like the string is bigger than what the memory can take. Guess that you could you be keeping long-lived references to large objects in memory?
http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/5050e855-20d0-4fc5-97b6-79fdc7f176c6/
C# Stringbuilder OutOfMemoryException
Related
In one of my datatable column, I want the value to be shown in double quotes
AS:- "My value"
Below is my code:-
string StrPriBody = "Dear User, <br><br> The Number of days revised by you from " +
" " + table.Rows[0]["LAST_ACTION_DAYS"] + " days to " +
" " + table.Rows[0]["CURRENT_ACTION_DAYS"] + " days. <br /> " +
" with Remark <b> " + table.Rows[0]["REMARKS"] + "</b><br /><br />";
I want to show REMARK value in double quotes.
How to achieve that ?
Add extra quotes with backslash:
string StrPriBody = "Dear User, <br><br> The Number of days revised by you from " +
" " + table.Rows[0]["LAST_ACTION_DAYS"] + " days to " +
" " + table.Rows[0]["CURRENT_ACTION_DAYS"] + " days. <br /> " +
" with Remark <b> \"" + table.Rows[0]["REMARKS"] + "\"</b><br /><br />";
Use \ to print the escape sequence characters in a string
" with Remark <b> \"" + table.Rows[0]["REMARKS"] + "\" </b><br /><br />";
For better readability I would use verbatim string literal, as it allows to avoid concatenation and easily expand on multiple lines. Also, String.Format would make your string more readable:
string StrPriBody = String.Format(#"
Dear User,
<br><br>
The Number of days revised by you from {0} days to {1} days. <br />
with Remark <b> ""{2}""</b>
<br /><br />",
table.Rows[0]["LAST_ACTION_DAYS"],
table.Rows[0]["CURRENT_ACTION_DAYS"],
table.Rows[0]["REMARKS"]);
Also, C# 6.0 (Visual Studio 2015) has introduced interpolated strings, that makes string construction even more reader friendly:
string StrPriBody = $#"
Dear User,
<br><br>
The Number of days revised by you from {table.Rows[0]["LAST_ACTION_DAYS"]} days to {table.Rows[0]["CURRENT_ACTION_DAYS"]} days. <br />
with Remark <b> ""{table.Rows[0]["REMARKS"]}""</b>
<br /><br />";
I am using the following code to give blank space so that the three elements "label, then dropdown and then a button for action on dropdown" are right aligned in a panel in a web page.
Now, I know I can do with padding/margin, however, it all works only with respect to the element at right side and not from the right hand side of the browser.
However, I was talented enough to achieve what I want using but I find it weird to write the code this way:
LiteralSpecial.Text = " " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
"Select page ";
Is there are way to refine this please, folks?
Have you tried using CSS?
<div style="text-align:right">Select page</div>
See it in action: http://jsfiddle.net/vhxchyrj/2/
<div style="width:600px;padding-left:550px;">Select page</div>
I Have a messagebox to display some text and data (if existing) within database. The current Issue is trying to show nulls and trying to convert to ShortDate. I've taken two approach but none quite work in the way I need.
The first approach uses Ternary concatenation within the string but it behaves really weird.
DialogResult DuplicateMessage = MessageBox.Show("A contact name " + DuplicateName.Forename + " " + DuplicateName.Surname + " already exists within the System."
+ "\n Existing Client: " + DuplicateName.Forename + " " + DuplicateName.Surname
+ "\n Date of Birth: " + DuplicateName.DOB != null ? Convert.ToDateTime(DuplicateName.DOB).ToString("yyyy-mm-dd") : " ",
,"Possible Duplicate Client", MessageBoxButtons.YesNo);
Currently The message box only shows the line breaks and the Date Of birth. Not even the text "Date of Birth"
If I remove Tertiary and conversion and simply have
DialogResult DuplicateMessage = MessageBox.Show("A contact name " + DuplicateName.Forename + " " + DuplicateName.Surname + " already exists within the System."
+ "\n Existing Client: " + DuplicateName.Forename + " " + DuplicateName.Surname
+ "\n Date of Birth: " + DuplicateName.DOB
,"Possible Duplicate Client", MessageBoxButtons.YesNo);
This works, shows everything. Only issue is that the Date of birth is in the wrong format. Was wondering how do I make it so the date is in short date format and will show everything.
all Properties Of 'DuplicateName' are nullable,
I suspect this is a problem with operator precedence using the conditional operator. It's likely including string concatenations as part of the condition being tested, rather than as part of the result. You can explicitly enclose the elements of that operator with parentheses to identify which strings belong therein and which do not:
"\n Date of Birth: " + (DuplicateName.DOB != null ? Convert.ToDateTime(DuplicateName.DOB).ToString("yyyy-mm-dd") : " ")
Additionally, if DOB is a DateTime? then you can simplify your code a little:
"\n Date of Birth: " + (DuplicateName.DOB.HasValue ? DuplicateName.DOB.Value.ToString("yyyy-mm-dd") : " ")
There's no need to use Convert on Nullable<T> types, you can more easily (and safely) make use of the HasValue and Value properties.
You can fix it by using another pair of parentheses:
(DuplicateName.DOB != null ? Convert.ToDateTime(DuplicateName.DOB))
In your first case, you're concatenating a huge string together (because you don't use any parentheses) and then testing that for null. It's equivalent to this:
var stringToTest = "A contact name " + DuplicateName.Forename + " " + DuplicateName.Surname + " already exists within the System."
+ "\n Existing Client: " + DuplicateName.Forename + " " + DuplicateName.Surname
+ "\n Date of Birth: " + DuplicateName.DOB;
DialogResult DuplicateMessage =
MessageBox.Show(stringToTest != null ? Convert.ToDateTime(DuplicateName.DOB).ToString("yyyy-mm-dd") : " ",
,"Possible Duplicate Client", MessageBoxButtons.YesNo);
This question already has answers here:
How to display the text in MVC?
(4 answers)
Closed 8 years ago.
I want to show a output in textbox in MVC. But its not displaying anything. I used the following code and i attached screenshot below:
#Html.TextAreaFor(up => up.CompileOutput)
foreach (CompilerError CompErr in results.Errors)
{
userProgram.CompileOutput = "Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
return View(userProgram);
The first image shows that the output is binded with that particular textbox. But in browser (image 2) shows nothing in the textbox (red colour)
I am even wondering why you did not got an exception. return view(string) will look for a view with the string parameter as name, it will not show the text.
I would suggest you use ViewBag instead. So you set your error text in a property you name as follow:
foreach (CompilerError CompErr in results.Errors)
{
userProgram.CompileOutput = "Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
ViewBag.ErrorText = userProgram.CompileOutput;
You can later on retrieve the value by simply calling ViewBag.ErrorText from you Razor view
Why not try doing it another way?
#Html.TextArea("CompileOutput", userProgram.CompileOutput)
I have build a JSON string (to be posted to a web service), and I used the C# StringBuilder class to do this. The problem is, that when I insert quotes, the StringBuilder class escapes them.
I am currently building the JSON string as such:
StringBuilder dataJSON= new StringBuilder();
dataJSON.Append("{");
dataJSON.Append(" " + Convert.ToChar(34) + "data" + Convert.ToChar(34) + ": {");
dataJSON.Append(" " + Convert.ToChar(34) + "urls" + Convert.ToChar(34) + ": [");
dataJSON.Append(" {" + Convert.ToChar(34) + "url" + Convert.ToChar(34) + ": " + Convert.ToChar(34) + domain + "/" + path[0] + Convert.ToChar(34) + "}");
dataJSON.Append(" ,{" + Convert.ToChar(34) + "url" + Convert.ToChar(34) + ": " + Convert.ToChar(34) + domain + "/" + path[1] + Convert.ToChar(34) + "}");
dataJSON.Append(" ]");
dataJSON.Append(" }");
dataJSON.Append("}");
However, the command:
dataJSON.ToString(); results in the string:
{ \"data\": { \"urls\": [ {\"url\": \"domain/test1.html\"} , {\"url\": \"domain/test2.html\"} ] }}
Notice the escaped quotes? This is really screwing me up, because the server can't handle the slashes.
My desired (which posts fine to my server when I use PHP) should be:
{ "data": { "urls": [ {"url": "domain/test1.html"} , {"url": "domain/test2.html"} ] }}
Is there ANY way to get a string in C# to include quotes that will result in the desired string?
Many thanks!
Brett
The QuickWatch/Watch window will add the extra \ in. If you view it in the Text Visualizer, you will not see them:
QuickWatch:
"{ \"data\": { \"urls\": [ {\"url\": \"domain/path1\"} ,{\"url\":
\"domain/path2\"} ] }}"
Visualizer (the actual output):
{ "data": { "urls": [ {"url": "domain/path1"} ,{"url": "domain/path2"} ] }}
The \ indicates that the quotes have been escaped and will be included in the final string as you're expecting them to be. I.e. there's nothing wrong with your output.
NB. I used "\"" instead of Convert.ToChar(34) when I tested this.
You may have more luck using the Newtonsoft.JSON library, or alternately just escaping the slashes yourself as \" in your string literals instead of using Char(34).
dataJSON.Append(" \"data\": {");