Category Archives: Windows Store App

Windows.Web.HttpClient and it’s PasswordCredential class

Microsoft is changing the Api to get HTTP content from version to version. Also the type of possible authentication mechanism behind is changing all the time. So in Universal App for Windows 10, Windows Phone or Windows Store 8 or 8.1. the underlying platform for HTTP access is different in several areas.

System.Net.HttpClient

The System.Net.HttpClient from NuGet that is using the different underlying platforms and therefore is making the same problems. To not being totally confused, it is better not to use System.Net and always use the underlying platform directly instead

Windows.Web.HttpClient or HttpWebRequest

It is better to use one these clients.

  • Windows Phone 8: HttpWebRequest
  • Windows 10 and 8.1 should use Windows.Web.HttpClient

Known problems and bugs in Windows.Web.HttpClient or the old HttpWebRequest:

There are some known bugs available but for a lot of them there are work arounds you can use:

If you have any problems by using the included authentication methods (for example: PasswordCredential) you “just” need to do the authentication by your self creating and adding specific request headers.

Hereinafter is a sample showing how these header entries must be used if you need Digest authentication. The sample uses the old HttpWebRequest but you can rewrite the sample to use Windows.Web.HttpClient easily.

DigestFixer

 

Advertisements

Code Reuse Analysis: Portable Libraries for Windows 8 and Windows Phone 8

I have written apps for both systems – Windows 8 and Windows Phone 8 by using portable class library to share and reuse code. Some people like to know how much synergy you will get while developing apps the two systems.

Analysis key figures

Project

Part of the analysis is a single project.

Features

The Windows 8 app and the Windows Phone 8 app are having about 80 percent of features in common. Round about 20 percent are specific features that are unique to one platform.

Architecture

The project is done by using MVVM pattern. Models, View-Models and Services are part of portable libaries. While the views, all the UI stuff and the background tasks (agents) are part of the platform libraries.

Views

In the Windows 8 app there are 10 views and 7 views in the Windows Phone 8 app.

Analysis Results

I think the best way it to compare the lines of code of the projects. I’m using the Code Metrics feature in Visual Studio to find out the values. So please be aware, that XAML is not part of the analysis.

All Lines of Code: 4887 = 100%

  • Portable Class Library: 2580 = 53%
  • Windows 8 and Windows Phone 8: 2307 = 47%
    • Windows 8: 866  = 17%
    • Windows Phone 8: 1100 = 22%

As you can see, in my project I was able reuse about 50% of the whole code by using portable class libaries.

Localhost connection fails in Unit Test Project

Windows 8 Store apps are not allowed to connect to localhost using any network connection type like a simple http request. For developers Visual Studio 2012 automatically exempts your Windows Store App projects by putting them into the right isolation level, but for your Unit Test projects Visual Studio does not do the same. So, to connect to localhost – or just if you are using Fiddler – in your Unit Test project , you have to manually put them in to the “exception list”.

Open a command line window and check, if your Unit Test project is in the correct isolation level.

CheckNetIsolation Loopbackexempt -s

Add your Unit Test project to the list

CheckNetIsolation Loopbackexempt -a -n=<package familiy name>

You can find your “package familiy name” in the “package.appmanifest” file of your Unit Test project in the Packaging tab.

PortiLog – Logging for Portable Class Libraries

The first version of PortiLog is available now. It is a small but simple library to write and monitor app log files. Windows 8 Store Apps and Windows Phone 8 Apps are supported.

https://portilog.wordpress.com/

Documentation and Samples here…

https://portilog.wordpress.com/getting-started/

Ignore SSL Certificate Errors In Windows 8.1 Apps

With Windows 8.1 it will be possible for app developers to ignore SSL certificate errors that will occur if you are using self-signed certificates for example. The new built-in HttpClient API supports ignoring such errors.

The source will look like this…


var filter = new HttpBaseProtocolFilter();
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult....)
var httpClient = new HttpClient(filter);
...

More about the topic can be found here…

http://msdn.microsoft.com/en-us/library/windows/apps/windows.web.http.filters.httpbaseprotocolfilter.ignorableservercertificateerrors.aspx

http://msdn.microsoft.com/en-us/library/windows/apps/windows.security.cryptography.certificates.chainvalidationresult.aspx

What’s about Window 8.0, Windows Phone 7 and 8

For earlier versions of Windows you need to install the SSL certificate to the device in order to trust the site. More information can be found here….

http://social.msdn.microsoft.com/Forums/windowsapps/en-US/b6887fa1-1b29-4747-a0f3-573e77cd10ea/can-i-tell-windows-8-apps-to-ignore-security-certificate-errors

Create a Non-Expiring Test Certificate (pfx) for Windows Store Apps

With the following command line you can create a non-expiring self-signed test certificate that can be used in Windows Store apps.

Start the Developer Command Prompt

MakeCert /n "CN=YourCompany" /r /h 0 /eku "1.3.6.1.5.5.7.3.3,1.3.6.1.4.1.311.10.3.13" /e "12/31/2100" /sv YourCompany.pvk YourCompany.cer
pvk2pfx -pvk YourCompany.pvk -spc YourCompany.cer -pfx YourCompany.pfx -f

How To Write Log Files in Windows Store Apps

Update: I published my own libary here… https://portilog.wordpress.com/

I was searching for a good and simple logging solution to use it my current Windows 8 project. A solution that just writes a simple log file. I found nothing really appropriate, so I’m using my own solution provided here.

PortiLog (NEW)

Because the Microsoft Solution including the sample here was too simple for my final needs I created my own solution.

https://portilog.wordpress.com/

Getting Started Link

https://portilog.wordpress.com/getting-started/

PortiLog supports Portable Class Libraries (Windows 8 and Windows Phone 8), is able to write simple log files and can send log data to a service to watch Windows Phone 8 and Windows 8 App logging on your developer machine.

MetroLog

https://github.com/mbrit/MetroLog

Seems to be a good one. I have not tried it yet. But for Windows Store Apps it is recommended to use SQlite as target. I dislike that.

Microsoft Logging Sample for Windows Store Apps

http://code.msdn.microsoft.com/windowsapps/Logging-Sample-for-Windows-0b9dffd7

This was exactly what I want. Just a few classes and no additional libraries. My solution bases on this sample. I just replaced the EventListener implementation with the one presented here.

Problems with the Microsoft Logging Sample

I came across several problems by using the solution from Microsoft
1. Log entries might be in the wrong order as a result of of the asynchronous file access.
2. Log entries might be lost, if they are written during background tasks
3. Log entries might be lost under heavy logging conditions

Solution

My solution is working fine in all scenarios. I’m buffering the log entries and write them only once after a delay of 500 milliseconds. The performance is great, the order of the log entries is correct. During background tasks you can add the Flush method at the end to ensure that every log entry is written to the file.

1. Download the Microsoft Logging Sample from above
2. Replace the EventListener implementation with this one.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.Threading;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Storage;
using Windows.System.Threading;

namespace FritzboxCallList.Win8.Logging
{
/// <summary>
/// This is an advanced useage, where you want to intercept the logging messages and devert them somewhere
/// besides ETW.
/// </summary>
public class StorageFileEventListener : EventListener
{
/// <summary>
/// Storage file to be used to write logs
/// </summary>
StorageFile _storageFile = null;
/// <summary>
/// Name of the current event listener
/// </summary>
string _name;
/// <summary>
/// The format to be used by logging.
/// </summary>
string _format = "{0:yyyy-MM-dd HH\\:mm\\:ss\\:ffff}\tType: {1}\tId: {2}\tMessage: '{3}'";
/// <summary>
/// Contains the local cache of the lines
/// </summary>
volatile List<string> _linesCache = new List<string>();
/// <summary>
/// Contains the number of lines that must be written to the log file
/// </summary>
volatile int _linesToProcess;
/// <summary>
/// Contains the sync root for the lines cache
/// </summary>
object _syncRoot = new object();
/// <summary>
/// Contains a delay timer
/// </summary>
ThreadPoolTimer _timer;

/// <summary>
/// Gets the log file name (without path)
/// </summary>
public string LogFileName
{
get
{
return _name.Replace(" ", "_") + ".log";
}
}

/// <summary>
/// Gets the backup log file name (without path)
/// </summary>
public string BackupLogFilename
{
get
{
return _name.Replace(" ", "_") + ".log.bak";
}
}

/// <summary>
/// Gets the full log file name (with path)
/// </summary>
public string FullLogFilename
{
get
{
return System.IO.Path.Combine(ApplicationData.Current.LocalFolder.Path, LogFileName);
}
}

/// <summary>
/// Gets the full backup log file name (with path)
/// </summary>
public string FullBackupLogFilename
{
get
{
return System.IO.Path.Combine(ApplicationData.Current.LocalFolder.Path, BackupLogFilename);
}
}

/// <summary>
/// Initializes a new instance of the listener
/// </summary>
/// <param name="name">the name of the listener. The file name of the log will be "(name).log"</param>
public StorageFileEventListener(string name)
{
this._name = name;

Debug.WriteLine("StorageFileEventListener for {0} has name {1}", GetHashCode(), name);
}

/// <summary>
/// Writes the event to the log file stack
/// </summary>
/// <param name="eventData">the data to be written</param>
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
var newFormatedLine = string.Format(_format, DateTime.Now, eventData.Level, eventData.EventId, eventData.Payload[0]);

//Debug.WriteLine(newFormatedLine);

AddLine(newFormatedLine);
}

/// <summary>
/// True, if the log file is not written completly
/// </summary>
public bool InProgress
{
get { return _linesToProcess != 0; }
}
/// <summary>
/// Waits for the worker to complete
/// </summary>
public void Flush()
{
while (_linesToProcess != 0)
Task.Delay(10).Wait();
}

/// <summary>
/// Disposes the instance
/// </summary>
public override void Dispose()
{
if (_storageFile != null)
{
Flush();

_storageFile = null;
}

base.Dispose();
}

/// <summary>
/// Add a line to the cache and start the worker
/// </summary>
/// <param name="line">the line to add</param>
public void AddLine(string line)
{
lock (_syncRoot)
{
_linesCache.Add(line);
_linesToProcess++;

// only start a new delay timer, if there already is no one
if (_timer == null)
_timer = ThreadPoolTimer.CreateTimer((source) => DelayedWorker(), new TimeSpan(0, 0, 0, 0, 500));
}

}

/// <summary>
/// The worker is writing the lines from the lines cache to the file
/// </summary>
void DelayedWorker()
{
// synchronize access to log lines in cache
lock (_syncRoot)
{
// remove the timer to make place for a new one
if (_timer != null)
_timer = null;

// synchronized check, if we have lines to log
if (_linesCache.Count == 0)
return;

// get lines and provide a new lines list for following log entries in the mean time
List<string> lines = _linesCache;
_linesCache = new List<string>();

try
{
// make five tries, if background workers are accessing the file also - so access could denied sometimes
for (int i = 0; i < 3; i++)
{
try
{
// for the first call - create the storage file
if (_storageFile == null)
{
var storageFileTask = ApplicationData.Current.LocalFolder.CreateFileAsync(
LogFileName, CreationCollisionOption.OpenIfExists);
Wait(storageFileTask);
_storageFile = storageFileTask.GetResults();
}

// check the size of the log file
CheckLogFileSize();

// write the buffered log entries to the file
var appendLinesAction = FileIO.AppendLinesAsync(_storageFile, lines);
Wait(appendLinesAction);

// retry on errors
if (appendLinesAction.Status == AsyncStatus.Error)
continue;

return;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("DelayedWorker exception: " + ex.Message  + DateTime.Now.ToString());
}

// Writing to the log file was not successful. Wait for a short period and do a retry
Task.Delay(300).Wait();
}
}
finally
{
// so we have processed some log entries - notifiy that
_linesToProcess -= lines.Count;
}
}
}

/// <summary>
/// Check, that the log file size will not explode
/// </summary>
/// <remarks>
/// When the log file size is more than 1 MB, the current log file is copied to the BackupLogFileName.
/// </remarks>
void CheckLogFileSize()
{
try
{
var bufferAction = FileIO.ReadBufferAsync(_storageFile);
Wait(bufferAction);
// when the log file reaches 1 mb file size, copy the log to bak file and empty the log file.
int mb = 1024 * 1000;
if (bufferAction.GetResults().Length > mb)
{
var bakFileAction = ApplicationData.Current.LocalFolder.CreateFileAsync(BackupLogFilename,
CreationCollisionOption.ReplaceExisting);
Wait(bakFileAction);

//copy and replace the old backup log
var copyAction = _storageFile.CopyAndReplaceAsync(bakFileAction.GetResults());
Wait(copyAction);

System.Diagnostics.Debug.WriteLine("clear file");

// empty the existing log file
var emptyFileAction = FileIO.WriteTextAsync(_storageFile, string.Empty);
Wait(emptyFileAction);
}
}
catch (Exception ex)
{
// Do nothing here. It will be handled the next time
System.Diagnostics.Debug.WriteLine("CheckLogFileSize failed: " + ex.Message);
}
}

/// <summary>
/// Waits until the status is not "Started"
/// </summary>
/// <param name="action">the action</param>
void Wait(IAsyncAction action)
{
while (action.Status == AsyncStatus.Started)
Task.Delay(10).Wait();
}

/// <summary>
/// Waits until the status is not "Started"
/// </summary>
/// <param name="bufferAction">the action</param>
void Wait(IAsyncOperation<Windows.Storage.Streams.IBuffer> bufferAction)
{
while (bufferAction.Status == AsyncStatus.Started)
Task.Delay(10).Wait();
}

/// <summary>
/// Waits until the status is not "Started"
/// </summary>
/// <param name="bakFileAction">the action</param>
void Wait(IAsyncOperation<StorageFile> bakFileAction)
{
while (bakFileAction.Status == AsyncStatus.Started)
Task.Delay(10).Wait();
}
}
}