There may be occasions where you want to allow an app to download content, perhaps modify it, and store it for later viewing. Fortunately the WebBrowser
has built-in capability for browsing offline content located in isolated storage. There is, however, no automatic way to store such content. It is your responsibility to place whatever content needs to be available for offline browsing in isolated storage.
Caution
Content loaded from the network has cross-site restrictions, which ordinarily prevent a web page from communicating with sites other than its site-of-origin. Content loaded from isolated storage, or by using the NavigateToString
method, however, has no such restrictions on cross-site access. Therefore, be mindful of unwittingly compromising the privacy of your users.
The example for this section looks at storing a web page and a referenced image in isolated storage and then directing a WebBrowser
to read the content directly from isolated storage. The sample code for this section is located in the WebBrowserIsolatedStorageView
page, in the downloadable sample code.
The OnNavigatedTo
method of the WebBrowserIsolatedStorageView
saves some example content to isolated storage. After the content has been stored, the WebBrowser
’s Base
property is assigned to the isolated storage directory containing the web page; this is then used by the WebBrowser
to locate HTML content (see Listing 7.9).
The Base
property should point to an isolated storage directory and is used by the WebBrowser
to resolve relative references. This includes the Uri Source
property and references to images within the HTML document.
public partial class WebBrowserIsolatedStorageView : PhoneApplicationPage
{
public WebBrowserIsolatedStorageView()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
SaveHtmlToIsolatedStorage();
webBrowser.Base = "WebContent";
webBrowser.Source = new Uri(@"Webpage.html", UriKind.Relative);
}
...
}
When the WebBrowser
attempts to load the URL Webpage.html, it uses the base directory of WebContent
to load all relative content (see Figure 7.18).
Saving the web page and the image to isolated storage is done by retrieving the IsolatedStorageFile
for the app and creating a directory called WebContent in which the content is placed. A simple document is written to a file in the directory, as shown in Listing 7.10.
void SaveHtmlToIsolatedStorage()
{
using (IsolatedStorageFile isolatedStorageFile
= IsolatedStorageFile.GetUserStoreForApplication())
{
if (!isolatedStorageFile.DirectoryExists("WebContent"))
{
isolatedStorageFile.CreateDirectory("WebContent");
}
using (IsolatedStorageFileStream isolatedStorageFileStream
= isolatedStorageFile.OpenFile(
@"WebContentWebpage.html", FileMode.Create))
{
using (StreamWriter streamWriter
= new StreamWriter(isolatedStorageFileStream))
{
streamWriter.Write(@"<html><head></head><body>
<h2>Stored in Isolated Storage</h2>
<p><img src=""Images/Book.jpg"" /></p>
</body></html>");
}
}
if (!isolatedStorageFile.DirectoryExists("WebContent/Images"))
{
isolatedStorageFile.CreateDirectory("WebContent/Images");
}
StreamResourceInfo resourceInfo = Application.GetResourceStream(
new Uri("WebBrowser/ImagePlacedInIsolatedStorage"
+ "/WP7Unleashed200x.jpg",
UriKind.Relative));
using (IsolatedStorageFileStream writeStream
= new IsolatedStorageFileStream(
@"WebContent/Images/Book.jpg",
FileMode.Create, isolatedStorageFile))
{
CopyStreamBytes(resourceInfo.Stream, writeStream);
}
}
}
The image, which is referenced by the img
element in the HTML document, is a project item with its build action set to Content. This image file is first opened using the static method GetResourceStream
of the Application
class. It is then converted to a byte array and saved in isolated storage. For the sake of completeness, the Stream
related methods are shown in Listing 7.11.
void CopyStreamBytes(
Stream fromStream, Stream toStream, bool closeToStream = true)
{
if (toStream.CanWrite)
{
byte[] fileBytes = ReadStreamBytes(fromStream);
toStream.Write(fileBytes, 0, fileBytes.Length);
if (closeToStream)
{
toStream.Close();
}
}
}
byte[] ReadStreamBytes(Stream fileStream)
{
/* Read the source file into a byte array. */
byte[] bytes = new byte[fileStream.Length];
int readLength = (int)fileStream.Length;
int bytesRead = 0;
while (readLength > 0)
{
/* Read may return anything from 0 to readLength. */
int read = fileStream.Read(bytes, bytesRead, readLength);
/* When no bytes left to read it is the end of the file. */
if (read == 0)
{
break;
}
bytesRead += read;
readLength -= read;
}
return bytes;
}
3.17.81.201