Solved

function to find and replace all image sources in a string, i have code but some bugs outstanding...

Posted on 2011-03-03
9
470 Views
Last Modified: 2012-05-11
hi all, my code below and the bugs

BUG 1 happens when there is no images in the string
BUG 2 happens with the code in the bottom
#################### BUG 1 #################################
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: startIndex at System.String.IndexOf(String value, Int32 startIndex, Int32 count, StringComparison comparisonType) at System.String.IndexOf(String value, Int32 startIndex, StringComparison comparisonType) at Functions.ExtractImages(String src, String replacement, Int32 counter, Dictionary`2& imageSources) in e:\netfolder\App_Code\functions.cs:line 114 at Documents.SendEmail(Object sender, EventArgs e) in e:\netfolder\documents\documents.aspx.cs:line 333

line 114 is :toIndex = src.IndexOf("/>", fromIndex);
line 333 is the function being run
            htmlBody = Functions.ExtractImages(
                Editor1.XHTML, // The HTML source to have <img> tags replaced
                replacement, // What to replace the src with - the {0} part represents where the number should go - so you could use image{0}.jpg to get image1.jpg, image2.jpg, image3.jpg, etc
                firstNumber, // Start with cid:image1 and go up 1 for each <img> tag
                ref imgSources  // The list of strings that will contain the original sources
            );

##################  BUG 2 ###############################
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: startIndex at System.String.IndexOf(String value, Int32 startIndex, Int32 count, StringComparison comparisonType) at System.String.IndexOf(String value, Int32 startIndex, StringComparison comparisonType) at Functions.ExtractImages(String src, String replacement, Int32 counter, Dictionary`2& imageSources) in e:\netfolder\App_Code\functions.cs:line 114 at Documents.SendEmail(Object sender, EventArgs e) in e:\netfolder\documents\documents.aspx.cs:line 333

Open in new window

##################### FUNCTIONS.cs ########################################
    public static string ExtractImages(string src, string replacement, int counter,
            ref Dictionary<string, string> imageSources)
    {
        int toIndex = 0, fromIndex = 0;

        do
        {
            if (toIndex > src.Length) break;
            fromIndex = src.IndexOf("<img", toIndex);
            toIndex = src.IndexOf("/>", fromIndex);
            string part = src.Substring(fromIndex, toIndex - fromIndex + 2);
            string[] tokens = part.Split(new string[] { "\"" }, System.StringSplitOptions.RemoveEmptyEntries);
            imageSources.Add(tokens[1], string.Format(replacement, counter));
            src = src.Replace(tokens[1], string.Format(replacement, counter++));
        } while (true);
        return src;
    }
################## DOCUMENTS.cs ##################################
Dictionary<string, string> imgSources = new Dictionary<string, string>();
            // Start with cid:image1 and go up 1 for each <img> tag
            int firstNumber = 1;
            // What to replace the src with - the {0} part represents where the number should go - so you could use image{0}.jpg to get image1.jpg, image2.jpg, image3.jpg, etc
            string replacement = "cid:image{0}";
            // Run the SourceTextBox contents through the <img> tag replacer, and assign
            // the results to the DestinationTextBox
            htmlBody = Functions.ExtractImages(
                Editor1.XHTML, // The HTML source to have <img> tags replaced
                replacement, // What to replace the src with - the {0} part represents where the number should go - so you could use image{0}.jpg to get image1.jpg, image2.jpg, image3.jpg, etc
                firstNumber, // Start with cid:image1 and go up 1 for each <img> tag
                ref imgSources  // The list of strings that will contain the original sources
            );
            AlternateView htmlView = AlternateView.CreateAlternateViewFromString(htmlBody, null, "text/html");
            // Now, write the original images and what they were replaced with
            // to a temporary StringBuilder
            foreach (KeyValuePair<string, string> originalSource in imgSources)
            {
                string strImageUrl = System.Web.HttpContext.Current.Server.MapPath(originalSource.Key);
                LinkedResource image = new LinkedResource(strImageUrl);
                image.ContentId = originalSource.Value.ToString().Replace("cid:", "");
                htmlView.LinkedResources.Add(image);
                              
                Editor1.Text += "<br />Key - " + originalSource.Key;
                Editor1.Text += "<br />Value - " + originalSource.Value;
                Editor1.Text += "<br />ImageURL - " + strImageUrl;
                Editor1.Text += "<br />Imagename - " + originalSource.Value.ToString().Replace("cid:", "");

                firstNumber++;
            }

Open in new window

################ BUG 2 String ###########################

<title> News Letter</title>
<div style="background-position: center; background-repeat: no-repeat; font-family: Arial, Helvetica, sans-serif;
font-size: 12px; color: #333333; background-color: #220000; margin: 0px; padding: 0px;" width="100%">
<table width="800" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center">
     <tbody>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/outer_top_left.jpg" alt="bg" />
             </div>
             </td>
             <td width="700">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="50" align="right">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/outer_top_right.jpg" alt="bg" />
             </div>
             </td>
         </tr>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="700">
             <table width="700" border="0" cellspacing="0" cellpadding="0">
                 <tbody>
                     <tr>
                         <td width="300">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/header_cw.jpg" alt="Construction Works Logo" />
                         </div>
                         </td>
                         <td width="400" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <p style="font-size: 10px;">
                         <a href="javascript:;">Click here for printer friendly version</a>
                         </p>
                         </div>
                         <h2 style="color: #990000;">
                         Type Title Here</h2>
                         </td>
                     </tr>
                 </tbody>
             </table>
             </td>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
         </tr>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/spacer.jpg" alt="Spacer" width="50" />
             </div>
             </td>
             <td width="700">
             <table width="700" border="0" cellspacing="0" cellpadding="0" bgcolor="#EEEEEE">
                 <tbody>
                     <tr>
                         <td width="20" valign="top">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/inner_top_left.jpg" alt="bg" />
                         </div>
                         </td>
                         <td width="640" colspan="3" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/shadow2.jpg" align="top" alt="background image 1" />
                         </div>
                         </td>
                         <td width="20" align="right" valign="top">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/inner_top_right.jpg" alt="bg" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="180" bgcolor="#CCCCCC" align="center" valign="top">
                         <table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">
                             <tbody>
                                 <tr>
                                     <td valign="top" align="left">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="/documents/mail_images/images_top_left.jpg" alt="bg" />
                                     </div>
                                     </td>
                                     <td align="center">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="/documents/mail_images/shadow3.jpg" alt="bg" />
                                     </div>
                                     </td>
                                     <td valign="top" align="right">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="/documents/mail_images/images_top_right.jpg" alt="bg" />
                                     </div>
                                     </td>
                                 </tr>
                                 <tr>
                                     <td>
                                     <div unselectable="ON" contenteditable="false">&nbsp;</div>
                                     </td>
                                     <td align="center">
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="/documents/mail_images/image1.jpg" alt="bg" />
                                     </span>
                                     </p>
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="/documents/mail_images/image2.jpg" alt="" />
                                     </span>
                                     </p>
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="/documents/mail_images/image3.jpg" alt="" />
                                     </span>
                                     </p>
                                     </td>
                                     <td>
                                     <div unselectable="ON" contenteditable="false">&nbsp;</div>
                                     </td>
                                 </tr>
                             </tbody>
                         </table>
                         </td>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="440">
                         Type Content Here
                         </td>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                     </tr>
                     <tr>
                     </tr>
                     <tr>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/inner_bot_left.jpg" alt="" />
                         </div>
                         </td>
                         <td width="660" colspan="3" align="center">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="20" align="right">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/inner_bot_right.jpg" alt="" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td colspan="5" bgcolor="#FFFFFF" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <img src="/documents/mail_images/shadow.jpg" align="top" alt="background image 2" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td colspan="5" bgcolor="#FFFFFF">
                         <div unselectable="ON" contenteditable="false">
                         <table width="700" border="0" cellspacing="0" cellpadding="0">
                             <tbody>
                                 <tr>
                                     <td width="340" align="right" valign="top">
                                     </td>
                                 </tr>
                             </tbody>
                         </table>
                         </div>
                         </td>
                     </tr>
                 </tbody>
             </table>
             </td>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/spacer.jpg" alt="Spacer" width="50" />
             </div>
             </td>
         </tr>
         <tr>
             <td width="50" align="left" valign="bottom">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/outer_bot_left.jpg" alt="" />
             </div>
             </td>
             <td width="700">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="50" align="right" valign="bottom">
             <div unselectable="ON" contenteditable="false">
             <img src="/documents/mail_images/outer_bot_right.jpg" alt="" />
             </div>
             </td>
         </tr>
     </tbody>
</table>
</div>

Open in new window

0
Comment
Question by:awilderbeast
  • 4
  • 4
9 Comments
 
LVL 42

Assisted Solution

by:sedgwick
sedgwick earned 125 total points
ID: 35027337
try this:
public static string ExtractImages(string src, string replacement, int counter, 
            ref Dictionary<string, string> imageSources)
        {
            int toIndex = 0, fromIndex = 0;

            do
            {
                if (toIndex > src.Length) break;
                fromIndex = src.IndexOf("<img", toIndex);
                if (fromIndex == -1) break;
                toIndex = src.IndexOf("/>", fromIndex);
                string part = src.Substring(fromIndex, toIndex - fromIndex + 2);
                string[] tokens = part.Split(new string[] { "\"" }, System.StringSplitOptions.RemoveEmptyEntries);
                imageSources.Add(tokens[1], string.Format(replacement, counter));
                src = src.Replace(tokens[1], string.Format(replacement, counter++));
            } while (true);
            return src;
        }

Open in new window

0
 
LVL 1

Author Comment

by:awilderbeast
ID: 35027514
thanks thats sorted bug one

bug two has now changed to the below

which i actuall dont think is to do with the mentioned functions

new bug line 344 is
string strImageUrl = System.Web.HttpContext.Current.Server.MapPath(originalSource.Key);

and if you look at the ouputs that i return the key isnt cid:image4 it has s path
i dont understand how this new error is even occuring, perhaps you can shed some light?

Thanks
#################### NEW BUG CODE ########################
            foreach (KeyValuePair<string, string> originalSource in imgSources)
            {
                string strImageUrl = System.Web.HttpContext.Current.Server.MapPath(originalSource.Key);
                LinkedResource image = new LinkedResource(strImageUrl);
                image.ContentId = originalSource.Value.ToString().Replace("cid:", "");
                htmlView.LinkedResources.Add(image);
                              
                Editor1.Text += "<br />Key - " + originalSource.Key;
                Editor1.Text += "<br />Value - " + originalSource.Value;
                Editor1.Text += "<br />ImageURL - " + strImageUrl;
                Editor1.Text += "<br />Imagename - " + originalSource.Value.ToString().Replace("cid:", "");

                firstNumber++;
            }

Open in new window

System.Web.HttpException (0x80004005): 'cid:image4' is not a valid virtual path. at System.Web.Util.UrlPath.CheckValidVirtualPath(String path) at System.Web.Util.UrlPath.Combine(String appPath, String basepath, String relative) at System.Web.VirtualPath.Combine(VirtualPath relativePath) at System.Web.HttpRequest.MapPath(VirtualPath virtualPath, VirtualPath baseVirtualDir, Boolean allowCrossAppMapping) at System.Web.HttpServerUtility.MapPath(String path) at Documents.SendEmail(Object sender, EventArgs e) in e:\netfolder\documents\documents.aspx.cs:line 344

Open in new window

############################ OUTPUTS ##############################
Key - /documents/mail_images/outer_top_left.jpg
Value - cid:image1
ImageURL - E:\netfolder\documents\mail_images\outer_top_left.jpg
Imagename - image1
Key - /documents/mail_images/outer_top_right.jpg
Value - cid:image2
ImageURL - E:\netfolder\documents\mail_images\outer_top_right.jpg
Imagename - image2
Key - /documents/mail_images/header_cw.jpg
Value - cid:image3
ImageURL - E:\netfolder\documents\mail_images\header_cw.jpg
Imagename - image3
Key - /documents/mail_images/spacer.jpg
Value - cid:image4
ImageURL - E:\netfolder\documents\mail_images\spacer.jpg
Imagename - image4
Key - /documents/mail_images/inner_top_left.jpg
Value - cid:image5
ImageURL - E:\netfolder\documents\mail_images\inner_top_left.jpg
Imagename - image5
Key - /documents/mail_images/shadow2.jpg
Value - cid:image6
ImageURL - E:\netfolder\documents\mail_images\shadow2.jpg
Imagename - image6
Key - /documents/mail_images/inner_top_right.jpg
Value - cid:image7
ImageURL - E:\netfolder\documents\mail_images\inner_top_right.jpg
Imagename - image7
Key - /documents/mail_images/images_top_left.jpg
Value - cid:image8
ImageURL - E:\netfolder\documents\mail_images\images_top_left.jpg
Imagename - image8
Key - /documents/mail_images/shadow3.jpg
Value - cid:image9
ImageURL - E:\netfolder\documents\mail_images\shadow3.jpg
Imagename - image9
Key - /documents/mail_images/images_top_right.jpg
Value - cid:image10
ImageURL - E:\netfolder\documents\mail_images\images_top_right.jpg
Imagename - image10
Key - /documents/mail_images/image1.jpg
Value - cid:image11
ImageURL - E:\netfolder\documents\mail_images\image1.jpg
Imagename - image11
Key - /documents/mail_images/image2.jpg
Value - cid:image12
ImageURL - E:\netfolder\documents\mail_images\image2.jpg
Imagename - image12
Key - /documents/mail_images/image3.jpg
Value - cid:image13
ImageURL - E:\netfolder\documents\mail_images\image3.jpg
Imagename - image13
Key - /documents/mail_images/inner_bot_left.jpg
Value - cid:image14
ImageURL - E:\netfolder\documents\mail_images\inner_bot_left.jpg
Imagename - image14
Key - /documents/mail_images/inner_bot_right.jpg
Value - cid:image15
ImageURL - E:\netfolder\documents\mail_images\inner_bot_right.jpg
Imagename - image15
Key - /documents/mail_images/shadow.jpg
Value - cid:image16
ImageURL - E:\netfolder\documents\mail_images\shadow.jpg
Imagename - image16

Open in new window

0
 
LVL 33

Assisted Solution

by:Todd Gerbert
Todd Gerbert earned 375 total points
ID: 35028504
The RegEx method works, I probably just made a copy/paste error when I posted it.  Using your "BUG 2" string above, I get these results with the RegEx method:

################ BUG 2 String ###########################

<title> News Letter</title>
<div style="background-position: center; background-repeat: no-repeat; font-family: Arial, Helvetica, sans-serif;
font-size: 12px; color: #333333; background-color: #220000; margin: 0px; padding: 0px;" width="100%">
<table width="800" border="0" cellspacing="0" cellpadding="0" bgcolor="#FFFFFF" align="center">
     <tbody>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image1" alt="bg" />
             </div>
             </td>
             <td width="700">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="50" align="right">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image2" alt="bg" />
             </div>
             </td>
         </tr>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="700">
             <table width="700" border="0" cellspacing="0" cellpadding="0">
                 <tbody>
                     <tr>
                         <td width="300">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image3" alt="Construction Works Logo" />
                         </div>
                         </td>
                         <td width="400" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <p style="font-size: 10px;">
                         <a href="javascript:;">Click here for printer friendly version</a>
                         </p>
                         </div>
                         <h2 style="color: #990000;">
                         Type Title Here</h2>
                         </td>
                     </tr>
                 </tbody>
             </table>
             </td>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
         </tr>
         <tr>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image4" alt="Spacer" width="50" />
             </div>
             </td>
             <td width="700">
             <table width="700" border="0" cellspacing="0" cellpadding="0" bgcolor="#EEEEEE">
                 <tbody>
                     <tr>
                         <td width="20" valign="top">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image5" alt="bg" />
                         </div>
                         </td>
                         <td width="640" colspan="3" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image6" align="top" alt="background image 1" />
                         </div>
                         </td>
                         <td width="20" align="right" valign="top">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image7" alt="bg" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="180" bgcolor="#CCCCCC" align="center" valign="top">
                         <table width="100%" height="100%" border="0" cellspacing="0" cellpadding="0">
                             <tbody>
                                 <tr>
                                     <td valign="top" align="left">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="cid:image8" alt="bg" />
                                     </div>
                                     </td>
                                     <td align="center">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="cid:image9" alt="bg" />
                                     </div>
                                     </td>
                                     <td valign="top" align="right">
                                     <div unselectable="ON" contenteditable="false">
                                     <img src="cid:image10" alt="bg" />
                                     </div>
                                     </td>
                                 </tr>
                                 <tr>
                                     <td>
                                     <div unselectable="ON" contenteditable="false">&nbsp;</div>
                                     </td>
                                     <td align="center">
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="cid:image11" alt="bg" />
                                     </span>
                                     </p>
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="cid:image12" alt="" />
                                     </span>
                                     </p>
                                     <p>
                                     <span style="border: 1px solid #666666;">
                                     <img src="cid:image13" alt="" />
                                     </span>
                                     </p>
                                     </td>
                                     <td>
                                     <div unselectable="ON" contenteditable="false">&nbsp;</div>
                                     </td>
                                 </tr>
                             </tbody>
                         </table>
                         </td>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="440">
                         Type Content Here
                         </td>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                     </tr>
                     <tr>
                     </tr>
                     <tr>
                         <td width="20">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image14" alt="" />
                         </div>
                         </td>
                         <td width="660" colspan="3" align="center">
                         <div unselectable="ON" contenteditable="false">
                         &nbsp;</div>
                         </td>
                         <td width="20" align="right">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image15" alt="" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td colspan="5" bgcolor="#FFFFFF" align="center">
                         <div unselectable="ON" contenteditable="false">
                         <img src="cid:image16" align="top" alt="background image 2" />
                         </div>
                         </td>
                     </tr>
                     <tr>
                         <td colspan="5" bgcolor="#FFFFFF">
                         <div unselectable="ON" contenteditable="false">
                         <table width="700" border="0" cellspacing="0" cellpadding="0">
                             <tbody>
                                 <tr>
                                     <td width="340" align="right" valign="top">
                                     </td>
                                 </tr>
                             </tbody>
                         </table>
                         </div>
                         </td>
                     </tr>
                 </tbody>
             </table>
             </td>
             <td width="50">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image17" alt="Spacer" width="50" />
             </div>
             </td>
         </tr>
         <tr>
             <td width="50" align="left" valign="bottom">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image18" alt="" />
             </div>
             </td>
             <td width="700">
             <div unselectable="ON" contenteditable="false">
             &nbsp;</div>
             </td>
             <td width="50" align="right" valign="bottom">
             <div unselectable="ON" contenteditable="false">
             <img src="cid:image19" alt="" />
             </div>
             </td>
         </tr>
     </tbody>
</table>
</div>

Open in new window

/documents/mail_images/outer_top_left.jpg => cid:image1
/documents/mail_images/outer_top_right.jpg => cid:image2
/documents/mail_images/header_cw.jpg => cid:image3
/documents/mail_images/spacer.jpg => cid:image4
/documents/mail_images/inner_top_left.jpg => cid:image5
/documents/mail_images/shadow2.jpg => cid:image6
/documents/mail_images/inner_top_right.jpg => cid:image7
/documents/mail_images/images_top_left.jpg => cid:image8
/documents/mail_images/shadow3.jpg => cid:image9
/documents/mail_images/images_top_right.jpg => cid:image10
/documents/mail_images/image1.jpg => cid:image11
/documents/mail_images/image2.jpg => cid:image12
/documents/mail_images/image3.jpg => cid:image13
/documents/mail_images/inner_bot_left.jpg => cid:image14
/documents/mail_images/inner_bot_right.jpg => cid:image15
/documents/mail_images/shadow.jpg => cid:image16
/documents/mail_images/spacer.jpg => cid:image17
/documents/mail_images/outer_bot_left.jpg => cid:image18
/documents/mail_images/outer_bot_right.jpg => cid:image19

Open in new window


This is the code I used (tweaking it to fit your project should be C# 101):
using System;
using System.Collections.Generic;
using System.Web;
using System.Text.RegularExpressions;

public class ImgTagReplacer
{
	private static Regex regex = new Regex(@"<img\s+[^>]*src\s*=\s*('|"")(.*?)('|"")[^>]*/>", RegexOptions.Compiled | RegexOptions.IgnoreCase);

	public static string ReplaceImgTags(string SourceHtml, string ReplacementFormat, int FirstNumber, List<string> OriginalImageSources)
	{
		try
		{
			String.Format(ReplacementFormat, FirstNumber);
		}
		catch (ArgumentNullException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}
		catch (FormatException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}

		int counter = FirstNumber - 1;
		return regex.Replace(SourceHtml, delegate(Match m)
		{
			counter++;
			if (OriginalImageSources != null)
				OriginalImageSources.Add(m.Groups[2].Value);
			return m.Value.Replace(m.Groups[2].Value, String.Format(ReplacementFormat, counter)); 
		});
	}
}

Open in new window


I'll try and add some comments to the code to explain how it works in a few minutes.
0
 
LVL 1

Author Comment

by:awilderbeast
ID: 35028583
hey tgerbert the code you jsut posted, i never got it to work with a dictionary, i didnt know how to split the m.groups[2].value up
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 35029312
If put breakpoints in your code you can step through it a line at a time, and just hover the mouse over variables to see their values - m.Groups[2].Value just has "/original/path/to/picture.jpg" in it, you wouldn't want to split it up.

Also, it's important to consult documentation - you can go to http://msdn.microsoft.com/library and  lookup things like String.Format(), Regex.Replace(), delegate keyword, etc.

This is a little verbose, I hope it makes sense, I'm not really getting where you're stuck and where you're good so I just tried to cover all the bases.

DON'T COPY & PASTE THIS CODE - UNDERSTAND IT'S CONCEPTS AND RE-APPLY THEM (do copy/paste the regular expression though, they're such a pain to get right).

using System;
using System.Collections.Generic;
using System.Web;
using System.Text.RegularExpressions;

public class ImgTagReplacer
{
	// This regular expression looks for and matches an <img /> tag: <img\s+[^>]*src\s*=\s*('|"")(.*?)('|"")[^>]*/>
	// The parts in parentheses are rememberd as "Groups", and the first
	// group starts and 0 and is always the entire match - group 1 is
	// the part of the match inside the first set of parentheses, group 2
	// is the second set of parentheses, etc.  In our particular case
	// the second set of parentheses represents the path to the image, e.g. /images/picture.jpg,
	// so if the regular expression matches we can then get the original
	// path from the ".Groups[2].Value" of the match

	// This Regex object is declared at the class-level as a static, this way we only ever use
	// one Regex object (as opposed to creating a new Regex everytime the ReplaceImgTags() method
	// is called) - and this regex is marked with the "Compiled" option which improves performance
	private static Regex regex = new Regex(@"<img\s+[^>]*src\s*=\s*('|"")(.*?)('|"")[^>]*/>", RegexOptions.Compiled | RegexOptions.IgnoreCase);

	public static string ReplaceImgTags(string SourceHtml, string ReplacementFormat, int FirstNumber, List<string> OriginalImageSources)
	{
		// The "ReplacementFormat" is expected to look like "cid:image{0}",
		// where {0} will be replaced by a number, so you'd end up with "cid:image1", "cid:image2", etc.
		// If instead ReplacementFormat was "{0}cid:image" you'd end up with "1cid:image", "2cid:image", etc.
		// See how "{0}" is really just a place-holder for where the number goes? This is kinda how
		// String.Format() and related methods work (in fact, later on String.Format() will be used
		// to achieve the desired result).
		// This try/catch block just checks to make sure ReplacementFormat is non-null and contains
		// AT LEAST {0} (if it doesn't contain "{0}" somewhere, String.Format() will throw a fit later)
		try
		{
			String.Format(ReplacementFormat, FirstNumber);
		}
		catch (ArgumentNullException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}
		catch (FormatException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}

		// The FirstNumber parameter lets you start the numbering at whatever number you want
		// So you could START at cid:image17 if you needed to for some reason.
		// The little section of code starting on the "counter++" line will be called for each
		// match (i.e. for each <img /> tag), and since the first line of that code block
		// is counter++, we initially need counter to start off at 1 less than FirstNumber,
		// so that the first time the code section runs it gets incremented to the FirstNumber
		int counter = FirstNumber - 1;

		// The regex.Replace method as used here expects two parameters.
		// The first is the SourceHtml string we're searching for <img /> tags.
		// The second parameter is a method - but instead of actually writing
		// a separate method in this class and just giving that method's name as the parameter,
		// the CONTENTS of that method IS the second parameter - which is done with the "delegate"
		// keyword and is known as an anonymous method (since it is in fact a method without a name)

		// regex.Replace is going to search SourceHtml for every occurence of
		// a sequence of characters that matches the regular expression we defined
		// on line 20 - which means in this case it's going to search SourceHtml
		// for each <img ... /> tag.  Then it's going to replace that <img ... /> tag
		// with whatever is returned by the "embedded" method
		return regex.Replace(SourceHtml, delegate(Match m)
		{
			// Start of "embedded" method (aka Anonymous Method)
			// m is a parameter passed into our function by regex.Replace, it is a "Match" object that
			// contains details about the piece of SourceHtml that matched the expression (i.e. our <img ... /> tag)

			counter++; // Increment the counter (self explanatory)

			// OriginalImageSources is a List<string> (a list of strings) that may or may not have been passed
			// into our ReplaceImgTags method
			if (OriginalImageSources != null)
			{
				// If it is non-null add to the string list 
				OriginalImageSources.Add(m.Groups[2].Value);
			}
			return m.Value.Replace(m.Groups[2].Value, String.Format(ReplacementFormat, counter)); // end of embedded/anonymous method
		});
	}
}

Open in new window

0
 
LVL 1

Author Comment

by:awilderbeast
ID: 35029478
ok im begining to understand it and im giong to read your comments a few more times (like 20) see if i can get it to sink in

but at the mo  that big string that ive inserted above, i just tried it again and got the below error
System.ArgumentException: An item with the same key has already been added. at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) at Functions.<>c__DisplayClass1.b__0(Match m) in e:\netfolder\App_Code\functions.cs:line 98 at System.Text.RegularExpressions.RegexReplacement.Replace(MatchEvaluator evaluator, Regex regex, String input, Int32 count, Int32 startat) at System.Text.RegularExpressions.Regex.Replace(String input, MatchEvaluator evaluator) at Functions.ReplaceImgTags(String SourceHtml, String ReplacementFormat, Int32 FirstNumber, Dictionary`2 imageSources) in e:\netfolder\App_Code\functions.cs:line 94 at Documents.SendEmail(Object sender, EventArgs e) in e:\netfolder\documents\documents.aspx.cs:line 333

Open in new window

0
 
LVL 33

Assisted Solution

by:Todd Gerbert
Todd Gerbert earned 375 total points
ID: 35029796
Rather than trying to throw together a bunch of code you're not really comfortable with yet, try and get a handle on the different pieces.  You can find information on the Dictionary<TKey,TValue> at http://msdn.microsoft.com/en-us/library/xfhwa508.aspx, and I would create a simple console application just to experiment with it.

That error you're getting is pretty straight-forward: each key used in the dictionary must be unique.
// This fails
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("John", "firstName");
dict.Add("John", "middleName");

Open in new window

// This works
Dictionary<string, string> dict = new Dictionary<string, string>();
dict.Add("firstName", "John");
dict.Add("middleName", "John");

Open in new window


Make sense?
0
 
LVL 33

Accepted Solution

by:
Todd Gerbert earned 375 total points
ID: 35029868
I seem to be copy & paste impaired - I left off some comments/details in my post above, it should have been this:

using System;
using System.Collections.Generic;
using System.Web;
using System.Text.RegularExpressions;

public class ImgTagReplacer
{
	// This regular expression looks for and matches an <img /> tag: <img\s+[^>]*src\s*=\s*('|")(.*?)('|")[^>]*/>
	// The parts in parentheses are rememberd as "Groups", and the first
	// group starts and 0 and is always the entire match - group 1 is
	// the part of the match inside the first set of parentheses, group 2
	// is the second set of parentheses, etc.  In our particular case
	// the second set of parentheses represents the path to the image, e.g. /images/picture.jpg,
	// so if the regular expression matches we can then get the original
	// path from the ".Groups[2].Value" of the match

	// This Regex object is declared at the class-level as a static, this way we only ever use
	// one Regex object (as opposed to creating a new Regex everytime the ReplaceImgTags() method
	// is called) - and this regex is marked with the "Compiled" option which improves performance
	private static Regex regex = new Regex(@"<img\s+[^>]*src\s*=\s*('|"")(.*?)('|"")[^>]*/>", RegexOptions.Compiled | RegexOptions.IgnoreCase);

	public static string ReplaceImgTags(string SourceHtml, string ReplacementFormat, int FirstNumber, List<string> OriginalImageSources)
	{
		// The "ReplacementFormat" is expected to look like "cid:image{0}",
		// where {0} will be replaced by a number, so you'd end up with "cid:image1", "cid:image2", etc.
		// If instead ReplacementFormat was "{0}cid:image" you'd end up with "1cid:image", "2cid:image", etc.
		// See how "{0}" is really just a place-holder for where the number goes? This is kinda how
		// String.Format() and related methods work (in fact, later on String.Format() will be used
		// to achieve the desired result).
		// This try/catch block just checks to make sure ReplacementFormat is non-null and contains
		// AT LEAST {0} (if it doesn't contain "{0}" somewhere, String.Format() will throw a fit later)
		try
		{
			String.Format(ReplacementFormat, FirstNumber);
		}
		catch (ArgumentNullException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}
		catch (FormatException)
		{
			throw new ArgumentException(
				"ReplacementFormat should contain the string to serve as the replacement for the <img> source; it MUST contain at least \"{0}\", to indicate where the number occurs in the replacement.",
				"ReplacementFormat");
		}

		// The FirstNumber parameter lets you start the numbering at whatever number you want
		// So you could START at cid:image17 if you needed to for some reason.
		// The little section of code starting on the "counter++" line will be called for each
		// match (i.e. for each <img /> tag), and since the first line of that code block
		// is counter++, we initially need counter to start off at 1 less than FirstNumber,
		// so that the first time the code section runs it gets incremented to the FirstNumber
		int counter = FirstNumber - 1;

		// The regex.Replace method as used here expects two parameters.
		// The first is the SourceHtml string we're searching for <img /> tags.
		// The second parameter is a method - but instead of actually writing
		// a separate method in this class and just giving that method's name as the parameter,
		// the CONTENTS of that method IS the second parameter - which is done with the "delegate"
		// keyword and is known as an anonymous method (since it is in fact a method without a name)

		// regex.Replace is going to search SourceHtml for every occurence of
		// a sequence of characters that matches the regular expression we defined
		// on line 20 - which means in this case it's going to search SourceHtml
		// for each <img ... /> tag.  Then it's going to replace that <img ... /> tag
		// with whatever is returned by the "embedded" method
		return regex.Replace(SourceHtml, delegate(Match m)
		{
			// Start of "embedded" method (aka Anonymous Method)
			// m is a parameter passed into our function by regex.Replace, it is a "Match" object that
			// contains details about the piece of SourceHtml that matched the expression - m will
			// effectively represent the <img /> tag and the pieces we chose to remember with 
			// parentheses in the regular expression

			counter++; // Increment the counter (self explanatory)

			// String.Format is going to find {0} inside the ReplacementFOrmat string
			// and replace it with whatever the value of counter is. e.g. if
			// ReplacementFormat is "cid:image{0}" then replacementText is going to be
			// "cid:image1" for the first <img /> tag, "cid:image2" for the second <img /> tag, etc.
			string replacementText = String.Format(ReplacementFormat, counter);

			string originalImgTag = m.Value; // This is the entire <img src=/blah/blah.jpg height="200" ... /> tag

			// This is just the /blah/blah.jpg part (remember the second set of parentheses in our regular expression
			// corresponds to this part of the <img> tag)
			string originalImgSrc = m.Groups[2].Value;

			// OriginalImageSources is a List<string> (a list of strings) that may or may not have been passed
			// into our ReplaceImgTags method
			if (OriginalImageSources != null)
			{
				// If it is non-null add to the string list the original url
				OriginalImageSources.Add(originalImgSrc);

				// If you wanted to use a Dictionary<string,string> instead of a list, and make the key
				// of the dictionary equal to the replacementText and the value equal to you could write
				// theDictionary.Add(replacementText, originalImgSrc);
				// And then outside of this method could write something like
				// textBox1.Text = theDictionary["cid:image1"];
				// in order to put "/images/pic.jpg" in the text box
			}

			// Search the original <img /> tag for the original img src, and replace
			// it with our new img src - so if the originalImgTag is "<img src='/blah/blah.jpg' height='200' />"
			// then originalImgSrc will be "/blah/blah.jpg", and if you replace "/blah/blah.jpg" with
			// "cid:image1", then newImgTag will end up being "<img src='cid:image1' height='200' />"
			string newImgTag = originalImgTag.Replace(originalImgSrc, replacementText);

			// Return the new <img /> tag to regex.Replace
			return newImgTag; // end of embedded/anonymous method
		});
	}
}

Open in new window

0
 
LVL 1

Author Closing Comment

by:awilderbeast
ID: 35034908
thanks alot!
begining to understand this now, ive saved the sample to study as i set up my test windows application

thanks again!

if youve got the time bert can you show me what you mean by updating the linq using a dictionary in this post
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_26858845.html

ive googled linq and updating with dictionary and i get nothing

thanks
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
Wouldn’t it be nice if you could test whether an element is contained in an array by using a Contains method just like the one available on List objects? Wouldn’t it be good if you could write code like this? (CODE) In .NET 3.5, this is possible…
This video discusses moving either the default database or any database to a new volume.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now