"Dynamic Data Display" is an extremely powerful, userful and free charting tool for WPF and C#. If you are looking for a charting tool, and upset with commercial charting tool and library all over the world, then Dynamic Data Display is the best for you.
http://www.mesta-automation.com/real-time-line-charts-with-wpf-and-dynamic-data-display/
Tuesday, January 6, 2015
Tuesday, December 3, 2013
Simplify Asynchronous Programming with C# "yield return"
A few words ahead, please see http://msdn.microsoft.com/en-us/magazine/cc163323.aspx, for the article by inventor of this technology. My post is just a reinvent of the Jeffrey's idea. But my implementation is easy to understand. I read the code by Jeffrey, it's large and hard to digest.
(Next article: Nested IEnumerable functions.)
OK, here we started with my understandable implementation.
Asynchronous programming is extremely important and useful when you are developing an internet server which is going to support large concurrent requests. When dealing with internet data transmission, blocking mode with one thread handling one request is the one of the most popular traditional technologies. Programmers like it because it's easy to implement. On par with traditional programming technologies, asynchronous programming has many advantages.
So, how to make your code stay in beautiful, logical, human readable form of linear structure, avoiding of tearing it into pieces, but still you could enjoy the high performance asynchronous programming technology? The answer is "yield return".
The basic idea of yield return is to form a state machine by writing the state changing logic into a single function or nested function calls. The coding style looks like the code of traditional technology of blocking mode data transmission. Every yield return will return from the function with all state reserved, and when last time the function being called, the code will be executed from last yield return statement.
See this simple example:
Foo() is a function, also it's a state machine. Every time you call it the function will resume execution at the point that last time returned. For sure that every local variable remains in its state of last yield return. OK, let's see how to execute this function:
It's time to show the core of the technology. Let's incorporate the state machine function with asynchronous function calls.
The code isn't real working code, just for theory illustration. The first statement calls BeginGetResponse() passing a callback handler in. The callback handler won't be called until BeginGetResponse() finishing the work. During this period of time, no thread of your app work for these stuffs. So you don't have to pay the price to wait for BeginGetResponse() to return, for example, a thread waiting by semaphore or event. Thus we have a chance to make Foo() to execute the rest of the code. But Driver() can't drive the execution for us. So we have to upgrade our Driver() to a real driver which can drive Foo() through all of its async steps.
So we have AsyncDriver class. Pay attention to BeginGetResponse(), as you can see the call back function is offered by AsyncDriver. When BeginGetResponse() finished its work, AsyncDriver will take control, and it drive the async steps in Foo() by calling iterator.MoveNext(). The 'iterator' is from Foo().
That explains the theory of driving async steps of an IEnumerable function. Real code would be more complex.
Here is the complete code of AsyncDriver. And follow that is the usage of AsyncDriver.
using System;
The usage of AsyncDriver:
(Next article: Nested IEnumerable functions.)
OK, here we started with my understandable implementation.
Asynchronous programming is extremely important and useful when you are developing an internet server which is going to support large concurrent requests. When dealing with internet data transmission, blocking mode with one thread handling one request is the one of the most popular traditional technologies. Programmers like it because it's easy to implement. On par with traditional programming technologies, asynchronous programming has many advantages.
- Far less threads involved, reduce large amount of memory usage.
- Since you don't have to create so many threads, its really responsive to handle an incoming request.
Though it's hard to implement, of course, and it's really easy to introduce bugs. Asynchronous calls always appear in Begin/End functions pair, for example, HttpWebRequest.BeginGetResponse() and HttpWebRequest.EndGetResponse(). You have to call the BeginGetResponse() first, passing in a call back function, so that when it could be called and you got notified when BeginGetResponse() succeeded with a real response object. If your code flow involves several asynchronous calls, then your code is extremely hard to understand and maintain, since your code logic would be teared into several functions.
So, how to make your code stay in beautiful, logical, human readable form of linear structure, avoiding of tearing it into pieces, but still you could enjoy the high performance asynchronous programming technology? The answer is "yield return".
The basic idea of yield return is to form a state machine by writing the state changing logic into a single function or nested function calls. The coding style looks like the code of traditional technology of blocking mode data transmission. Every yield return will return from the function with all state reserved, and when last time the function being called, the code will be executed from last yield return statement.
See this simple example:
private IEnumerable<int> Foo()
{
// some code here
yield return 1;
// some code here
yield return 2;
// some code here
yield return 0;
// some code here
}
Foo() is a function, also it's a state machine. Every time you call it the function will resume execution at the point that last time returned. For sure that every local variable remains in its state of last yield return. OK, let's see how to execute this function:
private void Driver()
{
foreach (var ele in Foo())
{
// do something
}
}
It's time to show the core of the technology. Let's incorporate the state machine function with asynchronous function calls.
private IEnumerable<int> Foo()
{
var ar = HttpWebRequest.BeginGetResponse(callbackHandler);
yield return 1;
var response = HttpWebRequest.EndGetResponse();
response.DoSomthing();
}
The code isn't real working code, just for theory illustration. The first statement calls BeginGetResponse() passing a callback handler in. The callback handler won't be called until BeginGetResponse() finishing the work. During this period of time, no thread of your app work for these stuffs. So you don't have to pay the price to wait for BeginGetResponse() to return, for example, a thread waiting by semaphore or event. Thus we have a chance to make Foo() to execute the rest of the code. But Driver() can't drive the execution for us. So we have to upgrade our Driver() to a real driver which can drive Foo() through all of its async steps.
public class AsyncDriver
{
public IEnumerator<int> iterator;
public void AsyncCallback(IAsyncResult ar)
{
DriveToNext();
}
private void DriveToNext()
{
iterator.MoveNext();
}
public void AsyncCallback(IAsyncResult ar)
{
DriveToNext();
}
}
public void Main()
{
AsyncDriver asyncDriver = new AsyncDriver();
asyncDriver.iterator = Foo().GetEnumerator();
}
private IEnumerable<int> Foo(AsyncDriver asyncDriver)
{
var ar = HttpWebRequest.BeginGetResponse(asyncDriver.AsyncCallback);
yield return 1;
var response = HttpWebRequest.EndGetResponse();
response.DoSomthing();
}
So we have AsyncDriver class. Pay attention to BeginGetResponse(), as you can see the call back function is offered by AsyncDriver. When BeginGetResponse() finished its work, AsyncDriver will take control, and it drive the async steps in Foo() by calling iterator.MoveNext(). The 'iterator' is from Foo().
That explains the theory of driving async steps of an IEnumerable function. Real code would be more complex.
Here is the complete code of AsyncDriver. And follow that is the usage of AsyncDriver.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Common
{
public class AsyncDriver
{
private class AsyncDriverResult : IAsyncResult
{
private object asyncState;
public object AsyncState
{
get { return asyncState; }
set { asyncState = value; }
}
public WaitHandle AsyncWaitHandle
{
get { throw new NotImplementedException(); }
}
public bool CompletedSynchronously
{
get { throw new NotImplementedException(); }
}
private bool isCompleted;
public bool IsCompleted
{
get { return isCompleted; }
set { isCompleted = value; }
}
}
private AutoResetEvent executionFinishedEvent;
private Mutex mutex;
private AsyncDriverResult asyncDriverResult;
private AsyncCallback AsyncDriverCallback;
private Exception terminationException;
private IEnumerable<int> enumerable;
private IEnumerator<int> iterator;
public delegate IEnumerable<int> AsyncEnumerator(AsyncDriver asyncDriver, object state);
public AsyncDriver()
{
mutex = new Mutex();
}
public void AsyncCallback(IAsyncResult ar)
{
DriveToNext();
}
private void DriveToNext()
{
ThreadPool.QueueUserWorkItem((aeObject) =>
{
mutex.WaitOne();
try
{
bool tonext = iterator.MoveNext();
if (tonext)
{
if (iterator.Current == 0)
{
OnExecutionFinished();
}
}
else
{
OnExecutionFinished();
}
}
catch (Exception ex)
{
terminationException = ex;
ex.Data.Add("PtolemaicCallStack", ex.StackTrace);
OnExecutionFinished();
}
finally
{
mutex.ReleaseMutex();
}
},
this);
}
private void OnExecutionFinished()
{
iterator.Dispose();
executionFinishedEvent.Set();
AsyncDriverCallback(asyncDriverResult);
}
public IAsyncResult BeginExecute(AsyncEnumerator asyncEnumerator, AsyncCallback callback, object state)
{
asyncDriverResult = new AsyncDriverResult();
asyncDriverResult.AsyncState = state;
enumerable = asyncEnumerator(this, state);
AsyncDriverCallback = callback;
Execute();
return asyncDriverResult;
}
public void EndExecute(IAsyncResult ar)
{
executionFinishedEvent.WaitOne();
if (terminationException != null)
{
throw terminationException;
}
}
public void Execute()
{
executionFinishedEvent = new AutoResetEvent(false);
iterator = enumerable.GetEnumerator();
DriveToNext();
}
public static string DumpException(Exception ex)
{
string msg = "\n=================================================================\n"
+ ex.ToString() + "\n"
+ ex.Message + "\n\n" + ex.StackTrace + "\n";
if (ex.Data.Contains("PtolemaicCallStack"))
{
msg += "\n---- PtolemaicCallStack ----\n" + ex.Data["PtolemaicCallStack"];
}
msg += "\n=================================================================\n";
return msg;
}
}
}
The usage of AsyncDriver:
public void Main()
{
Common.AsyncDriver asyncDriver = new Common.AsyncDriver();
var serverContext = new ServerContext();
serverContext.AsyncDriver = asyncDriver;
asyncDriver.BeginExecute(Foo, FooCallback, asyncDriver);
}
private void FooCallback(IAsyncResult ar)
{
var asyncDriver = ar.AsyncState as Common.AsyncDriver;
asyncDriver.EndExecute(ar);
}
private IEnumerable<int> Foo(Common.AsyncDriver asyncDriver, object state)
{
var ar = HttpWebRequest.BeginGetResponse(asyncDriver.AsyncCallback);
yield return 1;
var response = HttpWebRequest.EndGetResponse();
response.DoSomthing();
}
Labels:
.Net,
Asynchronous,
C#,
high performance,
Server,
yield return
Friday, October 18, 2013
[Windows Service Debugging] Separate code from service app for convenient debugging
Debugging a windows service is not as convenient as windows application as it states on this MSDN document.A simple way to improve debugging is to separate service function code from the service application to a DLL, and then create an normal windows application start the service object in DLL. Detailed steps as following:
- Create a windows service project that only has VS generated code in it.
- Create a DLL proeject that contains the service object.
- Let service project call the service object to start it.Then your service would work. But this is not for debugging.
- Create a normal windows application, and just as the service project, just call the service object ans start it. This application is convenient for you to debug the service object.
Wednesday, September 25, 2013
(Visual Studio) Per configuration application icon setting
For some reason, I want to build several versions with small differences, i.e. different application icons for different customers. For example, icon1 for customer 1, and icon2 for customer 2.
On Visual Studio 2010 UI, you can only the one icon for all configurations. But when you open .csproj file as plain text, you can see it's real powerful. All per configuration settings are under tag like this:
So just findimages\AppIcon.ico that doesn't belong to your configuration, and add it to the configuration you want. All done!
On Visual Studio 2010 UI, you can only the one icon for all configurations. But when you open .csproj file as plain text, you can see it's real powerful. All per configuration settings are under tag like this:
So just find
Monday, November 12, 2012
HTTPS Communication – HttpListener based Hosting and Client Certification
KEYWORDS: HTTPS, SSL, HttpListener, X509Chain, X509Certificate2, makecert, OpenSSL, client certificate
(Just found, a wonderful tool set that could help you to host easily, http://katanaproject.codeplex.com/. The site referred my post, and I didn't realize till now :-) thanks for refering. [2016-2-6])
HttpListener is the easiest way for you to host an HTTP/HTTPS server. This article provides you step-by-step instructions to create your own server and authenticate clients based on client certificate from ground up in C#.
Download the sample code
var server = new HttpListener();
server.Prefixes.Add("https://+:90/");
server.Start();
HttpListenerContext context = server.GetContext();
These fourlines will make your server started and listening on the port. Be aware of the exceptions (HttpListenerException) thrown from the invocation server.Start(), and see step 2 to solve it.
netsh http add urlacl url=https://+:80/MyUri user=DOMAIN\user
Pay attention to the parameter ‘user’. Put whatever user you want to assign the start server right to here. If set the parameter user=users, it will grant all user account (non-privileged) to start the app and listen on the specific ip and port. The ip part ‘+’ stands for all IPs of your machine. For the server you want to handle urls from root (e.g. http://localhost/), you don’t need ‘MyUri’ part, and your command is like this:
netsh http add urlacl url=https://+:80/ user=DOMAIN\user
So, let’s create the certificates. You can either create your certificates by makecert or by OpenSSL. And this How to Setup a CA gives you an easy tutorial of creating certificates hierachy by OpenSSL. First is the root CA certificate. For experimental cases, makecert is enough. But for product, you may want to use OpenSSL or apply a certificate from CA like VeriSign.
makecert -n "CN=TestCA" -r -sv TestCA.pvk TestCA.cer
And import the root certificate to the system certificate storage of Rusted Root Certification Authority. See this article.
Then create the certificate for your HTTPS web site.
makecert -iv TestCA.pvk -n "CN=TestSite" -sv TestSite.pvk -ic TestCA.cer TestSite.cer -sr LocalMachine -ss My -sky exchange -pe
If you will test your client app on a machine other than the server machine, you have to import the TestCA.cer to the client machine as well. So that the client machine trust TestCA (the root cert), it will also trust the server certificate (TestSite).
Hosting an HTTPS site, you must have a certificate with private key. But the last makecert command creates the private key in TestCA.pvk which can’t be imported to the system storage directly. We have to convert it to .pfx format:
pvk2pfx -pvk "TestSite.pvk" -spc "TestSite.cer" -pfx "TestSite.pfx"
Then you will see the certificate for your site:

netsh http add sslcert ipport=0.0.0.0:90 appid={61047666-992C-4137-9303-7C01781B054E} certhash=75d0fed71881f2141b5b6cb24801dfa554439b1c clientcertnegotiation=enable
‘0.0.0.0’ in the ipport parameter means every ip of this machine would be assigned with the certificate. The parameter appid is your application id. You can see it in the project property, the ‘Application’ page, and the dialog poped up by clicking ‘Assembly Information’ button. The parameter ‘clientcertnegotiation=enable’ will allows C/S mutually authentication based on certificates, i.e. server side could verfiy the certificate validation of the client side as well as the client side verifying the server side. If you don’t want verification for client side, just omit the parameter.
Let’s add responding code to the server side, so that we can see something on the page.
string message = "Hello World!";
var buffer = System.Text.Encoding.UTF8.GetBytes(message);
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.OutputStream.Close();
Now the page displays “Hello World!”.
Here is the basic client code without client certificate.
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(CheckValidationResult);
string url = "https://localhost:90/";
Console.WriteLine("Visiting " + url);
HttpWebRequest objRequest = System.Net.HttpWebRequest.Create(url) as HttpWebRequest;
objRequest.ProtocolVersion = HttpVersion.Version10;
var response = objRequest.GetResponse();
var responseReader = new StreamReader(response.GetResponseStream());
var responseContent = responseReader.ReadToEnd();
Console.WriteLine("Server replied: " + responseContent);
CheckValidationResult is a callback function which allows you to perform customized validation against server certificate, returns true to accept the certificate. As expected, the client gets the server reply: “Hello World!”.
HttpWebRequest objRequest = System.Net.HttpWebRequest.Create(url) as HttpWebRequest;
X509Certificate2 clientCertificate = new X509Certificate2("TestClient.pfx", "the key password");
objRequest.ClientCertificates.Add(clientCertificate);
You have to add certificate to the https request right after you created the request, because GetResponse() will use the certificate immediately. Here is the second way of creating X509Certificate2 - loading the certificate from the system store:
static X509Certificate2 LoadClientCertificate()
{
// Note: Change "My" and StoreLocation.CurrentUser to where your certificate stored.
var store = new X509Store("My", StoreLocation.CurrentUser);
var certificates = store.Certificates.Find(X509FindType.FindBySubjectName, "TestClient", true);
if (certificates.Count != 0)
{
return null;
}
return certificates[0];
}
Before running it, you have to import the certificate (with private key) to the store just like you did with the server certificate. Loading a certificate (without private key) can be done by a non-privileged account, while accessing private key of a certificate from the system store requires administrator privilege. So when you run above code by a non-privileged account, you will get the certificate although, but only public key is in it. While the server side needs the client to sign something to verify the client’s identity, so the client must have the private key. So when carrying out further steps of HTTPS communication
Loading from store and loading from file both has pros and cons.
HttpListenerContext context = server.GetContext();
var clientCertificate = context.Request.GetClientCertificate();
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.Build(clientCertificate);
if (chain.ChainStatus.Length != 0)
{
// Invalid certificate
context.Response.OutputStream.Close();
}
X509Chain is a tool which builds the chain of trust of the certificate. If the certificate is invalid, then you can find error information in chain.ChainStatus. You can implement detailed logic upon X509Chain rather than only checking chain.ChainStatus.Length. Set RevocationMode to NoCheck because we don’t have a certificate server to tell you whether a certificate is revoked.
(Just found, a wonderful tool set that could help you to host easily, http://katanaproject.codeplex.com/. The site referred my post, and I didn't realize till now :-) thanks for refering. [2016-2-6])
HttpListener is the easiest way for you to host an HTTP/HTTPS server. This article provides you step-by-step instructions to create your own server and authenticate clients based on client certificate from ground up in C#.
Download the sample code
STEP 1
Firstly, you should create your .net application and add these four lines.var server = new HttpListener();
server.Prefixes.Add("https://+:90/");
server.Start();
HttpListenerContext context = server.GetContext();
These fourlines will make your server started and listening on the port. Be aware of the exceptions (HttpListenerException) thrown from the invocation server.Start(), and see step 2 to solve it.
STEP 2
Step 1 shows you it’s so easy to start a server. But wait, Start() throws an exception (HttpListenerException: Access Denied, native error code 5, HRESULT 80004005), if you run your app under non-privilege account. If you want a non-privilege account to run the server, you have to add ACL (Access Control Lists) to the system. In command line:netsh http add urlacl url=https://+:80/MyUri user=DOMAIN\user
Pay attention to the parameter ‘user’. Put whatever user you want to assign the start server right to here. If set the parameter user=users, it will grant all user account (non-privileged) to start the app and listen on the specific ip and port. The ip part ‘+’ stands for all IPs of your machine. For the server you want to handle urls from root (e.g. http://localhost/), you don’t need ‘MyUri’ part, and your command is like this:
netsh http add urlacl url=https://+:80/ user=DOMAIN\user
STEP 3
And then your app won’t throw any exception. Your app would be blocked at server.GetContext() and waiting for incoming connections. Try the url https://localhost:90/ in your browser, there is still an error page with HTTP 101 ERR_CONNECTION_RESET. This because you haven’t assign a certificate to the server and the browser can’t verify the validity of the server. Remember we are visiting an HTTPS site. The server certificate is a must.So, let’s create the certificates. You can either create your certificates by makecert or by OpenSSL. And this How to Setup a CA gives you an easy tutorial of creating certificates hierachy by OpenSSL. First is the root CA certificate. For experimental cases, makecert is enough. But for product, you may want to use OpenSSL or apply a certificate from CA like VeriSign.
makecert -n "CN=TestCA" -r -sv TestCA.pvk TestCA.cer
And import the root certificate to the system certificate storage of Rusted Root Certification Authority. See this article.
Then create the certificate for your HTTPS web site.
makecert -iv TestCA.pvk -n "CN=TestSite" -sv TestSite.pvk -ic TestCA.cer TestSite.cer -sr LocalMachine -ss My -sky exchange -pe
If you will test your client app on a machine other than the server machine, you have to import the TestCA.cer to the client machine as well. So that the client machine trust TestCA (the root cert), it will also trust the server certificate (TestSite).
Hosting an HTTPS site, you must have a certificate with private key. But the last makecert command creates the private key in TestCA.pvk which can’t be imported to the system storage directly. We have to convert it to .pfx format:
pvk2pfx -pvk "TestSite.pvk" -spc "TestSite.cer" -pfx "TestSite.pfx"
Then you will see the certificate for your site:
STEP 4
How to use the server certificate? At this point, the when client connect to the server, the client will throw an exception (WebException The underlying connection was closed: An unexpected error occurred on a send), simply because the server doesn’t use the certificate yet. To resolve the exception,just binding the certifiate to the server’s ip and port by netsh.netsh http add sslcert ipport=0.0.0.0:90 appid={61047666-992C-4137-9303-7C01781B054E} certhash=75d0fed71881f2141b5b6cb24801dfa554439b1c clientcertnegotiation=enable
‘0.0.0.0’ in the ipport parameter means every ip of this machine would be assigned with the certificate. The parameter appid is your application id. You can see it in the project property, the ‘Application’ page, and the dialog poped up by clicking ‘Assembly Information’ button. The parameter ‘clientcertnegotiation=enable’ will allows C/S mutually authentication based on certificates, i.e. server side could verfiy the certificate validation of the client side as well as the client side verifying the server side. If you don’t want verification for client side, just omit the parameter.
STEP 5
Visit https://localhost:90/ again, your browser will warning you that the site is not the owner of the certificate. It’s because we don’t have a domain for our experimental site and no domain name was set into the certificate. So just click continue to view the page and the browser will show you a blank page.Let’s add responding code to the server side, so that we can see something on the page.
string message = "Hello World!";
var buffer = System.Text.Encoding.UTF8.GetBytes(message);
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.OutputStream.Close();
Now the page displays “Hello World!”.
STEP 6
We have done the work of constructing server side. The server can show its identity by providing its certificate and client can verify it. Client still shows no certificate to the server. In some cases, the server need to verify the client’s identity, and only when the client is valid (e.g. a valid member of some organization) the server would start data communication. In this case, a client app (other than web browser) is a must. So let’s create a client app.Here is the basic client code without client certificate.
ServicePointManager.ServerCertificateValidationCallback =
new RemoteCertificateValidationCallback(CheckValidationResult);
string url = "https://localhost:90/";
Console.WriteLine("Visiting " + url);
HttpWebRequest objRequest = System.Net.HttpWebRequest.Create(url) as HttpWebRequest;
objRequest.ProtocolVersion = HttpVersion.Version10;
var response = objRequest.GetResponse();
var responseReader = new StreamReader(response.GetResponseStream());
var responseContent = responseReader.ReadToEnd();
Console.WriteLine("Server replied: " + responseContent);
CheckValidationResult is a callback function which allows you to perform customized validation against server certificate, returns true to accept the certificate. As expected, the client gets the server reply: “Hello World!”.
STEP 7
Here we add client certification code. Basically you have two ways of creating a X509Certificate2 which could contain public/private key pair. Other ways like manipulating public/private key pair raw data directly, may be tricky and complex.- Load .pfx from file;
- Load certificate with private key from the system’s certificate store.
HttpWebRequest objRequest = System.Net.HttpWebRequest.Create(url) as HttpWebRequest;
X509Certificate2 clientCertificate = new X509Certificate2("TestClient.pfx", "the key password");
objRequest.ClientCertificates.Add(clientCertificate);
You have to add certificate to the https request right after you created the request, because GetResponse() will use the certificate immediately. Here is the second way of creating X509Certificate2 - loading the certificate from the system store:
static X509Certificate2 LoadClientCertificate()
{
// Note: Change "My" and StoreLocation.CurrentUser to where your certificate stored.
var store = new X509Store("My", StoreLocation.CurrentUser);
var certificates = store.Certificates.Find(X509FindType.FindBySubjectName, "TestClient", true);
if (certificates.Count != 0)
{
return null;
}
return certificates[0];
}
Before running it, you have to import the certificate (with private key) to the store just like you did with the server certificate. Loading a certificate (without private key) can be done by a non-privileged account, while accessing private key of a certificate from the system store requires administrator privilege. So when you run above code by a non-privileged account, you will get the certificate although, but only public key is in it. While the server side needs the client to sign something to verify the client’s identity, so the client must have the private key. So when carrying out further steps of HTTPS communication
- When the client certificate loaded from system store, the client code will get an WebException;
- When the client cerfiticate loaded from file, the server will get no client cert (GetClientCertificate() returns null).
Loading from store and loading from file both has pros and cons.
STEP 8
Server side still doesn’t verify the client certificate. So let’s add the code logic.HttpListenerContext context = server.GetContext();
var clientCertificate = context.Request.GetClientCertificate();
X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.Build(clientCertificate);
if (chain.ChainStatus.Length != 0)
{
// Invalid certificate
context.Response.OutputStream.Close();
}
X509Chain is a tool which builds the chain of trust of the certificate. If the certificate is invalid, then you can find error information in chain.ChainStatus. You can implement detailed logic upon X509Chain rather than only checking chain.ChainStatus.Length. Set RevocationMode to NoCheck because we don’t have a certificate server to tell you whether a certificate is revoked.
Wednesday, August 22, 2012
Render English and Chinese with mono font
(This is an unresolved issue)
How to make a Chinese character exactly 2 English characters wide?
I've tried it in WPF application with Courier New and Segoe UI Mono, but both failed. And also tried SimSun as fallback font, failed again.
Here is the summary of my test.
Successful Examples
Notepad
Notepad++
HTML with pre tag rendered by Chrome
Failed Examples
Visual Studio 2010
HTML without pre tag rendered by Chrome
HTML with and without pre tag rendered by IE
I tried Courier New and Segoe UI Mono with fallback font SimSun in my WPF app. The fallback font mechanism worked, because it can render STLiti which is 隶书, see below
One Chinese char is a little bit less than 2 English chars in width. when fallback font is SimSun, it's the same case
Visual Studio has the same issue
While Notepad++ is pretty successful
Different web browser has different behavior. With
<pre> tag would work well in Chrome while it can't give you Chinese char of 2 English chars width without
<pre>. And IE can't do it in both cases.
As you can see Chinese chars in Figure 3 is a little bit wider than Chinese chars in Figure 1. Is there a covered mechanism results narrow Chinese chars?
How to make a Chinese character exactly 2 English characters wide?
I've tried it in WPF application with Courier New and Segoe UI Mono, but both failed. And also tried SimSun as fallback font, failed again.
Here is the summary of my test.
Successful Examples
Notepad
Notepad++
HTML with pre tag rendered by Chrome
Failed Examples
Visual Studio 2010
HTML without pre tag rendered by Chrome
HTML with and without pre tag rendered by IE
I tried Courier New and Segoe UI Mono with fallback font SimSun in my WPF app. The fallback font mechanism worked, because it can render STLiti which is 隶书, see below
One Chinese char is a little bit less than 2 English chars in width. when fallback font is SimSun, it's the same case
Figure 1
Visual Studio has the same issue
Figure 2
While Notepad++ is pretty successful
Figure 3
Different web browser has different behavior. With
<pre> tag would work well in Chrome while it can't give you Chinese char of 2 English chars width without
<pre>. And IE can't do it in both cases.
As you can see Chinese chars in Figure 3 is a little bit wider than Chinese chars in Figure 1. Is there a covered mechanism results narrow Chinese chars?
Tuesday, March 6, 2012
Config Test Deployment for VS2010
The MSDN document How to: Config Test Deployment is somewhat out-dated. .testrunconfig in VS2010 is actually local.testsettings. Another config file 'TraceAndTestImpact.testsettings' really fooled me. ^_^
Subscribe to:
Posts (Atom)