basquang™ on clouds

April 27, 2017

Calling Untrusted SSL HTTPS request using HttpClient give “Message=The remote certificate is invalid according to the validation procedure”

Filed under: JSON,Microsoft Technology,MVC,WebAPI — basquang @ 3:36 PM

Scenario:

+You want to deploy web application server (for example ASP.NET Web API) which require SSL certificate and HTTPS

+You want to make a call to that server using HttpClient

Problem:

+You may see the following errors message when make a call to https required url using HttpClient
HResult=-2146233079
Message=The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.

HResult=-2146233087
Message=The remote certificate is invalid according to the validation procedure.

HResult=-2146233088
Message=An error occurred while sending the request.

Solution:

Using this lines of code to accept all server certificates from client. This line of code is using for testing purpose only with you are using self-signed or untrusted certificates

//Accept all server certificate
ServicePointManager.ServerCertificateValidationCallback =
    delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                {
                    return true;
                };

For example you want to make a https POST to Web API method in this post Hello ASP.NET Web API

static async Task PostSampleAsync()
        {
            //Accept all server certificate
            ServicePointManager.ServerCertificateValidationCallback =
                delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                {
                    return true;
                };
            client.BaseAddress = new Uri("https://10.1.16.193/WebAPISample/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.PostAsJsonAsync("api/values", "hello!");
            response.EnsureSuccessStatusCode();
            var result = response.Content.ReadAsAsync<string>().Result;
            Console.WriteLine(result);
        }

Happy coding!

Hello ASP.NET Web API

Filed under: JSON,Microsoft Technology,MVC,WebAPI — basquang @ 3:13 PM

1. Create a simple ASP.NET Web API project with HTTP GET and POST method

Create a simple Web API Controller like this:

    public class ValuesController : ApiController
    {
        string[] list = new string[] { "value1", "value2" };
        // GET api/values
        public IEnumerable<string> Get() { return list; }

        // GET api/values/1
        public string Get(int id) { return list[id]; }

        // POST api/values
        public string Post([FromBody]string value) { return value; }
    }

2. Test the Web API using web browser or POSTMAN

Navigate GET method by web browser

http://localhost:3649/api/values

webapi1

in POSTMAN http://localhost:3649/api/values/1

webapi2

in POSTMAN test HTTP POST method

webapi3

3. Call the Web API using HttpClient

+ Create a console application

+ Install Nuget package

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
  <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net452" />
</packages>

+ Create a method to consume Web API method GET like this

static HttpClient client = new HttpClient();
        static void Main(string[] args)
        {
            RunAsync().Wait();
        }

        static async Task RunAsync()
        {
            //await PostSampleAsync();
            await GetSampleAsync();

            Console.ReadLine();
        }
static async Task GetSampleAsync()
        {
            // this is where we will send it
            string uri = "http://localhost:3649/api/values";

            // create a request
            HttpWebRequest request = (HttpWebRequest)
            WebRequest.Create(uri); request.KeepAlive = false;
            request.ProtocolVersion = HttpVersion.Version10;
            request.Method = "GET";

            /*====HTTP POST====*/
            //request.Method = "POST";
            //// turn our request string into a byte stream
            //byte[] postBytes = Encoding.ASCII.GetBytes("hello"); //param

            //// this is important - make sure you specify type this way
            //request.ContentType = "application/x-www-form-urlencoded";
            //request.ContentLength = postBytes.Length;
            //Stream requestStream = request.GetRequestStream();

            //// now send it
            //requestStream.Write(postBytes, 0, postBytes.Length);
            //requestStream.Close();

            // grab te response and print it out to the console along with the status code
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Console.WriteLine(new StreamReader(response.GetResponseStream()).ReadToEnd());
            Console.WriteLine(response.StatusCode);
        }

+ Run debug application you will see the result as below

webapi4

+ Create a method to consume Web API method POST like this

static async Task PostSampleAsync()
        {
            client.BaseAddress = new Uri("http://localhost:3649/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            HttpResponseMessage response = await client.PostAsJsonAsync("api/values", "hello!");
            response.EnsureSuccessStatusCode();
            var result = response.Content.ReadAsAsync<string>().Result;
            Console.WriteLine(result);
        }

+ Run debug application for this method you will see the result as below

webapi5.PNG

Happy coding!

September 9, 2015

Best Practices: Upgrade to Windows 10 UWP Universal apps

Filed under: Microsoft Technology,UWP — basquang @ 11:29 AM
Tags: ,
Scenario:
– You have Windows Phone 8.x and Windows 8.x apps and want to upgrade the app to UWP Universal for Windows 10 to take advantage of new API platform?
– You just only want to update the Windows app to UWP but leave the phone app version in 8.x for some reason ex: AdMob SDK has not yet supported for Windows Phone 8.1 or later. Here are some best practices for you:
1. To target your UWP app only for Windows 10 devices without phone version
Open the Package.appxmanifest file then edit the Dependencies as below
<Dependencies>
    <!--<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />-->
    <TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.10240.0" MaxVersionTested="10.0.10240.0" />
  </Dependencies>
For this setting, you cannot deploy your app to Emulator or phone devices. And then when you upload the package to store, you will see the instruction below “Device families: Windows.Destop minverion 10.0.10240.0”
11638797_10204463343656324_1794777682_o
For more detail please visit msdn link here
https://msdn.microsoft.com/en-us/library/windows/apps/dn986903.aspx
2. Your UWP app using some extra features as access user appointments, contacts…but you do not see that capabilities in Package.appxmanifest to declare.
The solution is open Package.appxmanifest file then edit the node Capabilities as below:
<Capabilities>
    <Capability Name="internetClient" />
    <uap:Capability Name="appointments" />
  </Capabilities>
For more detail please visit msdn link here
https://msdn.microsoft.com/en-us/library/windows/apps/mt270968.aspx
https://msdn.microsoft.com/en-us/library/windows/apps/dn934741.aspx
3. You want to create settings page for your UWP looks like Microsoft Mail Universal app, which display the page flyout on the right. With Windows 8.x this will be completed by using SettingFlyout template, but the template is not supported for Windows 10 UWP.
Solution is create a new page or usercontrol then change the page/usercontrol class to inherit to Windows.UI.Xaml.Controls.SettingsFlyout. In UWP app the SettingsFlyout control is not visible in template selection but it still there in code.
public sealed partial class SettingsFlyoutControl : SettingsFlyout
<SettingsFlyout
    x:Class="LichViet.UserControls.SettingsFlyoutControl"...>
....
</SettingsFlyout>

Hope this help!

April 26, 2014

[WP8.1]: Changing Windows Phone 8.1 WebView default User-Agent in all outbound HTTP requests

Filed under: Microsoft Technology,Tips,Windows Phone — basquang @ 10:07 AM
Tags: , ,

Recently, I’m developing Windows Phone 8 app which hosting our cloud services. We need to add some custom HTTP Headers in to requests. Unfortunately, Windows Phone 8 WebBrowser control doesn’t have properties to set custom User-Agent by default. The only way you can do is the method:

webBrowser1.Navigate(new Uri("https://basquang.wordpress.com/2014/04/26/wp8-1-changing-windows-phone-8-1-webview-default-user-agent-in-all-outbound-http-requests/", UriKind.Absolute), 
null, "User-Agent: your custom user-agent");

But with this method, you are able to pass your custom user-agent in first request only. With outbound HTTP request, meaning all web link in your site, the webBrowser1 will using device’s default User-Agent.

You can check your current user-agent here: http://whatsmyuseragent.com/

By the release of Windows Phone 8.1, now you can set your custom User-Agent for entire process by using Win32 API: UrlMkSetSessionOption

Using following code to make your user-agent by default for all outbound HTTP request in WebView control on Windows Phone 8.1

[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
private static extern int UrlMkSetSessionOption(int dwOption, string pBuffer, int dwBufferLength, int dwReserved);

const int URLMON_OPTION_USERAGENT = 0x10000001;
public void ChangeUserAgent(string Agent)
   {
      UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, Agent, Agent.Length, 0);
   }

void MainPage_Loaded(object sender, RoutedEventArgs e)
   {
      ChangeUserAgent("My Custom User-Agent");
      wb.Navigate(new Uri("https://basquang.wordpress.com/2014/04/26/wp8-1-changing-windows-phone-8-1-webview-default-user-agent-in-all-outbound-http-requests/", UriKind.Absolute));
   }

Hope this help!

Reference: http://www.lukepaynesoftware.com/articles/programming-tutorials/changing-the-user-agent-in-a-web-browser-control/

June 12, 2013

Business Intelligence – Microsoft BI Solution

June 27, 2012

TFS 2010: Analysis Database corrupted

Filed under: Microsoft Technology,TFS,Tips — basquang @ 10:56 AM

Sometime TFS analysis database TFS_Analysis may get problems. For examples:

Error 1: Unable to get the required information about this cube. The cube might have been reorganized or changed on the server. The PivotTable was not refreshed.

Error 2: Detailed Message: TF221122: An error occurred running job Incremental Analysis Database Sync for team project collection or Team Foundation server TEAM FOUNDATION.
Exception Message: Error encountered when creating connection to Analysis Services. Contact your Team Foundation Server administrator. (type AnalysisServiceConnectionException)

Error 3: Exception Message: File system error: The following file is corrupted: Physical file: \\?\C:\Program Files\Microsoft SQL Server\MSAS10_50.MSSQLSERVER\OLAP\Data\Tfs_Analysis.0.db\Dim Team Project.0.dim\330.ProjectPath.ksstore. Logical file .
Errors in the metadata manager. An error occurred when loading the Team Project dimension, from the file, ‘\\?\C:\Program Files\Microsoft SQL Server\MSAS10_50.MSSQLSERVER\OLAP\Data\Tfs_Analysis.0.db\Dim Team Project.330.dim.xml’.
Errors in the metadata manager. An error occurred when loading the Team System cube, from the file, ‘\\?\C:\Program Files\Microsoft SQL Server\MSAS10_50.MSSQLSERVER\OLAP\Data\Tfs_Analysis.0.db\Team System.1191.cub.xml’.
(type OperationException)

In these cases you may have to rebuild the Cube and Warehouse of your TFS.

To rebuild the cube and warehouse, following these steps:

1. Delete analysis database TFS_Analysis

– Go to SQL Server and locate the folders contains TFS_Analysis database C:\Program Files\Microsoft SQL Server\MSAS10_50.MSSQLSERVER\OLAP\Data

– Delete following files and folder: Tfs_Analysis.0.db, CryptKey.bin, Tfs_Analysis.0.db

Restart SQL Server Analysis Database service

2. To recreate the Tfs_Analysis database, please refer to the following steps:

– Launch TFS Admin Console | Application Tier | Reporting, in the right panel, click Edit to open the Reporting window.

– Under the Analysis Services tab, input the Tfs_Analysis under Database textbox, and re-provide the required account under Account for accessing data source.

– Click Ok to generate the Tfs_Analysis database in Analysis Services.

– Click Start Jobs and Start Rebuild to rebuild warehouse and the Analysis Services database.
The similar way to recreated Tfs_Warehouse database under Warehouse tab in Reporting window.

Hope this help!

November 15, 2010

Develop a File IO ActiveX control in Microsoft .NET

Filed under: ActiveX,Digital Signature,Microsoft Technology — basquang @ 4:39 PM

Development

1. Use this guide to create your own ActiveX control

Writing an ActiveX Control in .NET

2. Design your ActiveX as picture bellow:

image

3. Use following code behind

namespace FileIOActiveXControl
{
    public partial class WriteToClientControl : UserControl
    {
        public WriteToClientControl()
        {
            InitializeComponent();
        }

        private void btnWrite_Click(object sender, EventArgs e)
        {
            WriteLog(@"c:\temp\log.txt", txtUserInput.Text);
        }

        public void WriteLog(string fileName, string content)
        {
            try
            {
                StreamWriter log = new StreamWriter(fileName, true);
                log.WriteLine(content);
                log.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }
    }
}

3. Create TestActiveX.htm

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<hr>
Please note that you MUST load this HTML document from your local IIS, or from a TRUSTED SITE or the control will not load properly on the page due to security policy.
<br>
To fix this:<br>
<li>copy the HTM file and the DLL into your c:\inetpub\wwwroot folder (or applicable IIS root directory)
<li>load the document in your browser with the url:  http://localhost/TestActiveX.htm
  <hr>
	 <OBJECT id="fileIOActiveX" name="fileIOActiveX" classid="http:FileIOActiveXControl.dll#FileIOActiveXControl.WriteToClientControl" width="450" height="100" VIEWASTEXT>
	 </OBJECT>
  <hr>
 </body>
</script>
</html>

Deployment

1. Copy FileIOActiveXControl.dll and TestActiveX.htm to the same folder

2. Go to IIS to create a new web site and point to that folder

3. Use another computer to test your control.

If you control cannot load to page like picture bellow.

image

a. Try to add the site to Trusted Zone in IE

b. Make sure .dll and .htm in the same folder

If your control is loaded correctly, you will see:

image

4. Enter some text to the textbox then click Write To File button. You may see:

“Request for the permission of type ‘System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’ failed.”

image

To fix this. You have to configure Code Access Security for Microsoft .NET on client. Run following command to fix this issue.

“C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\caspol.exe -quiet -machine -chggroup Trusted_Zone FullTrust”

image

And  (MANDATORY if your client is running OS 64 bit)

“C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\caspol.exe -quiet -machine -chggroup Trusted_Zone FullTrust”

image

5. Stop IE –> reload the test page –> input some text –> click “Write To File” button again now. There will not have any error message appear. Check the log file from C:\temp\log.txt

Success.

July 14, 2010

Microsoft Outlook Social Connector Provider for Facebook and Windows Live is now available!

Filed under: Microsoft Technology — basquang @ 7:01 AM

I was waiting for these one very long time. I installed it then already seeing all of updated information from my Facebook and Windows Live contacts. Here are some snapshot of emails from my co-worker and friends.

imageimage

Microsoft Outlook Social Connector Provider for Facebook

Microsoft Outlook Social Connector Provider for Windows Live Messenger

June 25, 2010

Windows Live Essential! Cool! Cool!

Filed under: Microsoft Technology — basquang @ 10:42 AM

June 18, 2010

Combine Microsoft ReportViewer, WCF and ASP.NET

Filed under: Microsoft Technology — basquang @ 5:05 AM

Scenario:

– We have a existing Website portal using ASP.NET

– We have a reporting desktop application using Microsoft ReportViewer

– We want to share some report from reporting application to website portal

Solution:

– We use WCF as interface to integrated between ASP.NET and desktop applications

– WCF will provides reports as streaming images data.

Implementation:

Step 1: Create WCF Services

– Create new WCF Service Application from Visual Studio 2010

image

– Define Service Contract

[ServiceContract]
public interface IService1
{
    [OperationContract]
    Stream GenerateImage();        
} 

– Implement Service Contract. We must to export LocalReport to image stream

public System.IO.Stream GenerateImage()
        {
            LocalReport report = new LocalReport();
            //string path = @"D:\Report1.rdlc";
            string path = HttpContext.Current.Server.MapPath("~/Report1.rdlc");
            report.ReportPath = path;
 
            Warning[] warnings;
            string[] streamids;
            string mimeType;
            string encoding;
            string extension;
 
            byte[] bytes = report.Render(
               "Image", null, out mimeType, out encoding,
                out extension,
               out streamids, out warnings);
            Stream stream = new MemoryStream(bytes);
            return stream;
        }

– Enable WCF Streaming in configuration file

<basicHttpBinding>
  <binding name="HttpStreaming" maxReceivedMessageSize="67108864"
           transferMode="Streamed"/>
</basicHttpBinding>

– Create a new Report1.rdlc as following:

image

– Step 2: Test the Service on Windows Form:

– Create new Windows Forms

– Add services reference to your service

– Add a PictureBox control to Form interface then add following code in code behind

public Form1()
        {
            InitializeComponent();
            ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
            Stream memList = client.GenerateImage();           
           
            System.Drawing.Image image = System.Drawing.Image.FromStream(memList);                  
            pictureBox1.Image = image;
        }

– Run the Form you will see:

image

– Step 3: Rendering Image to website portal

– Similar in Windows Form, ASP.NET can display image from stream by very simple code:

protected void Page_Load(object sender, EventArgs e)
        {
            ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
            Stream memList = client.GenerateImage();
         
            System.Drawing.Image image = System.Drawing.Image.FromStream(memList);
            image.Save(Response.OutputStream, System.Drawing.Imaging.ImageFormat.Gif);            
        }

– You will see:

image

Conclusion:

There are three technical used to resolve this scenario:

– Export ReportViewer to image stream

– Enable Streaming in WCF

– Rendering Image from streaming data.

Reference:

How to: Enable Streaming

LocalReport.Render Method (String, String, out String, out String, out String, out String[], out Warning[])

Next Page »

Blog at WordPress.com.