Hello I have a model method that looks like this.
public string menuItems(bool drop)
{
var baseUrl = IGT.baseUrl;// string.Format("{0}://{1}{2}", HttpContext.Current.Request.Url.Scheme, HttpContext.Current.Request.Url.Authority, HttpRuntime.AppDomainAppVirtualPath);
string addmore = "<a class='dropdown-item' href=" + baseUrl + "DODetails/Create?orderID=" + ID.ToString() + ">Add More</a>";
string changestatus = "<a class='dropdown-item' href=" + baseUrl + "DisposalOrders/ChangeStatus/" + ID.ToString() + ">Change Status</a>";
string details = "<a class='dropdown-item' href=" + baseUrl + "DisposalOrders/Details?id=" + ID.ToString() + ">Details</a>";
string delete = "<a class='dropdown-item' href=" + baseUrl + "DisposalOrders/Delete?id=" + ID.ToString() + ">Delete</a>";
string edit = "<a class='dropdown-item' href=" + baseUrl + "DisposalOrders/Edit?id=" + ID.ToString() + ">Edit</a>";
string notes = "<a class='dropdown-item' href=" + baseUrl + "DisposalOrders/Notes/" + ID.ToString() + ">Notes</a>";
//string delim = " | ";
switch (Status)
{
case DOStatus.Pending:
return addmore + " | " + edit + " | " + details + " | " + changestatus + " | " + delete + " | " + notes;
//return String.Concat(addmore, delim, changestatus, delim, delete, delim, details, delim, edit, delim, notes);
case DOStatus.Disposed:
return details + notes;
};
return details;
}
And a view page that returns those values by doing this
<p>
#Html.Raw(Model.menuItems(false)) | #Html.ActionLink("Back to List", "Index")
</p>
I have done this with other pages in my site and it looks like this
But what mine currently does is
I don't know if it's a system bug or something wrong with my code or what. Just confused at what the issue is right now
Here is my Markup
Related
First, I apologize for the length of this, but it's all I knew when I started. Now I'm experimenting with the foreach, List<t> and TreeView classes to avoid repetition as recmomended by SO community.
The form will collect information via text boxes, allow attachments of files with file dialogs and collate all info into a neat HTML bodied email. We sell slabs.. and my original code looked a little like this:
private void PrepareReturnEmailTwoSlabs()
{
LoadSettings();
string Fname = Properties.Settings.Default.FabricatorName;
string Facc = Properties.Settings.Default.FabricatorAccountNo;
string Fadd1 = Properties.Settings.Default.FabricatorAddress1;
string Fadd2 = Properties.Settings.Default.FabricatorAddress2;
string Ftown = Properties.Settings.Default.FabricatorTown;
string Fcounty = Properties.Settings.Default.FabricatorCounty;
string Fpostcode = Properties.Settings.Default.FabricatorPostcode;
string Fphoneno = Properties.Settings.Default.FabricatorPhone;
string Femail = Properties.Settings.Default.FabricatorEmail;
string Fclient = Properties.Settings.Default.ClientManagerEmail;
string Fcentre = Properties.Settings.Default.CentreEmail;
string FQt = Properties.Settings.Default.QTEmail;
string Dateofinv = dateTimePicker1.Value.ToShortDateString();
string Inv = textBox13.Text;
string Material1 = textBox14.Text;
string Thick1 = comboBox8.SelectedValue.ToString();
string Batch1 = textBox44.Text;
string Reason1 = comboBox1.SelectedValue.ToString();
string Notes = textBox18.Text;
string Thick2 = comboBox7.SelectedValue.ToString();
string Material2 = textBox15.Text;
string Batch2 = textBox45.Text;
string Reason2 = comboBox2.SelectedValue.ToString();
if (Thick2 == null)
{
Thick2 = "not selected";
}
if (Material2 == null)
{
Material2 = "not selected ";
}
if (Batch2 == null)
{
Batch2 = "not selected ";
}
if (Reason2 == null)
{
Reason2 = "not selected ";
}
GenerateUniqueRefReturn();
//construct email
var message = new MimeMessage();
message.From.Add(new MailboxAddress("************", "***************"));
message.To.Add(new MailboxAddress("**********", "********"));
message.Subject = "Return" + " " + Returnid;
//different message bodies dependant on how many slabs are chosen
TextPart body2 = new TextPart("html")
{
Text = #"Please See Below Information" + "<br/>" +
"<h4>Return ID: " + " " + Returnid + "</h4>" + "<br/>" +
"<b>Fabricator Name:</b>" + " " + Fname + "<br/>" + Environment.NewLine +
"<b>Account Number:</b>" + " " + Facc + "<br/>" + Environment.NewLine +
"<b>Address Line 1:</b>" + " " + Fadd1 + "<br/>" + Environment.NewLine +
"<b>Address Line 2:</b>" + " " + Fadd2 + "<br/>" + Environment.NewLine +
"<b>Town:</b>" + " " + Ftown + "<br/> " + Environment.NewLine +
"<b>County:</b>" + " " + Fcounty + "<br/>" + Environment.NewLine +
"<b>Postcode:</b>" + " " + Fpostcode + "<br/>" + Environment.NewLine +
"<b>Phone:</b>" + " " + Fphoneno + "<br/>" + Environment.NewLine +
"<b>Email:</b>" + " " + Femail + "<br/>" + Environment.NewLine + "<br/>" +
"<br/>" +
"<b>Date Of Invoice: </b>" + " " + DoI + "<br/>" +
"<b>Invoice: </b>" + " " + Inv + "<br/>" +
"<b>Material Information:</b>" + "<br/>" +
//slab 1
"<b>Thickness: </b>" + " " + Thick1 + "mm" + "<br/>" +
"<b>Material Name: </b>" + " " + Material1 + "<br/>" +
"<b>Batch No: </b>" + " " + Batch1 + "<br/>" +
"<b>Reason for Return: </b>" + " " + Reason1 + "<br/>" + "<br/>" +
//slab 2
"<b>Thickness: </b>" + " " + Thick2 + "mm" + "<br/>" +
"<b>Material Name: </b>" + " " + Material2 + "<br/>" +
"<b>Batch No: </b>" + " " + Batch2 + "<br/>" +
"<b>Reason for Return: </b>" + " " + Reason2 + "<br/>" + "<br/>" +
"<br/>" +
"<b>Notes:" + " " + Notes
};
var builder = new BodyBuilder();
//check for return attachment and if found, assign attachment to message via bodybuilder
if (checkBox5.Checked)
{
builder.TextBody = body2.Text;
builder.HtmlBody = body2.Text;
builder.Attachments.Add(ReturnAttachment1);
message.Body = builder.ToMessageBody();
}
if (checkBox7.Checked)
{
builder.TextBody = body2.Text;
builder.HtmlBody = body2.Text;
builder.Attachments.Add(ReturnAttachment1);
builder.Attachments.Add(ReturnAttachment2);
message.Body = builder.ToMessageBody();
}
if (checkBox6.Checked)
{
builder.TextBody = body2.Text;
builder.HtmlBody = body2.Text;
builder.Attachments.Add(ReturnAttachment1);
builder.Attachments.Add(ReturnAttachment2);
builder.Attachments.Add(ReturnAttachment3);
message.Body = builder.ToMessageBody();
}
else
{
message.Body = body2;
}
//Connection to SMTP and Criteria to Send
using (var client = new SmtpClient())
{
// For demo-purposes, accept all SSL certificates (in case the server supports STARTTLS)
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect("smtp.gmail.com", 587, false);
// Note: only needed if the SMTP server requires authentication
client.Authenticate("***************#********.com", "*********");
client.Send(message);
client.Disconnect(true);
This code was repeated all the way up to five slabs. So now, I have a class:
{
public string Thickness { get; set; }
public string Material { get; set; }
public string Batch { get; set; }
public Slab(string Thick, string Mat, string Batchno)
{
Thickness = Thick;
Material = Mat;
Batch = Batchno;
}
}
A List that holds this object:
private void button1_Click(object sender, EventArgs e)
{
string t = comboBox1.SelectedValue.ToString();
string m = comboBox2.SelectedValue.ToString();
string b = textBox6.Text;
Slab S = new Slab(t, m, b);
allSlabs.Add(S);
PaintTree();
}
public void PaintTree()
{
int ParentIndex;
TreeSlabs.Nodes.Clear();
foreach (Slab slab in allSlabs)
{
TreeSlabs.BeginUpdate();
TreeSlabs.Nodes.Add("Slab" + " " + (allSlabs.IndexOf(slab) + 1).ToString());
ParentIndex = allSlabs.IndexOf(slab);
TreeSlabs.Nodes[ParentIndex].Nodes.Add("Thickness: " + $"{slab.Thickness}");
TreeSlabs.Nodes[ParentIndex].Nodes.Add("Material: " + $"{slab.Material}");
TreeSlabs.Nodes[ParentIndex].Nodes.Add("Batch: " + $"{slab.Batch}");
TreeSlabs.EndUpdate();
}
}
Now i want to create a foreach.. that iterates through each node.. and collects the info from the parent and its children foreach node, and somehow instantiate new HTML methods for each node..
Foreach Node:
Compose HTML Line - new HTML
Slab 1:
Thickness:
Material
Batch
Slab 2:... etc
If theres 8 nodes, it generates 8 of those bodies. i can think of ways.. but i KNOW they're defintely not the correct ways to go about it based on what ive read and seen out there.
Many Thanks
You don't need to iterate through the tree and try to reclaim the data you put into it from the List of Slabs; it would be simpler to enumerate the List:
By the way, some other tips:
don't beginupdate/endupdate inside the loop, do it outside
the Add method that adds a node to a tree returns the node it added; you don't have to find it again by index, just capture it var justAdded = rootnode.Add("parent node"); and then add your thickness etc to it justAdded.Nodes.Add("thickness..."). The only add command that doesn't return the added mode is the one that takes a treenode type object; it doesn't need to return it because you already have it
consider adding a method to your slab to return some html, to simplify things
you can tidy all that html up with some string interpolation like you did with your $"{slab.thickness}" etc
I have the following code:
[Authorize]
[HttpGet]
public FileContentResult DownloadMsgAsPdf(string FileId, string outer = "")
{
var Results = (SearchResult)TempData["Results"];
var msg = Results.emails[FileId];
...
return File(pdfBytes, System.Net.Mime.MediaTypeNames.Application.Octet, msg.Id + ".pdf");
}
Now upon running it once (clicking a link) it does everything completely fine. However upon clicking it a second time (with nothing else changed or called) it errors out, with Results being null. I assume this means TempData is getting cleared, but how could this be?
Here is the full code if it's needed:
[Authorize]
[HttpGet]
public FileContentResult DownloadMsgAsPdf(string FileId, string outer = "")
{
var Results = (SearchResult)TempData["Results"];
var msg = Results.emails[FileId];
TempData.Keep();
msg.BodyHTML = System.Web.HttpUtility.HtmlDecode(msg.BodyHTML);
var htmlContent = String.Format("<center><p><b>Case ID</b>: " + msg.Id
+ " <b>User ID</b>: " + Session["userid"]
+ " <b>Privileged</b>: ");
if (msg.Tags != null)
{
htmlContent += msg.Tags.ContainsKey("privileged");
}
else
{
htmlContent += "False";
}
htmlContent += " <b>Downloaded</b>: " + DateTime.Now.ToString("g") + "</center>"
+ " <p> -- Forwarded message -- </p> "
+ " <p><b> From :</b> <a href='#'>" + msg.From + "</a> </p> "
+ " <p><b> Date:</b> Mon, oct 25 2010 at 4:42 PM </p> "
+ " <p> <b>Subject:</b> " + msg.Subject + " </p> "
+ " <p><b> To:</b> " + msg.To + " </p> "
+ " <p><b> Cc: </b> </p> "
+ " <div> "
+ " <ul> ";
if(msg.attachementList != null){
if (!msg.attachementList.Any())
{
htmlContent += "<text> "
+ "<li><label style='color:gray'>No attachment</label></li></text>";
}
else
{
foreach (var attachment in msg.attachementList)
{
var filename = System.IO.Path.GetFileName(attachment);
htmlContent += "<text> "
+ "<li><a href='#'>" + filename + "</a></li></text>";
}
}
}
htmlContent += "</ul>"
+ "</div>"
+ "<div padding: 5px;'>"
+ msg.BodyText
+ "</div>"
+ "</div>";
var pdfBytes = (new NReco.PdfGenerator.HtmlToPdfConverter()).GeneratePdf(htmlContent);
if (outer != "")
{
return File(pdfBytes, System.Net.Mime.MediaTypeNames.Application.Octet, msg.Id + ".pdf");
}
return new FileContentResult(pdfBytes, "application/pdf");
}
TempData means you only can get once. And i see you use TempData.Keep(), but this method only effect on the same http context. I think you can use Session or Cache instead of the TempData.
I would like to add multiple maps of the Google Maps API to a page of my C# ASP.NET application. However, with my current code, only the last map is shown. All the other divs that should contain a map are empty. As you can see in my code, the maps already have unique names (not on a nice way, but it is unique). Can someone explain what I am doing wrong?
It would be really appreciated.
Initialize Google:
protected void loadGoogle()
{
var googleScript = "function loadScript() {" +
"var script = document.createElement(\"script\");" +
"script.type = \"text/javascript\";" +
"script.src = \"http://maps.google.com/maps/api/js?sensor=false& callback=initialize\"; " +
"document.body.appendChild(script);" +
"}" +
"window.onload = loadScript;";
ClientScript.RegisterStartupScript(typeof(Page), "CreateGoogleMapScript", googleScript, true);
}
Create maps (called multiple times):
protected void createMap(String mapId, String address)
{
var script = "function initialize() {" +
"var geocoder = new google.maps.Geocoder();" +
"var latlng = new google.maps.LatLng(-34.397, 150.644);" +
"var mapOptions" + mapId + " = {" +
"zoom: 16," +
"center: latlng," +
"mapTypeId: google.maps.MapTypeId.ROADMAP" +
"};" +
" var map" + mapId + " = new google.maps.Map(document.getElementById(" + mapId + "), mapOptions" + mapId + ");" +
"var address = \"" + address + "\";" +
"geocoder.geocode( { 'address': address}, function(results, status) {" +
"if (status == google.maps.GeocoderStatus.OK) {" +
"map" + mapId + ".setCenter(results[0].geometry.location);" +
"var marker = new google.maps.Marker({" +
"map: map" + mapId + "," +
"position: results[0].geometry.location" +
"});" +
"} else {" +
"alert(\"Geocode was not successful for the following reason: \" + status); " +
"}" +
"});" +
"}";
ClientScript.RegisterClientScriptBlock(typeof(Page), "CreateMapScript"+mapId, script, true);
}
Called by:
While loop, with a literal.Text that adds a new div, followed by createMap(mapId, address);
UPDATE:
My new code:
var script = "function initialize() { var geocoder = new google.maps.Geocoder();";
for (int i = 0; i < maps.Count; i++)
{
String currentId = maps[i] as String;
String currentLocation = locations[i] as String;
script += " " +
"var latlng = new google.maps.LatLng(" + 500 + "," + 400 + ");" +
"var myOptions = {" +
"zoom: 16," +
"center: latlng," +
"mapTypeId: google.maps.MapTypeId.ROADMAP" +
"};" +
"var map = new google.maps.Map(document.getElementById(\"" + currentId + "\"), myOptions);" +
"var address = \"" + currentLocation + "\";" +
"geocoder.geocode( { 'address': address}, function(results, status) {" +
"if (status == google.maps.GeocoderStatus.OK) {" +
"map.setCenter(results[0].geometry.location);" +
"var marker = new google.maps.Marker({" +
"map: map," +
"position: results[0].geometry.location" +
"});" +
"} else {" +
"alert(\"Geocode was not successful for the following reason: \" + status); " +
"}" +
"});";
}
script += "};";
Now all maps are drawn, but only the last map has the right location. The other ones are based on the latlng variable. Why can't the geocoder be used multiple times?
Perhaps just the last initialize function is firing in the browser? Try having just 1 initialise function that initialises all your maps.
i am trying to get the values of my controls like this:
function ConfirmWithUser()
{
var nodeText = '';
$('.mytreeview input[#type=checkbox]:checked').each(function() {
nodeText += $(this).next('a').text() + '\r';
});
var confirmationMessage;
confirmationMessage = "Please review the data before submitting:" + "\r"
+ "Sample Received Date: " + document.getElementById(received_dateTextbox).Value + "\r"
+ "Site of Ocurrence: " + document.getElementById(site_of_occurrenceTextBox).Value + "\r"
+ "Occurrence Date: " + document.getElementById(occurrence_dateTextBox).Value + "\r"
+ "Report Date: " + document.getElementById(report_byTextBox).Value + "\r"
+ "Specimen ID: " + document.getElementById(spec_idTextBox).Value + "\r"
+ "Batch ID: " + document.getElementById(batch_idTextBox).Value + "\r\n"
+ "Report Initiated By: " + document.getElementById(report_byTextBox).Value + "\r\n"
+ "Problem Identified By: " + $("input[#name=RadioButtonList1]:checked").val() + "\r\n"
+ "Problem List: " + nodeText;
HiddenFieldConfirmation.Value = confirmationMessage;
if (confirm(document.getElementById('HiddenFieldConfirmation').value) == true)
{ return true; }
else
{ return false; }
}
and the CONFIRM box is not firing at all! i do not get any pop up.
i tried to debug using firefox, and as soon as it go to this line:
confirmationMessage = "Please review the data before submitting:" + "\r"
+ "Sample Received Date: " + document.getElementById(re.......
it escapes out of the function
what am i doing wrong? how can i get the values of all the controls?
You need to use a lowercase "v" for value and quote your element ids. Eg:
document.getElementById("received_dateTextbox").value
Since it appears you are already using jQuery, you can make your code a little more concise. So document.getElementById("received_dateTextbox").value becomes:
$("#received_dateTextbox").val()
There is no variable named spec_idTextBox.
You probably want to pass a string literal.
Once you fix that, you need to use .value in lowercase
If you are using dynamic client ids, you have to render the ids inline or pass them to your function:
confirmationMessage = "Please review the data before submitting:" + "\r"
+ "Sample Received Date: " + document.getElementById('<% = received_dateTextbox.ClientID %>').value + "\r"
+ "Site of Ocurrence: " + document.getElementById('<% = site_of_occurrenceTextBox.ClientID %>').value + "\r"
+ "Occurrence Date: " + document.getElementById('<% = occurrence_dateTextBox.ClientID %>').value + "\r"
+ "Report Date: " + document.getElementById('<% = report_byTextBox.ClientID %>').value + "\r"
+ "Specimen ID: " + document.getElementById('<% = spec_idTextBox.ClientID %>').value + "\r"
+ "Batch ID: " + document.getElementById('<% = batch_idTextBox.ClientID %>').value + "\r\n"
+ "Report Initiated By: " + document.getElementById('<% = report_byTextBox.ClientID %>').value + "\r\n"
+ "Problem Identified By: " + $("input[#name=RadioButtonList1]:checked").val() + "\r\n"
+ "Problem List: " + nodeText;
I have the following bits of code:
public static void WriteHTML(string cFile, List<Movie> mList)
{
int lineID = 0;
string strMovie, strGenre, tmpGenre = null;
// initiates streamwriter for catalog output file
FileStream fs = new FileStream(cFile, FileMode.Create);
StreamWriter catalog = new StreamWriter(fs);
string strHeader = "<style type=\"text/css\">\r\n" + "<!--\r\n" + "tr#odd {\r\n" + " background-color:#e2e2e2;\r\n" + " vertical-align:top;\r\n" + "}\r\n" + "\r\n" + "tr#even {\r\n" + " vertical-align:top;\r\n" + "}\r\n" + "div#title {\r\n" + " font-size:16px;\r\n" + " font-weight:bold;\r\n" + "}\r\n" + "\r\n" + "div#mpaa {\r\n" + " font-size:10px;\r\n" + "}\r\n" + "\r\n" + "div#genre {\r\n" + " font-size:12px;\r\n" + " font-style:italic;\r\n" + "}\r\n" + "\r\n" + "div#plot {\r\n" + " height: 63px;\r\n" + " font-size:12px;\r\n" + " overflow:hidden;\r\n" + "}\r\n" + "-->\r\n" + "</style>\r\n" + "\r\n" + "<html>\r\n" + " <body>\r\n" + " <table>\r\n";
catalog.WriteLine(strHeader);
foreach (Movie m in mList)
{
strMovie = lineID == 0 ? " <tr id=\"odd\" style=\"page-break-inside:avoid\">" : " <tr id=\"even\" style=\"page-break-inside:avoid\">";
catalog.WriteLine(strMovie);
foreach (string genre in m.Genres)
tmpGenre += ", " + genre;
try
{ strGenre = tmpGenre.Substring(2); }
catch (Exception)
{ strGenre = null; }
strMovie = " <td>\r\n" + " <img src=\".\\images\\" + m.ImageFile + "\" width=\"75\" height=\"110\">\r\n" + " </td>\r\n" + " <td>\r\n" + " <div id=\"title\">" + m.Title + "</div>\r\n" + " <div id=\"mpaa\">" + m.Certification + " " + m.MPAA + "</div>\r\n" + " <div id=\"genre\">" + strGenre + "</div>\r\n" + " <div id=\"plot\">" + m.Plot + "</div>\r\n" + " </td>\r\n" + " </tr>\r\n";
catalog.WriteLine(strMovie);
lineID = lineID == 0 ? 1 : 0;
}
catalog.WriteLine(" </table>\r\n" + " </body>\r\n" + "</html>");
catalog.Close();
}
public static void WritePDF(string cFile, string pdfFile)
{
// Sets up PDF to write to
EO.Pdf.HtmlToPdf.Options.PageSize = new SizeF(8.5f, 11f);
EO.Pdf.HtmlToPdf.Options.OutputArea = new RectangleF(0.5f, .25f, 7.5f, 10.25f);
HtmlToPdf.ConvertUrl(cFile, pdfFile);
}
My HTML file writes fine, but when it tried to convert the HTML file to PDF I get an exception that it times out.
I did a test previously, and had it convert the code (not the file) within the WriteHTML function and it worked great. I have confirmed that the cFile exists and is a valid file (created previously in WriteHTML). The path to pdfFile is valid, and the documentation does not state the file needs to already exist (.ConvertHTML did not need an existing file).
Only thing I can think of is that the catalog.html file isn't released and ready to read yet. I made sure I closed it in the WriteHTML function. How can I test that the file is ready to be read?
Tried setting .MaxLoadWaitTime = 120000 with no luck.
Any clues would be greatly appreciated!
After a battery of further testing, and scouring the EO support forums, it appears to be a limitation of the free version of EO. It seems to have difficulty with HTML files over 3MB.
It's a shame since the EO product is very good, but not unfortunately not worth $250 IMO.