I am creating a custom include method (load) to check if a file exists. The load function includes the file if it exists or sends an email to notify me of a broken link if it doesn't. The problem I am having is if the include file contains server controls, it just displays them as plain text. This is a problem if I were to try to add an include file to an include file.
In default.aspx I have:
<% ResourceMngr.load("~/Includes/menu.inc"); %>
In ResourceMngr:
public static void load(String url) {
string file = HttpContext.Current.Server.MapPath(url);
if (System.IO.File.Exists(file))
{
HttpContext.Current.Response.Write(System.IO.File.ReadAllText(file));
}
else
{
String body = "This message was sent to inform you that the following includes file is missing: \r\n";
body += "Referrer URL: " + HttpContext.Current.Request.Url.AbsoluteUri + "\r\n";
body += "File Path: " + file;
MailUtil.SendMail("email#email.com", "Missing Includes File", body);
}
}
So, if "menu.inc" also includes a <% ResourceMngr.load("~/Includes/test.inc"); %> tag, it just prints it out in plain text on the page instead of trying to include test.inc while all the other html on the page shows up exactly as expected. How would I allow my include file to have server controls?
I assume you come from a classic asp or php background. asp.net doesn't work in this way with includes. You probably want to look up some basic webforms or mvc tutorials because you want to work with the framework, and not against it :-)
in particular, look up how to use UserControls (ie. the ones with a .ascx extension)
Related
In C# I have code that uploads a file Async to a php file, then in the PHP file I assign a unique ID (given by the C# code), then store the file in a database. This can run multiple times BUT it only seems to be working with the very first file that gets uploaded, and not the subsequent.
Maybe (is_uploaded_file($_FILES['file']['tmp_name']) only knows how to reference the VERY FIRST file it receives and doesn't know to clear it from memory? So the other files it receives shortly later is called (is_uploaded_file($FILES['file2']['tmp_name'] or something. Just a shot in the dark.
I'm not going to post a bunch of code because my code is very simple and is not a problem with it as far as I am aware, this is the only reason this error might be happening as far as I know.
EDIT: Fine, its not that simple but here is code:
C#
foreach (MailItem email in Globals.ThisAddIn.Application.ActiveExplorer().Selection)
{
string email_id = ArchiveEmail(email);
if (chkBoxSyncEmail.Checked)
{
foreach (Attachment atch in email.Attachments)
{
try
{
if(AttachmentsBeingSent.Contains(atch.FileName))
{
//Sending attachment.
string filePath = Path.Combine(#"", (email_id + atch.FileName)); //We add the unique email_id to the beginning of the filename, it is always 13 chars long so we can pull the unique id off later with ease.
atch.SaveAsFile(filePath); //Save as file
WebClient wc = new WebClient();
await wc.UploadFileTaskAsync(new Uri("https://xxxx.com/xxxx/xxxx/xxxx/upload_attachment.php"), "POST", filePath);
MessageBox.Show(atch.FileName + " Uploaded successfully");
if (File.Exists(filePath))
{
File.Delete(filePath);
}
}
}
PHP
<?php
include('../include/xxx.php');
if (is_uploaded_file($_FILES['file']['tmp_name']))
{
global $xxx;
$uploaddir = 'xxxxxxxx/'; // Relative Upload Location of data file, if its empty it should place in this location.
$given_email_ID = substr(($_FILES['file']['name']),0,13); //Take first 13 chars off from beginning and that is our email_ID.
$fileName = substr(($_FILES['file']['name']),13); //This should be our filename and extension intact. Still need to add a unique_ID to this one so it doesn't get overwritten in file system.
$unique_ID = uniqid();
$newName = $unique_ID.$fileName;
$download_loc = ($uploaddir.$NewName);
if (move_uploaded_file($_FILES['file']['tmp_name'], $uploaddir.$newName))
{
$xxx->query("
INSERT INTO attachments(
email_id,
file_name,
download_loc) VALUES (
'" . $given_email_ID . "',
'" . $newName . "',
'" . $download_loc . "'
);
");
}
}
QUERY (in PHP)This only gives me one result! I should have at least multiple. Only one thing gets entered in the table back in the other PHP script.
<?php
$attachments = $xxxx->query("
SELECT *
FROM attachments
");
if($attachments->num_rows > 0) {
while ($row = $attachments->fetch_assoc()) {
echo $row['email_id'].' ';
}
}
?>
As you're sending the files without any html or form directly by C# I verified your C# code a bit now and remarked a fault.
You've to see the principal statements I do, about the notation in C# I might be wrong as I'm not working with it. So it's possible, that you've to adjust my code.
The important point is: you're sending in each loop only one file.
This is your code, generally adjusted to upload several files if available:
foreach (MailItem email in Globals.ThisAddIn.Application.ActiveExplorer().Selection)
{
string email_id = ArchiveEmail(email);
if (chkBoxSyncEmail.Checked)
{
// collecting attachements
array attachements;
foreach (Attachment atch in email.Attachments)
{
if(AttachmentsBeingSent.Contains(atch.FileName))
{
string filePath = Path.Combine(#"", (email_id + atch.FileName)); //We add the unique email_id to the beginning of the filename, it is always 13 chars long so we can pull the unique id off later with ease.
atch.SaveAsFile(filePath); //Save as file
attachements[] = filePath;
}
}
try
{
// if there are any attachements, do upload
if(sizeof(attachements))
{
//Sending attachments.
WebClient wc = new WebClient();
await wc.UploadFileTaskAsync(new Uri("https://xxxx.com/xxxx/xxxx/xxxx/upload_attachment.php"), "POST", attachements);
...
}
}
}
}
I removed a few lines with some logic which was prepared to send only one file. If you send multiple files at once, things are working different and you can't handle a feedback for every single file, at least not in the kind like you coded.
You've to make two small changes in your code:
the name in the input-field of the form has to be an array to take several file and it has to be noted / announced that upload of several files is possible:
<input type="file" name="attachements[]" multiple="multiple" id="attachements" />
The array of files is built when the square brackets are used [] after the field-name.
multiple can be noted in several versions, probably it's enough just to use the word inside the html for the input-field without any assignment, the notation I used above comes from the old xml-syntax, you also can leave the assignment empty or use "true" as value.
The php-code for handling a single file has to be moved into a loop to handle all files. Before changing the form you won't be able to see more than one file in the incoming array $_FILES. According to the input-field above all files will be available in the variable $_FILES['attachements'].
Furthermore you've to adjust the form-element perhaps. If you handle the upload by the same site respectively file where the form is located you can just note it like this and leavinng action empty:
<form action="" enctype="multipart/form-data" method="post">
If you handle the upload on a different site just enter the filename in the action like this:
<form action="url/to/file/handle-upload.php" enctype="multipart/form-data" method="post">
Here you find an approach to realize it with ajax: PHP Handling file uploads
Here you find a video with a solution that is building a few small features around the whole approach.
Here you find the input-field with type file in the html5-standard.
Trying to assigning hyperlink to pdf location inside PDF using c# asp.net web forms.
This is my C# code assigned link url to pdf location.
protected void FillPDF()
{
Dictionary<string, string> formFieldMap;
pdfPath = Path.Combine(Server.MapPath("../img/fullapplication_final.pdf"), ""); // need to take
formFieldMap = PDFHelper.GetFormFieldNames(pdfPath);
string livepath = "http://www.example.com/";
if (!string.IsNullOrEmpty(Request.QueryString["RegistrationId"].ToString() as string))
{
bo.Para1 = Request.QueryString["RegistrationId"].ToString();
bo.Para2 = "3";
DataTable dt = bl.Admin_Get_UserInformation(bo);
formFieldMap["text_attchedfilertpin"] = livepath + "TrainingPlan/" + dt.Rows[0]["TrainingPlan"].ToString();
}
}
This code is showing an url like www.example.com/my.pdf as its output.
But I need the output to be like this : click here to download pdf
I am trying below new code to get the output as I need it:
HyperLink DynLink = new HyperLink();
DynLink.ID = "DynLink1";
DynLink.Text = "click here to donwload pdf";
DynLink.NavigateUrl = livepath + "TrainingPlan/" + dt.Rows[0]["TrainingPlan"].ToString();
Page.Controls.Add(DynLink);
But I'm not able to assign view of pdf using
formFieldMap["text_attchedfilertpin"]
I am looking for your help thank you in advance.
In order for the PDF link to be recognized as a file download, you need to add a special Content-Disposition: attachment; file=xxx.pdf HTTP header (see this for code example - code to download PDF file in C# ).
Let's say you want to have a link http://www.example.com/plans/my123.pdf that when clicked initiates a PDF file download of a training plan called "my123".
You can create an HTTP handler - a class PlanPDF that implements IHttpHandler. In the code of the handler you can set the right Content-Type, Content-Disposition, Content-Length and transmit the PDF file as in the link above. See this article for a simple example of IHttpHandler
Next you need to configure URL rewriting so that requests coming to /plans/my123.pdf get mapped to your handler PlanPDF.
This you can do in your "Web.config" (see the same codeproject article for an example).
Parse the plan name from the request URL path, and use it to determine which training plan file to transmit.
I have an issue with an mvc4 application in witch i would like to send a generated html page created with HTML + C#. The problem is that when i recieved the email i see my c# code like the exemple bellow:
Recieved Email
But in the mail preview i can see the correct values like this:
Mail Preview
So this is my EmailTemplate method:
<pre>
public static async Task<string> EMailTemplate (string template)
{
var templateFilePath =HostingEnvironment.MapPath("~/Views/Home/") + template + ".cshtml";
StreamReader objstreamreaderfile = new StreamReader(templateFilePath);
var body = await objstreamreaderfile.ReadToEndAsync();
objstreamreaderfile.Close();
return body;
}
</pre>
Please if you have any idea how to convert my template to Html without inclouding my C# code.
Thanks,
Use Pure Html template (Not a cshtml view) with Inline CSS and Absolute image URIs for email body and fill it text templates. See the below image.
In the above image, field with ##...## are text templates.
Now read this HTML template as a string and replace ##...## fields by some dynamic information using the C# code (Actually any language code). You can use string.Replace() method to replace these fields by actual values. I have already used this method and it is working fine. I hope this will help you too.
I'm a beginner in C# (and any networking code to be honest). I'm trying to send a calendar invite, that will be wired when you click a button on the company's website. This is a typical n-tier system, using asp.net/C# and SQL.
We used to simply generate an ics that the user would then have to know to open with Outlook, but I've since learned how to manually code a VCALENDAR so it shows up right away in Outlook nice and neat.
It's all been going fairly smoothly, but I would now like the body of the calendar invite to be able to accept HTML, to attach links in particular. I've experimented with AlternateViews, but it seems that the "X-ALT-DESC" attribute inside of VCALENDAR should do exactly what I want. However, try as I may Outlook ignores it and uses the description. There is clearly something I am missing.
(To clarify, everything works & compiles, except for the HTML alt description)
private Guid? CreateEmail()
{
Guid eventGuid = Guid.NewGuid();
MailMessage msg = new MailMessage();
msg.IsBodyHtml = true;
msg.From = new MailAddress("fromemail", "From Name");
msg.To.Add(toEmail);
msg.Subject = subject;
StringBuilder s = new StringBuilder();
s.AppendLine("BEGIN:VCALENDAR");
s.AppendLine("VERSION:2.0");
s.AppendLine("PRODID:-//My Product//Outlook MIMEDIR//EN");
s.AppendLine("METHOD:" + method); //In this case, "REQUEST"
s.AppendLine("STATUS:" + status.status); //"CONFIRMED"
s.AppendLine("BEGIN:VEVENT");
s.AppendLine("UID:" + eventGuid.ToString());
s.AppendLine("PRIORITY" + status.priority); //3
s.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:" + ShowAs.ToString()); //"BUSY"
s.AppendLine("SEQUENCE:" + UpdateNumber);//0
s.AppendLine("DTSTAMP:" + DateTime.Now.ToUniversalTime().ToString());
s.AppendLine("DTSTART:" + DateTimetoCalTime(startTime));
s.AppendLine("DTEND:" + DateTimetoCalTime(endTime));
s.AppendLine("SUMMARY:" + subject);
s.AppendLine("LOCATION: " + location);
s.AppendLine("DESCRIPTION: " + "Plain simple description"
string html_begin = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">" +
"\n<html>" +
"\n<head>" +
"\n<title></title>" +
"\n</head>" +
"\n<body>" +
"\n<!-- Converted from text/rtf format -->\n\n<P DIR=LTR><SPAN LANG=\"en-us\">" +
"\n<Font face=\"Times New Roman\"";
body = "I simply <b> want some bold </b> here 555";
string html_end = "</font></span></body>\n</html>";
string html_body = html_begin + body + html_end;
msg.Body = html_body;
s.AppendLine("X-ALT-DESC;FMTTYPE=text/html:" + html_body);
msg.Body = html_body;
s.AppendLine("X-ALT_DESC;FMTTYPE=text/html:" + html_body);
s.AppendLine("STATUS:" + status.status); //"CONFIRMED"
s.AppendLine("BEGIN:VALARM");
s.AppendLine("TRIGGER:-PT1440M");
s.AppendLine("ACTION:Accept");
s.AppendLine("DESCRIPTION:Reminder");
s.AppendLine("END:VALARM");
s.AppendLine("END:VEVENT");
s.AppendLine(string.Format("ATTENDEE;CN=\"{0}\";RSVP=TRUE:mailto:{1}", msg.To[0].DisplayName, msg.To[0].Address));
s.AppendLine("END:VCALENDAR");
System.Net.Mime.ContentType type = new System.Net.Mime.ContentType("text/calendar");
type.Parameters.Add("method", method);
type.Parameters.Add("name", "meeting.ics");
msg.AlternateViews.Add(AlternateView.CreateAlternateViewFromString(s.ToString(), type));
SMTP.send(msg);
return EventGuid;
Produces this body in outlook:
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 3.2//EN”>
<html>
<head>
<title></title>
</head>
<body>
<!-- Converted from text/rtf format -->
<P DIR=LTR><SPAN LANG=”en-us”>
<Font face=”Times New Roman”I simply <b> want some bold </b> here 555</font></span></body>
</html>
From testing:
If I leave Msg.body out, it just used the "DESCRIPTION".
If I make it equal the HTML, I get the above result.
Thank You!
You can have X-ALT-DESC on multiple lines, you just need to add a space on the beginning of each lines following it.
Lines of text SHOULD NOT be longer than 75 octets, excluding the line break. Long content lines SHOULD be split into a multiple line representations using a line "folding" technique. That is, a long line can be split between any two characters by inserting a CRLF immediately followed by a single linear white-space character (i.e., SPACE or HTAB). Any sequence of CRLF followed immediately by a single linear white-space character is ignored (i.e., removed) when processing the content type.
https://icalendar.org/iCalendar-RFC-5545/3-1-content-lines.html
I found that the HTML string must be all on one line. If the HTML is broken over multiple lines, that does not conform to Vcalendar encoding and the description is either rendered as a blank page or as plain text with all HTML tags visible.
I've seen others out there claiming that the DESCRIPTION tag must be used in front of "X-ALT-DESC;FMTTYPE=text/html:". This is totally WRONG and FALSE. If "DESCRIPTION" exists, it takes precedence, the "X-ALT-DESC;FMTTYPE=text/html:" line is completely ignored by Outlook and the plain text description is rendered. Therefore, "X-ALT-DESC;FMTTYPE=text/html:" must stand on it's own and be on it's own line.
Working example:
...
X-ALT-DESC;FMTTYPE=text/html:<html><body>Bing</body></html>
...
Wrong:
...
DESCRIPTION;X-ALT-DESC;FMTTYPE=text/html:<html><body>Bing</body></html>
...
Wrong again:
...
X-ALT-DESC;FMTTYPE=text/html:<html>
<body>
Bing
</body>
</html>
...
For those in the future:
The problem was the use of
.AppendLine.
Simply use
.Append
The ics file which i am loading is not created with proper spaces which is longer than 75 octets, if i am manually adding space and loading to Ical.net.Calendar it works fine. But i want to do the same through c# code like manipulating the calendar file before loading to avoid parsing errors.
For reference, here's an explanation from https://icalendar.org/
"The original iCalendar standard allowed only plain text as part of an event description. HTML markup, such as font attributes (bold, underline) and layout (div, table) was not allowed in the text description field. First seen in Microsoft Outlook, the X-ALT-DESC parameter provides a method to add HTML to an event description. "X-" fields are allowed for non-standard, experimental parameters. This field has become the method of choice when including HTML in a description. When using HTML, both fields must be included so that iCalendar readers that do not support the X-ALT-DESC field can still read the text version."
...and it looks like Outlook 2016 dropped support for this. Generating ics files with html description only is most of the time not an option as Thunderbird/Lightening in the past did not handle this leading to calendar invites with empty body.
https://answers.microsoft.com/en-us/msoffice/forum/msoffice_outlook/outlook-2016-ics-description-shows-no-html/08d06cba-bfe4-4757-a052-adab64ea75a2?page=1
I have problem with browse button and switching to file dialog. I cannot use my file path control and just send there my string with file path and file itself, as it's readonly and in fact some behind control is my input filepath.
Here's my code
driver.FindElement(By.Id("browseButton")).Click();
driver.SwitchTo().ActiveElement().SendKeys(filepath);
Above code fills my control for file path, as i can see that on UI. But my open file dialog is still opened and i do not know how to close it and submit my upload.
Uploading files in Selenium can be a pain, to say the least. The real problem comes from the fact that it does not support dialog boxes such as file upload and download.
I go over this in an answer to another question, so I will just copy/paste my answer from there here. The code examples should actually be relevant in your case, since you are using C#:
Copied from previous answer on question here:
Selenium Webdriver doesn't really support this. Interacting with non-browser windows (such as native file upload dialogs and basic auth dialogs) has been a topic of much discussion on the WebDriver discussion board, but there has been little to no progress on the subject.
I have, in the past, been able to work around this by capturing the underlying request with a tool such as Fiddler2, and then just sending the request with the specified file attached as a byte blob.
If you need cookies from an authenticated session, WebDriver.magage().getCookies() should help you in that aspect.
edit: I have code for this somewhere that worked, I'll see if I can get ahold of something that you can use.
public RosterPage UploadRosterFile(String filePath){
Face().Log("Importing Roster...");
LoginRequest login = new LoginRequest();
login.username = Prefs.EmailLogin;
login.password = Prefs.PasswordLogin;
login.rememberMe = false;
login.forward = "";
login.schoolId = "";
//Set up request data
String url = "http://www.foo.bar.com" + "/ManageRoster/UploadRoster";
String javaScript = "return $('#seasons li.selected') .attr('data-season-id');";
String seasonId = (String)((IJavaScriptExecutor)Driver().GetBaseDriver()).ExecuteScript(javaScript);
javaScript = "return Foo.Bar.data.selectedTeamId;";
String teamId = (String)((IJavaScriptExecutor)Driver().GetBaseDriver()).ExecuteScript(javaScript);
//Send Request and parse the response into the new Driver URL
MultipartForm form = new MultipartForm(url);
form.SetField("teamId", teamId);
form.SetField("seasonId", seasonId);
form.SendFile(filePath,LoginRequest.sendLoginRequest(login));
String response = form.ResponseText.ToString();
String newURL = StaticBaseTestObjs.RemoveStringSubString("http://www.foo.bar.com" + response.Split('"')[1].Split('"')[0],"amp;");
Face().Log("Navigating to URL: "+ newURL);
Driver().GoTo(new Uri(newURL));
return this;
}
Where MultiPartForm is:
MultiPartForm
And LoginRequest/Response:
LoginRequest
LoginResponse
The code above is in C#, but there are equivalent base classes in Java that will do what you need them to do to mimic this functionality.
The most important part of all of that code is the MultiPartForm.SendFile method, which is where the magic happens.
One of the many ways to do that is to remove the disable attribute and then use typical selenium SendKeys() to accomplish that
public void test(string path)
{
By byId = By.Id("removeAttribute");
const string removeAttribute = #"document.getElementById('browseButton').removeAttribute('disabled');";
((IJavaScriptExecutor)Driver).ExecuteScript(removeAttribute);
driver.FindElement(byId).Clear();
driver.FindElement(byId).SendKeys(path);
}
You can use this Auto IT Script to Handle File Upload Option.
Auto IT Script for File Upload:
AutoItSetOption("WinTitleMatchMode","2") ; set the select mode to
Do
Sleep ("1000")
until WinExists("File Upload")
WinWait("File Upload")
WinActivate("File Upload")
ControlFocus("File Upload","","Edit1")
Sleep(2000)
ControlSetText("File Upload" , "", "Edit1", $CmdLineRaw)
Sleep(2000)
ControlClick("File Upload" , "","Button1");
Build and Compile the above code and place the EXE in a path and call it when u need it.
Call this Once you click in the Browse Button.
Process p = System.Diagnostics.Process.Start(txt_Browse.Text + "\\File Upload", DocFileName);
p.WaitForExit();