Hey all I am using the new WebView2 with my WinForms app. I can get it to display my dynamic html that I create but it has the "" when it tries to load the images for the page.
The image tag looks like this:
<div id="animation1" style="display: inline-flex;">
<img src="file:///C:\Users\admin\source\repos\wCondictions\bin\x86\Debug\Resources/nice.gif" style="height: 110px; width: 110px;">
<span class="imgWeather">Nice</span>
</div>
The code I am currently using is this:
fileNames = new DirectoryInfo(resourcePath)
.GetFiles()
.OrderBy(p => Path.GetFileNameWithoutExtension(p.Name))
.Select(fi => fi.Name)
.ToArray();
string blah = Path.Combine(Application.StartupPath, "Resources");
string fullHtml = string.Empty;
string HeaderHtml = "<!DOCTYPE html>\n" +
"<html>\n" +
"<style>\n" +
".imgW {\n" +
"position: absolute;\n" +
"z-index: 10;\n" +
"color: red;\n" +
"width: 110px;\n" +
"height:30px;\n" +
"text-align: center;\n" +
"vertical-align: middle;\n" +
"top: 88px;\n" +
"background-color: aquamarine;\n" +
"font-family: Arial;\n" +
"font-size: small;\n" +
"}\n" +
"</style>\n" +
"<body style=\"background-color: #00000;\">";
string dynamixImg = "<div id=\"animation1\" style=\"display: inline-flex;\">\n" +
"<img src=\"file:///" + blah + "/{0}\" style=\"height: 110px; width: 110px;\" />\n" +
"<span class=\"imgW\">{1}</span>\n" +
"</div>";
string FooterHtml = "</body>" +
"</html>";
for (int a = 0; a < fileNames.Count(); a++)
{
fullHtml += string.Format(
dynamixImg,
fileNames[a],
fileNames[a]
.Replace(".gif", "")
.Replace("&", "&&")
) + "\n";
}
await webView21.EnsureCoreWebView2Async();
webView21.CoreWebView2.SetVirtualHostNameToFolderMapping(
"Resources",
#"C:\Users\admin\source\repos\wCondictions\bin\x86\Debug\Resources\",
CoreWebView2HostResourceAccessKind.Allow
);
webView21.NavigateToString(HeaderHtml + fullHtml + FooterHtml);
I've seen many places where it says to use the SetVirtualHostNameToFolderMapping but even with that it still says the same error.
So I am not sure what I am missing or misunderstanding about how to use the SetVirtualHostNameToFolderMapping in order to allow the images to load locally?
Ok, I will try again, my first answer was confusing.
You get the error because you use the file:// protocol.
It seems you have not fully understood the the use of SetVirtualHostNameToFolderMapping.
Once you have set the virtual server by calling SetVirtualHostNameToFolderMapping you should use that virtual server just as you use any other server on the internet. Do NOT use file://!
So all you have to do is edit your HeaderHtml and your <img src.
The HeaderHtml should include a <base> tag, which should point to your virtual server root:
<html>
<head>
<base href="http://Resources" />
</head>
That makes it very easy to build you dynamic <ìmg> tags, the source is simply the file name:
<img src="image.png" />
Now WebView2will translate it into a file path and fetch the image!
As a side note, you can also include files from sub-folder by adding the folder name in front of the file name, like this:
<img src="/subfolder/image.png" />
Related
I'm currently working on an equipment return eform, people input the equipment they're returning and when they click submit an email is sent to them and the equipment return team. I've also added a function where by when submit is clicked the programme accesses a database and brings up all the equipment that user still has yet to return. It then adds a grid view of the equipment they have yet to return to the email. To make the grid view show up on the email i had to convert the email to html, but when it does this it ruins the formatting of the email and puts it into one big paragraph instead of a few lines e.g.
(how I want it)
Hello
Bob Johnson has returned a laptop to Steve Johnson on the 28th of may
They also have these items taken out:
(How it comes out)
Hello Bob Johnson has returned a laptop to Steve Johnson on the 28th of may
They also have these items taken out:
below I have included the c# method I've used to send the email
}
protected void emailconfirmation(ObjectClass obIn_survey);
try
{
s_Body += " Hello" + " \n\n" +
"*************** \n" +
ob_survey.ob_Name + " " + "has Returned a" + " " + ob_survey.ob_Description_of_Equipment + " " + ob_survey.ob_asset_number + " " + "to" + " " + ob_survey.ob_Returned_To + " " + "(Charger returned, " + ob_survey.Return_Charger + ")" + " on" + " " + ob_survey.ob_Date_of_Return.ToShortDateString() + " " + " \n\n" +
" \n\n" + "Regards" + " \n\n" + "RCI Team" + " \n\n" + "This User also has the current Item(s) taken out";
s_GridView = GetGridviewData(gv_Equipment);
utility.Email_GenericMessage("RCITeam#rotherham.gov.uk", ob_survey.ob_Email_Receipt_to + ",RCITeam#rotherham.gov.uk", "Equipment Return", s_Body + s_GridView);
edited the above line
}
catch (Exception)
{
throw;
}
Here is the method in the utility class
public void Email_GenericMessage(String sIn_EmailFrom, String sIn_Emailto, String sIn_Subject, String sIn_Body )
{
using (MailMessage msg = new MailMessage(sIn_EmailFrom, sIn_Emailto, sIn_Subject, sIn_Body ))
{
msg.IsBodyHtml = true;
using (SmtpClient clt = new SmtpClient(System.Configuration.ConfigurationManager.AppSettings["SmtpServer"]))
{
clt.Send(msg);
}
}
Can anyone help? Thanks
This seems like it could be solved with a string replace. Have you tried s_Body.replace("\n", "<br/>");? Since the message html new lines are represented as <br/> instead of \n.
Use .html layout and placeholder for creating emails.
It's most ease and correct way.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div>{{NameFirst}}</div>
<div>{{NameSecond}}</div>
<div>{{Price}}</div>
<div>{{InvoiceNumber}}</div>
</body>
</html>
string forReplace = "{{" + prName + "}}";
if (res.Contains(forReplace))
{
var prValue = item.GetValue(obj);
res = res.Replace(forReplace, prValue.ToString());
}
I have the following html markup in a form with with and UpdatePanel. This code is rendering/displaying exactly as I want when statically coded. However, when I use a while loop in the c# codebehind to dynamically concatenate the code for all the 'docbox' elements into a string then set that string into InnerHtml for div 'bookshelf_items', it renders/displays very differently. It appears that after the first .docbox div is generated, the subsequent docbox divs are inside it. Another bizarre thing is that everything that should display after 'bookshelf_items' disappears.
Edit
<div class="bookshelf_items" id="bookshelf_items" runat="server">
<div class='docbox'>
<div class='doc' contenteditable='true' id='doc_50'>
<div class='doc_title'>TEST TITLE</div>
<div class='doc_txt'>TEST TEXT</div>
</div>
<div class='doc_date'>TEST DATE</div>
<div class='doc_del' ID='del_50' runat='server' />
<div class='doc_getlyt' ID='getlyt_50' runat='server' />
</div>
</div>
Edit - removed the CSS
Edit - removed the C# codebehind
Try this
private void GetUserDocs(string user_id)
{
using (SqlConnection connection = new SqlConnection(conn))
using (SqlCommand cmd = new SqlCommand("SELECT id, title, alias, dt from dbo.user_works WHERE user_id = #user_id", connection))
{
cmd.Parameters.AddWithValue("user_id", user_id);
connection.Open();
using (var reader = cmd.ExecuteReader())
{
// Check if the reader has any rows at all before starting to read.
if (reader.HasRows)
{
string doclist_html = "<div class=\"bookshelf_items\" id=\"bookshelf_items\" runat=\"server\">";
while (reader.Read())
{
string doc_id = reader["id"].ToString().Trim();
string title = reader["title"].ToString().Trim();
string alias = reader["alias"].ToString().Trim();
string dt = reader["dt"].ToString().Trim();
string date = DateTime.Parse(dt).ToShortDateString();
//build doc html
doclist_html = doclist_html + String.Format(
"<div class='docbox'>" +
"<div class='doc' contenteditable='true' id='doc_x{0}'>" +
"<div class='doc_title'>{1}" +
"</div>" +
"<div class='doc_txt'>{2}" +
"</div>" +
"</div>" +
"<div class='doc_date'>{3}</div>" +
"<div class='doc_del' ID='del_{0}' runat='server' />" +
"<div class='doc_getlyt' ID='getlyt_{0}' runat='server' />" +
"</div>",
doc_id, title, alias, date);
}
doclist_html += "</div>";
bookshelf_items.InnerHtml = doclist_html;
string testhtml = bookshelf_items.InnerHtml;
}
else
{
//username not found
lbl_error.Text = ">>Failed to get documents<<";
}
}
}
}
I figured out the solution to my own problem and I want to post the answer here in case anyone else runs into the same issue
When setting the InnerHtml into my div, the following code broke the parent/child hierarchy
<div class='doc_del' ID='del_54 runat='server' />
<div class='doc_getlyt' ID='getlyt_54' runat='server' />
The solution was to replace the embedded close characters with specific div close tag as follows:
<div class='doc_del' ID='del_54 runat='server'></div>
<div class='doc_getlyt' ID='getlyt_54' runat='server'></div>
Hopefully this will save someone some time and frustration. I don't know why it works this way. Maybe someone who knows will share. Thanks to those who commented on my issue
I'm trying to make a dynamic javascript from code behind that would be added to the page and would enable thus a little jwplayer to open up, my code so far:
void playAudioFile(string path)
{
string script =
#" var div = document.getElementById('playerDiv');
var audio = document.createElement('audio');
audio.setAttribute('id', 'audioPlayer');
div.appendChild(audio);
jwplayer(""audioPlayer"").setup({
file: 'http://ps.staging.be/webservice/MP3DownloadHandler.ashx?id='" + path +
#"'&date=' + '<%=Encrypt.EncryptString(String.Format(""{0:dd/MM/yyyy}"",
DateTime.UtcNow))%>',
width: ""100%"",
height: ""30"",
type: 'mp3',
stretching: ""uniform"",
controlbar: 'bottom'
});
";
//Add the script to it's tags
HtmlGenericControl playScript = new HtmlGenericControl("script");
playScript.InnerHtml = script;
//Add it on his place
playerDiv.Controls.Add(playScript);
But this turns out to a "could not make contact with localhost:55323 does anyone know what mistake I make? + is there a better way? The purpose would be to display a player if a person clicked on an element on my website, and the players path would change on hand of the selected item. I'm kinda making a system like youtube if you want something to compare with.
Final Solution
string date = Encrypt.EncryptString(String.Format("{0:dd/MM/yyyy}", DateTime.UtcNow));
string script =
#" var div = document.getElementById('ContentPlaceHolder1_playerDiv');
var audio = document.createElement('audio');
audio.setAttribute('id', 'audioPlayer');
div.appendChild(audio);
jwplayer(""audioPlayer"").setup({
file: 'http://ps.staging.be/webservice/MP3DownloadHandler.ashx?id=" + path + #"&date=" + date + #"',
width: '100%',
height: '30',
type: 'mp3',
stretching: 'uniform',
controlbar: 'bottom'
});
";
//Add the script to it's tags
HtmlGenericControl playScript = new HtmlGenericControl("script");
playScript.InnerHtml = script;
//Add it on his place
playerDiv.Controls.Add(playScript);
You should be using ClientScript.RegisterStartupScript to do this:
Page.ClientScript.RegisterStartupScript(this.GetType(), "FooKey", script, true);
You have a code block inside the script, not sure why you don't build that string in code and then append it to the script:
string date = Encrypt.EncryptString(String.Format("{0:dd/MM/yyyy}", DateTime.UtcNow));
string script =
#" var div = document.getElementById('playerDiv');
var audio = document.createElement('audio');
audio.setAttribute('id', 'audioPlayer');
div.appendChild(audio);
jwplayer(""audioPlayer"").setup({
file: 'http://ps.staging.be/webservice/MP3DownloadHandler.ashx?id='" + path + #"'&date=" + date + ", width: '100%', height: '30',type: 'mp3', stretching: 'uniform',controlbar: 'bottom'});";
You can not add scriptlet in the string and assign it to some controls InnerHtml.
I would write javascript directly to aspx (html) side as I belive that is simple and more straight forward.
Change
+ '<%=Encrypt.EncryptString(String.Format(""{0:dd/MM/yyyy}"", DateTime.UtcNow))%>',
To
+ Encrypt.EncryptString(String.Format("{0:dd/MM/yyyy}", DateTime.UtcNow))
I want to apply different css on different browsers.
I want to run one css when it is safari and second for all others.
How can I detect that and apply css according to that?
You can use CSS browser selectors for this. There are different solutions available for this on the net.
For example:
CSS Browser Selector
The CSS Browser Selector is a small JavaScript library which allows you to include different cascading style sheets (CSS) for each browser.
An example:
<style type="text/css">
.ie .example {
background-color: yellow
}
.ie7 .example {
background-color: orange
}
.opera .example {
background-color: green
}
.webkit .example {
background-color: black
</style>
If you Google for "different css per browser" you'll find other solutions as well, but most of them boil down to similar solutions.
Another way would be to detect the browser type and capabilities in ASP.NET so that you can render the appropriate HTML / CSS / ...etc. You can find more information on that topic here:
http://msdn.microsoft.com/en-us/library/3yekbd5b.aspx
For example:
private void Button1_Click(object sender, System.EventArgs e)
{
System.Web.HttpBrowserCapabilities browser = Request.Browser;
string s = "Browser Capabilities\n"
+ "Type = " + browser.Type + "\n"
+ "Name = " + browser.Browser + "\n"
+ "Version = " + browser.Version + "\n"
+ "Major Version = " + browser.MajorVersion + "\n"
+ "Minor Version = " + browser.MinorVersion + "\n"
+ "Platform = " + browser.Platform;
TextBox1.Text = s;
}
The Browser property of the Request returns a HttpBrowserCapabilities object. It contains information on the capabilities of the browser that is running on the client.
http://msdn.microsoft.com/en-us/library/system.web.httpbrowsercapabilities.aspx
You can examine the UserAgent property of the Request object.
Inside the page head tag
<%# Request.UserAgent.ToLower().Contains("safari") ?
"<link rel='stylesheet' type='text/css' href='safari.css' />" :
"<link rel='stylesheet' type='text/css' href='other.css' />" %>
Use below things....in your control...and you can set different style...to asp.net textbox control for different browser.
<asp:TextBox ID="TestTextBox" runat="server" ie:Text="You are in Internet explorer." mozilla:Text="You are in Firefox." Text="You are in other browser." ie:CssClass="IEStyle" mozilla:CssClass="FFStyle" CssClass="DefaultStyle" />
using Using the Request.Browser you can determine the browser user is using your
You can check it from javascript like:
if (navigator.appName == 'Microsoft Internet Explorer') {
var fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
i m trying to create a div container in c# codebehind.i want the div container to raise a javascript event onclick once its clicked.its working fine.below is the code where a javascript function "ds()" is called with no parameters.the problem is that i want to pass a parameter to javascript function.I dont know how to accomplish it.Kindly facilitate me.
//string userIcon = "gbn";
sb.Append(userIcon + #"<div onclick=""ds()"" style='background-color: #EFEFEF; padding: 10px;'>" + "<a href=#>" + "MubbshirAbbs" + "</a></div><br>");
Literal1.Text = sb.ToString();
The Javascript function is this:
function ds()
{
var a="";alert("123");
document.getElementById("TextBox1").style.backgroundColor="red";
}
Kindly let me know how can i add a parameter in the div onclick function.
Alter the C# code:
sb.Append(userIcon);
sb.Append(#"<div onclick=""ds(");
sb.Append("'clicked'");
sb.Append(#")"" style='background-color: #EFEFEF; padding: 10px;'>");
sb.Append("<a href=#>");
sb.Append("MubbshirAbbs");
sb.Append("</a></div><br>");
Alter the javascript:
function ds(param)
{
var a="";alert("123");
document.getElementById("TextBox1").style.backgroundColor="red";
}
I don't know if I get your problem, can't you just do this?:
sb.Append(userIcon + #"<div onclick=""ds(" + parameter + ")"" style='background-color: #EFEFEF; padding: 10px;'>" + "<a href=#>" + "MubbshirAbbs" + "</a></div><br>");
Literal1.Text = sb.ToString();
function ds(parameter)
{
var a="";alert(parameter);
document.getElementById("TextBox1").style.backgroundColor="red";
}