I'm creating a gif file using a camera in c#, then sending that gif to the persons email. I've attached the gif and created an html email, then display the gif inline using an img tag with the src being the cid of the attached gif file.
Its working perfectly except for androids gmail client. When you view the email in the android gmail client, the gif flashes, showing the background either between frames, at the end of the gif sequence, or sometimes showing the gif once then the gif just disappears.
I am using a table (it seems divs made it worse), and no background images or colors. Sometimes it seemed like certain things i did fixed the problem because it was playing just fine, but after opening the email a couple times or sending a couple more, the gif would do it again (start flashing).
is this a bug in the gmail client or something? nothing i've done seems to help. The gif plays perfectly in every other client i've tried and in the browser works just fine.
Is there something i could try that might fix this problem?
i'm sure people will want to see some code, so here it is, super simple
<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center" style="min-width:638px;">
<tr>
<td align="center" valign="top">
<table width="640px" border="0" cellspacing="0" cellpadding="0" align="center">
<tr>
<td width="78px" height="482px" align="center">
<img alt="xxxxxxx" src="cid:B01_frameLeft" border="0" style="display:block;"></a>
</td>
<td width="484px" height="484px" align="center">
<img alt="xxxxxxx" src="cid:B02_gif" border="0" width="484" height="484" style="display:block;"></a>
</td>
<td width="78px" height="482px" align="center">
<img alt="xxxxxxx" src="cid:B03_frameRight" border="0" style="display:block;"></a>
</td>
</tr>
</table>
</td>
</tr>
</table>
So it seems that if there are possibly more than one "layer", the gif "may" flash. I had multiple tables wrapped up in a single table. after removing the container table, the gif stopped flashing. I wonder if android gmail was having a problem because it maybe didn't know if it should display the next frame of the gif or the containing table? I still don't know for sure, but i'm certain that this can be considered a bug, i'm really surprised there is very little on the internet about this.
anyway, to fix my problem this is what i did.
removed all bgcolors and backgrounds from all html in the email
removed container table which contained tables for the layout, where one of them contained the gif
changed from using divs to using tables
not sure if all that was needed or not, but after doing those things i don't have a problem with the gif flashing anymore
Related
My viewmodel object contains approximately 200 to 300 objects.
One property for that object is an 100x100px image converted to Base64string.
Here is my code for rendering the entire collection:
<table class="table-condensed">
<tbody>
#foreach (var ua in day.Value)
{
<tr>
<td style="width: 105px;">
<img src="data:image;base64,#ua.UserProfileImage" style="width:100px;height:100px;" alt="User Image" />
</td>
<td valign="top">
<b>#ua.UserFirstName #ua.UserLastName</b> <a asp-controller="Users" asp-action="File" asp-route-id="#ua.UserId">(Profile)</a><br />
#if (!string.IsNullOrEmpty(ua.TeamName))
{
<small>#ua.TeamName</small><br />
}
<span class="label label-default">#ua.FunctionName</span><text> </text><span class="label label-default">#ua.HireDate</span>
</td>
</tr>
}
</tbody>
The logic and the time till the controller returns the data is 0.5 seconds so my problem isn't there.
The render speed for the entire view is about 5 to 8 seconds because of those many images.
Is there a way to improve that number?
I'm using ASP.NET Core 2.
You can use Ajax javascript to load every image and you can implement some pagination , the load time will be the same but on the client side it looks better
You should consider to use lazy image loading
https://github.com/craigbuckler/progressive-image.js. You can see at demo that images are not loading until you scroll to their destination
I have some code that gets a web response. How do I take that response and search for a table using its CSS class (class="data")? Once I have the table, I need to extract certain field values. For example, in the sample markup below, I need the values of Field #3 and Field #5, so "85" and "1", respectively.
<table width="570" border="0" cellpadding="1" cellspacing="2" class="data">
<tr>
<td width="158"><strong>Field #1:</strong></td>
<td width="99">1</td>
<td width="119"><strong>Field #2:</strong></td>
<td width="176">110</td>
</tr>
<tr>
<td width="158"><strong>Field #3:</strong></td>
<td width="99">85</td>
<td width="119"><strong>Field #4:</strong></td>
<td width="176">-259.34</td>
</tr>
<tr>
<td width="158"><strong>Field #5:</strong></td>
<td width="99">1</td>
<td width="119"><strong>Field #6:</strong></td>
<td width="176">110</td>
</tr>
<tr>
<td width="158"><strong>Field #7:</strong></td>
<td width="99">12</td>
<td width="119"><strong>Field #8:</strong></td>
<td width="176">123.23</td>
</tr>
</table>
Use the HTML Agility Pack and parse the HTML. If you want to do it the simplest way then go grab its beta (it supports LINQ).
As Randolf suggests, using HTML Agility Pack is a good option.
But, if you have control of the format of the HTML, it is also possible to do string parsing to extract the values you are after.
It is nearly trivial to download the entire HTML as a string and search for the string "<table" followed by the string "class=\"data\"". Then you can easily extract the values you are after by doing similar string manipulations.
I'm not saying you should do this, for the resulting code will be harder to read and maintain that the code using HTML Agility Pack, but it will save you an external dependency and your code will probably perform much better.
In a WP7 app I made, I started using HTML Agility Pack to parse some HTML and extract some values. This worked well, but it was quite slow. Switching to the string parsing regime made my code many times faster while returning the exact same result.
I currently have a table with a repeater that is being filled with data
<table width="100%" >
<tr>
<td class="add_border_bold" nowrap>Title</a></td>
<td class="add_border_bold" nowrap>User</td>
</tr>
<asp:Repeater id="program_list" OnItemDataBound="Repeater1_ItemDataBound" runat="server">
<ItemTemplate>
<tr>
<td class="add_border">
<%# Eval("short_title") %>
</td>
<td class="add_border">
<%# Eval("userid") %>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
I'm currently converting this from coldfusion. In the previous application, I had multiple table layouts for displaying different kinds of information, for example, phone number instead of userid. (although, working with a lot more columns, I shortened it for posting). In coldfusion I would just wrap each table in a <cfif> tag controlled by a variable that said which view to use. I am unaware how to get multiple data displays into a single page controlled by a variable, like I was before. Mostly because, it appears that most of my logic is done in the code behind files, so I don't understand how to get those changes across in the .aspx, or how to manipulate them from the code behind file.
Thanks in advance.
I would utilize a MultiView control and determine which view to show from code-behind.
I have an ASP.NET web app that retrieves a JSON collection and outputs the content of the collection, via LINQ to a StringBuilder that has a lot of table and other tags in HTML, with my data pieces interspersed.
This is what I mean:
sb.AppendFormat(#"
<table cellpadding=""0"" class=""TableStyle"" style=""width: 70%; height: 100%;"" cellspacing=""5"">
<tr>
<td class=""PicHolder"" style=""width: 151px"" rowspan=""2"">
<a href=""http://twitter.com/{0}"" target=""_blank""><img height=""45px"" width=""45px"" src=""{1}"" alt=""{4}""></td>
<td style=""width: 100%; height: 36px;"" class=""LinkTitleCell"" valign=""top"">
<span class=""BoldText"" style=""height: 23px"">
<span class=""HyperLinks"">{6}</span></span></ br><span class=""NormText"">
</tr>
<tr>
<td style=""width: 100%; height: 10px;"" class=""MentionedXTimes"" valign=""top"">
<span class=""NormText"">Mentioned {3} time(s).</span></td>
</tr>
<tr>
<td style=""width: 151px"" class=""UserName""><span class=""UserName""><img height=""1"" src=""spacer.gif"" width=""1"" />{4}:</span></td>
<td style=""height: 23%; width: 100%"" class=""WhatUserSaid"" valign=""top"">
{5}</td>
</tr>
<tr>
<td style=""width: 151px"" class=""UserName"">Info:</td>
<td style=""height: 24px; width: 100%"" class=""LinkTitleCell"" valign=""top""><span class=""NormText"">{7}</span></td>
</tr>
<tr>
<td style=""height: 9px; width: 151px""></td>
<td class=""LinkGreen"" style=""height: 9px; width: 100%"" valign=""top"">{2}</td>
</tr>
<tr>
<td style=""height: 9px; width: 151px""> </td>
<td class=""TableSpacer"" style=""height: 9px; width: 100%"" valign=""top""> </td>
</tr>
</table>",
count.First.userName, count.First.imgURL, newdata, count.Count, count.First.userName, count.First.txtDesc, (title != string.Empty) ? title2 : newdata, metaDesc2);
You can see all of the {0} and {1} data place holders I am using in the code above, and the reference to the data required at the end of the StringBuilder method call.
I want to be able to separate the HTML from my app so that I can edit it more easily without having to escape all of the "" quote marks.
So I need a template that has place holder for where my data goes. This is a noob question and I know exactly what want but not how to implement it.
Any help much appreciated!
I'm getting some bad vibes here, like you're building the entire page or at least a very large part of it inside a single stringbuilder for output. This is a very bad thing to do.
If you want to "accumlate" your page string like this, you should write to the Response object directly instead. The StringBuilder forces you to keep all that html in memory on your server for every request, and memory use like this on a web server just won't scale well when you have many requests going at once. Even worse, there's a chance of these stringbuilders ending up on the Large Object Heap. If that happens it could ultimately cause OutOfMemoryExceptions. By contrast, the Response object buffers your html as you write it, and so you only use memory per request up to the size of the buffer. That will scale/perform much better.
Even better, though, is if you work with ASP.Net to make this happen rather than against it. That solves both the scaling problem and your "templating" problem. For example, I'll show you a better way to adapt just a small snippet of the html you posted. First write your .aspx markup like this:
<table cellpadding="0" class="TableStyle" style="width: 70%; height: 100%;" cellspacing="5">
<tr>
<td class="PicHolder" style="width: 151px" rowspan="2">
<asp:HyperLink runat="server" ID="TwitterLink" target="_blank">
<asp:Image runat="server" ID="TwitterLinkImage" Height="45px" Width="45px"/>
</asp:HyperLink></td>
...
</tr>
And then use code like this in your .cs code-behind:
TwitterLink.NavigateUrl = "http://twitter.com/" + count.First.userName;
TwitterLinkImage.ImageUrl = count.First.imgURL;
TwitterLinkImage.AlternateText = newdata;
There you go. Clean separation of markup and code/data that's more readable, avoids all the messy escaping, and will perform even better than your stringbuilder. If you have a lot of records that are exactly the same and you still want fine control over your HTML output, use an <asp:Repeater> control and set up markup like this in it's ItemTemplate. Then c# code will go in the repeater's ItemDatabound event.
As with most things there are a number of ways of doing it; from the pure code behind which you have as your original question through to the pure client side / jquery templating.
Another option would be to have a user control with the html part of the output in. This could have an associated property with the data object assigned to it. You could then access the data in the html you would put somethihng like:
<%= MyClass.Property %>
Where ever you want that value to appear in the html.
So what I'd look to do (not tested as don't have VS installed on this machine) is the following:
create a class which will store the data which you will be receiving in json format
Create the user control
Specifiy a property on the control which takes an instance of your class defined above
Add the control onto your aspx page
In the code behind of the aspx page set the retrieval and parsing of the json data in the Page_Load event.
Still in the Page_Load; assign the newly created instance of the object to the usercontrol property
Once this is done when the page renders the user control can access the data and display it through the mechanism (bit of code) above.
Hope this helps, been doing a lot of MVC stuff recently so my Web Forms is a little rusty :-)
If this doesn't make much sense, I appologise in advance and if you let me know I will try and update the post with some more code examples to try and make it make more sense :-)
Perhaps it's better to return the data as json to the browser and there use jqGrid or jQuery template.
Grz, Kris.
This is inline code of a .aspx page:-
<table>
<tr>
<td>Some static data</td>
<td>Text box control</td>
<td><div id="div1"></div></td>
</tr>
</table>
Third <td> has a div 'div1'. This div does not have any data most of time on that page. But sometimes i need to display some dynamic data there). Now problem is, if there is no data in div 'div1', firefox consider it as a space in it and takes approx. 5px space in browser. (But IE8 in compatibility view is fine)
What is the work around here for firefox?
I'd consider if you actually need the div - I guess you are filling it with data in certain circumstances by targetting the ID, by why not just target the table cell instead?
<table>
<tr>
<td>Some static data</td>
<td>Text box control</td>
<td id="div1"></td>
</tr>
</table>
Try setting all margins and padding to 0 at the start of your CSS.
*{
margin: 0;
padding: 0;
}
And then you can set those values explicitly where required.
That's because you have a padding applied to the td elements. You could do this: <td style="padding:0"><div id="div1" style="display:none; padding:1px;"></td>
And shift the padding to the div element and the hide it when it is empty. Firefox doesn't apply any padding to it in that case. But, it should still look like other tds when there is data applied to it.
It sounds like you need to reset your styles. There's a couple of good ones out there including Eric Meyer's CSS reset and Yahoo YUI2 CSS reset.