I am working on upgrading a .NET application without changing its functionality. What I did so far is:
upgrading from mvc 2 to mvc 4
upgrading from framework 3.5 to 4.0
using visual studio 2015 instead of 2010
upgrading the custom made utilities and mvc the same way
Right now I am stuck at the pdf conversion in the custom utilities dll. The error I get is in the image below. It says:
ExportHtmlToPdfBytes failed for url http://localhost:4984/Rijopdracht.mvc/Print/861175: Conversion error: WebKit Navigation timeout.
Error message.
The link is available and accessible behind a proxy. The method ExportHtmlToPdfBytes looks like this:
public byte[] ExportHtmlToPdfBytes(string url)
{
try
{
PdfConverter pdfConverter = CreatePdfConvertor();
byte[] bytes = pdfConverter.GetPdfBytesFromUrl(url);
return bytes;
}
catch (Exception ex)
{
throw new WrapperException(ex, "ExportHtmlToPdfBytes failed for url {0}:", url);
}
}
During debugging I discovered that the program breaks when it calls the function GetPdfBytesFromUrl. After the program breaks, the proxy user I use to access the url, gets blocked. I found out that a user gets blocked if and only if the password has been typed wrong 6 or more times.
I triple checked the username and password that came from the appsettings, and they are correct. Can somebody tell me what is going on and how to solve this?
The complete class PdfUtilities where this function comes from is:
using ExpertPdf.HtmlToPdf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Jumbo.Utilities
{
public class PdfUtilities
{
public PdfUtilities() {
FooterText = String.Empty;
FitWidth = false;
LeftMargin = 5;
RightMargin = 5;
TopMargin = 5;
BottomMargin = 5;
PdfCompressionLevel = PdfCompressionLevel.Normal;
JpegCompressionLevel = 10;
}
public string FooterText { get; set; }
public string AuthenticationUsername { get; set; }
public string AuthenticationPassword { get; set; }
public bool FitWidth { get; set; }
public string BaseUrl { get; set; }
public int LeftMargin { get; set; }
public int RightMargin { get; set; }
public int TopMargin { get; set; }
public int BottomMargin { get; set; }
public int JpegCompressionLevel { get; set; }
public PdfCompressionLevel PdfCompressionLevel { get; set; }
private PdfConverter CreatePdfConvertor()
{
PdfConverter pdfConverter = new PdfConverter();
pdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4;
pdfConverter.PdfDocumentOptions.PdfCompressionLevel = PdfCompressionLevel;
pdfConverter.PdfDocumentOptions.PdfPageOrientation = PDFPageOrientation.Landscape;
pdfConverter.PdfDocumentOptions.LiveUrlsEnabled = false;
pdfConverter.PdfDocumentOptions.ShowHeader = true;
pdfConverter.PdfDocumentOptions.ShowFooter = true;
pdfConverter.PdfDocumentOptions.LeftMargin = LeftMargin;
pdfConverter.PdfDocumentOptions.RightMargin = RightMargin;
pdfConverter.PdfDocumentOptions.TopMargin = TopMargin;
pdfConverter.PdfDocumentOptions.BottomMargin = BottomMargin;
pdfConverter.PdfDocumentOptions.GenerateSelectablePdf = true;
pdfConverter.PdfDocumentOptions.EmbedFonts = true;
pdfConverter.PdfDocumentOptions.JpegCompressionLevel = JpegCompressionLevel;
if (FitWidth)
{
pdfConverter.PageWidth = 0;
pdfConverter.PdfDocumentOptions.FitWidth = true;
pdfConverter.PdfDocumentOptions.StretchToFit = true;
}
else
pdfConverter.PdfDocumentOptions.FitWidth = false;
//pdfConverter.PageWidth = 0;
pdfConverter.PdfDocumentOptions.ShowHeader = false;
pdfConverter.PdfFooterOptions.FooterTextColor = System.Drawing.Color.Black;
pdfConverter.PdfFooterOptions.DrawFooterLine = false;
pdfConverter.PdfFooterOptions.PageNumberText = "Page";
pdfConverter.PdfFooterOptions.ShowPageNumber = true;
pdfConverter.PdfFooterOptions.FooterText = FooterText;
if (!string.IsNullOrEmpty(AuthenticationUsername) && !string.IsNullOrEmpty(AuthenticationPassword))
{
pdfConverter.AuthenticationOptions.Username = AuthenticationUsername;
pdfConverter.AuthenticationOptions.Password = AuthenticationPassword;
}
else
{
string username = SettingsUtilities.GetSetting<string>(GenericConstants.AS_PROXY_USERNAME, null);
if (!String.IsNullOrEmpty(username))
{
string password = SettingsUtilities.GetSetting<string>(GenericConstants.AS_PROXY_PASSWORD, null);
pdfConverter.AuthenticationOptions.Username = username;
pdfConverter.AuthenticationOptions.Password = password;
}
}
pdfConverter.LicenseKey = "tZ6HlY2Vh4WBg5WDm4WVhoSbhIebjIyMjA==";
return pdfConverter;
}
public byte[] ExportHtmlToPdfBytes(string url)
{
try
{
PdfConverter pdfConverter = CreatePdfConvertor();
byte[] bytes = pdfConverter.GetPdfBytesFromUrl(url);
return bytes;
}
catch (Exception ex)
{
throw new WrapperException(ex, "ExportHtmlToPdfBytes failed for url {0}:", url);
}
}
public byte[] ExportHtmlStringToPdfBytes(string html)
{
PdfConverter pdfConverter = CreatePdfConvertor();
byte[] bytes;
if (BaseUrl == null)
bytes = pdfConverter.GetPdfBytesFromHtmlString(html);
else
bytes = pdfConverter.GetPdfBytesFromHtmlString(html, BaseUrl);
return bytes;
}
public void SaveHtmlToPdf(string url, string saveLocation)
{
Logging.LogVerboseCaller(Logging.Cat.Utilities, "Start export to htm for " + url);
byte[] contents = ExportHtmlToPdfBytes(url);
Logging.LogVerboseCaller(Logging.Cat.Utilities, "End export. Start save to " + saveLocation);
FileUtilities.SaveFile(saveLocation, contents);
Logging.LogVerboseCaller(Logging.Cat.Utilities, "End save");
}
}
}
A colleague of mine was able to solve it.
First of all: if we needed the proxy, we shouldn't use the AuthenticationOptions. I believe these are meant to login with your ExpertPDF account. There are proxy attributes for the PdfConverter class that could be used for that.
But, that wasn't the problem. My problem was that I used a license for an earlier version. The error wasn't clear on this, but it was an invalid license key.
To test this, we commented out the license key. We automatically used the demo version that puts a watermark over the generated pdfs, but it told us that it was a wrong license key that messed it up.
Related
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 3 years ago.
I have a relatively simple console app (framework) which has a tightly coupled classes with properties and my main triggers an async task. These are my property classes:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net.Http; //for HTTP client
using System.Reflection;
using System.Threading.Tasks; //for Async Request/Response
using Newtonsoft.Json; //for JSON properties
namespace PSD2
{
[Serializable]
public class PS
{
public System.Uri BaseURL { get; set; } = new System.Uri("http://192.999.999.999:8888/some/url/here/");
public ConsHeaders Headers { get; set; }
public ConsBody Body { get; set; }
public consAttributes Attributes { get; set; }
}
[Serializable]
public partial class ConsHeaders
{
[JsonProperty("Core-ID")]
public string corID { get; set; }
[JsonProperty("PS-Token")]
public string PS_Token { get; set; }
[JsonProperty("Req-ID")]
public string reqID { get; set; }
}
[Serializable]
public partial class consAttributes
{
[JsonProperty("consId")]
public string consId { get; set; } = String.Empty;
[JsonProperty("consStatus")]
public string consStatus { get; set; } = String.Empty;
[JsonProperty("userName")]
public string userName { get; set; } = String.Empty;
};
[Serializable]
public partial class consBody
{
[JsonProperty("access")]
public AccessHeaders access { get; internal set; }
[JsonProperty("combinedServiceIndicator")]
public Boolean CombinedServiceIndicator { get; set; } = false;
[JsonProperty("frequencyPerDay")]
public int FrequencyPerDay { get; set; } = 4;
[JsonProperty("recurringIndicator")]
public Boolean RecurringIndicator { get; set; } = false;
[JsonProperty("validUntil")]
public string ValidUntil { get; set; } = "9999-12-31";
}
...
Now, my Program class creates an object and in Main I call a class called testing who has my logic behind, nothing more than populating the object properties with values, and calls a Task asycn which is also present inside. Code continues from above as:
public class Program
{
public static PS cnsnt = new PS();
public static void Main(string[] args)
{
Testing test = new Testing();
test.createCONS();
}
public class Testing
{
public void createCONS()
{
try
{
cnsnt.Headers = new ConsHeaders
{
corID = "Something",
reqID = "AnotherThing",
PS_Token = "myTokenValue"
};
cnsnt.Body = new ConsBody
{
access = new AccessHeaders
{
AllPsd2 = "allAccounts",
AvailableAccounts = "YES"
},
CombinedServiceIndicator = false,
FrequencyPerDay = 10,
ValidUntil = "2020-12-31"
};
cnsnt.Attributes = new consAttributes
{
consId = "",
_links_self_href = "",
consStatus = "",
status_href = "",
userName = ""
};
}
catch (System.Exception e)
{
throw new System.Exception("Error - Aborting..");
}
myConsAsync(cnsnt.BaseURL, cnsnt, HttpMethod.Post).GetAwaiter().GetResult();
}
public async static Task myConsAsync(Uri HTTPaddress, PS ConSent, HttpMethod httpMethod)
{
try
{
HttpClient client = new HttpClient();
System.Text.UTF8Encoding utf8 = new System.Text.UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true);
using (HttpRequestMessage request = new HttpRequestMessage(httpMethod, HTTPaddress))
{
client.BaseAddress = HTTPaddress;
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("Connection", "keep-alive");
client.DefaultRequestHeaders.Add("Cache-Control", "no-cache");
//...
client.DefaultRequestHeaders.Add("Core-ID", ConSent.Headers.corID);
client.DefaultRequestHeaders.Add("Req-ID", ConSent.Headers.reqID);
client.DefaultRequestHeaders.Add("PS-Token", ConSent.Headers.PS_Token);
//...
request.Content = new StringContent(JsonConvert.SerializeObject(ConSent, Formatting.Indented), utf8, "application/json");
using (HttpResponseMessage response = await client.SendAsync(request).ConfigureAwait(false))
{
response.EnsureSuccessStatusCode();
Int32 code = (Int32)response.StatusCode;
string responseBody = response.Content.ReadAsStringAsync().Result.ToString();
try
{
if (responseBody.Contains("consId"))
{
try
{
string responseValues = JSONtoKeyValue(responseBody);
var dict = responseValues.Split('|')
.Select(x => x.Split('='))
.Where(x => x.Length > 1
&& !String.IsNullOrEmpty(x[0].Trim())
&& !String.IsNullOrEmpty(x[1].Trim()))
.ToDictionary(x => x[0].Trim(), x => x[1].Trim());
foreach (KeyValuePair<string, string> entry in dict)
{
if (entry.Value == null)
{
dict.Remove(entry.Key);
}
else
{
string key = entry.Key;
string value = entry.Value;
try
{
if (cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key) != null)
{
// ---> ERROR: Object reference not set to an instance of an object.
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value);
}
}
catch (System.Exception e)
{
Console.WriteLine("Failed during processing Property: " + e.Message);
}
}
}
Console.ReadLine();
}
catch (System.Exception e)
{
Console.WriteLine(e.StackTrace + "\r\n" + e.Message);
}
}
else
{
throw new System.Exception("Fatal error reading response body for the consent Id. Aborting..");
};
}
catch (System.Exception e)
{
Environment.Exit(13);
}
}
}
}
catch (Exception e)
{
//whatever, Console.WriteLine("Error in " + e.TargetSite + "\r\n" + e.Message + "\r\n" + e.Data);
}
//return
}
// this works as intended.. included just for completion
public static string JSONtoKeyValue(string pString)
{
pString.Trim();
if (pString == null)
{
return "";
}
else
{
pString = pString.Replace("\r\n", "|").Replace(":", "=").Replace("\"", "").Replace("{", "").Replace("}", "").Replace(",", "");
int j = 0, inputlen = pString.Length;
char[] newarr = new char[inputlen];
for (int i = 0; i < inputlen; ++i)
{
char tmp = pString[i];
if (!char.IsWhiteSpace(tmp))
{
newarr[j] = tmp; ++j;
}
}
return new String(newarr, 0, j).Replace("||", "|").Replace("||", "|").Replace("=|", "_").Trim('|');
}
}
}
}
}
Notice in the Task that I want to read a string separated with pipes (a small method does the work nicely) and I try to see if I have this property in my object, and if yes, to populate the value.
However, in line
ConSent.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value);
I get the error "Object reference not set to an instance of an object."
I struggle on this one, could someone help me?
You have made a simple mistake.
You check for
(cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key) != null)
But then you assign with
ConSent.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value)
Just replace it with,
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key).SetValue(cnsnt, entry.Value).
Note its cnsnt. Not ConSent.
and you'll be fine. Happy reflecting!
edit:
saw your edit, same thing.
cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key)
cnsnt.GetType().GetTypeInfo().GetDeclaredProperty(key)
you are basically checking on a different bject if it has a property and then you try to set it on another.
Suggestion.
Why not go:
var keyProperty = cnsnt.Attributes.GetType().GetTypeInfo().GetDeclaredProperty(key);
if(keyProperty != null)
{
keyProperty.SetValue(cnsnt, entry.Value);
}
this way it will not fail, ever.
I have found many different solutions with OAuth and either with some libraries or with pure requests (https://github.com/googlesamples/oauth-apps-for-windows).
However, none of the solutions looks like the one that I really need. Currently, my application uses its own database for users to log in using WCF service request (with username and password). However, all users have their domain e-mail created with Google accounts, so I want to add another button "Sign In with Google", which will just make sure that user can also login with his Google e-mail-password pair. I don't need a returned token for the further use etc.
What is the simplest way to achieve this functionality in WPF/C# desktop application?
Here is a self-sufficient, 3rd party-free, WPF sample that does Google auth (it could be easily converted to winforms as well).
If you run it you won't be logged and the app will show you a button. If you click that button, an embedded webbrowser control will run though the Google auth.
Once you are authenticated, the app will just display your name as returned by Google.
Note it's based on official Google's sample here: https://github.com/googlesamples/oauth-apps-for-windows but it uses an embedded browser instead of spawning an external one (and few other differences).
XAML code:
<Window x:Class="GoogleAuth.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="750" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="btv" />
</Window.Resources>
<Grid>
<DockPanel Visibility="{Binding State.IsSigned, Converter={StaticResource btv}}">
<Label>You are signed as:</Label>
<Label Content="{Binding State.Token.Name}" />
</DockPanel>
<Grid Visibility="{Binding State.IsNotSigned, Converter={StaticResource btv}}">
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Button Click="Button_Click">Click to Sign In</Button>
<WebBrowser Grid.Row="1" x:Name="Wb" Height="Auto" />
</Grid>
</Grid>
</Window>
C# code:
using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
namespace GoogleAuth
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
State = new OAuthState();
DataContext = this;
}
public OAuthState State { get; }
private void Button_Click(object sender, RoutedEventArgs e)
{
var thread = new Thread(HandleRedirect);
thread.Start();
}
private async void HandleRedirect()
{
State.Token = null;
// for example, let's pretend I want also want to have access to WebAlbums
var scopes = new string[] { "https://picasaweb.google.com/data/" };
var request = OAuthRequest.BuildLoopbackRequest(scopes);
var listener = new HttpListener();
listener.Prefixes.Add(request.RedirectUri);
listener.Start();
// note: add a reference to System.Windows.Presentation and a 'using System.Windows.Threading' for this to compile
await Dispatcher.BeginInvoke(() =>
{
Wb.Navigate(request.AuthorizationRequestUri);
});
// here, we'll wait for redirection from our hosted webbrowser
var context = await listener.GetContextAsync();
// browser has navigated to our small http servern answer anything here
string html = string.Format("<html><body></body></html>");
var buffer = Encoding.UTF8.GetBytes(html);
context.Response.ContentLength64 = buffer.Length;
var stream = context.Response.OutputStream;
var responseTask = stream.WriteAsync(buffer, 0, buffer.Length).ContinueWith((task) =>
{
stream.Close();
listener.Stop();
});
string error = context.Request.QueryString["error"];
if (error != null)
return;
string state = context.Request.QueryString["state"];
if (state != request.State)
return;
string code = context.Request.QueryString["code"];
State.Token = request.ExchangeCodeForAccessToken(code);
}
}
// state model
public class OAuthState : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private OAuthToken _token;
public OAuthToken Token
{
get => _token;
set
{
if (_token == value)
return;
_token = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Token)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsSigned)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsNotSigned)));
}
}
public bool IsSigned => Token != null && Token.ExpirationDate > DateTime.Now;
public bool IsNotSigned => !IsSigned;
}
// This is a sample. Fille information (email, etc.) can depend on scopes
[DataContract]
public class OAuthToken
{
[DataMember(Name = "access_token")]
public string AccessToken { get; set; }
[DataMember(Name = "token_type")]
public string TokenType { get; set; }
[DataMember(Name = "expires_in")]
public int ExpiresIn { get; set; }
[DataMember(Name = "refresh_token")]
public string RefreshToken { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
[DataMember]
public string Picture { get; set; }
[DataMember]
public string Locale { get; set; }
[DataMember]
public string FamilyName { get; set; }
[DataMember]
public string GivenName { get; set; }
[DataMember]
public string Id { get; set; }
[DataMember]
public string Profile { get; set; }
[DataMember]
public string[] Scopes { get; set; }
// not from google's response, but we store this
public DateTime ExpirationDate { get; set; }
}
// largely inspired from
// https://github.com/googlesamples/oauth-apps-for-windows
public sealed class OAuthRequest
{
// TODO: this is a sample, please change these two, use your own!
private const string ClientId = "581786658708-elflankerquo1a6vsckabbhn25hclla0.apps.googleusercontent.com";
private const string ClientSecret = "3f6NggMbPtrmIBpgx-MK2xXK";
private const string AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/v2/auth";
private const string TokenEndpoint = "https://www.googleapis.com/oauth2/v4/token";
private const string UserInfoEndpoint = "https://www.googleapis.com/oauth2/v3/userinfo";
private OAuthRequest()
{
}
public string AuthorizationRequestUri { get; private set; }
public string State { get; private set; }
public string RedirectUri { get; private set; }
public string CodeVerifier { get; private set; }
public string[] Scopes { get; private set; }
// https://developers.google.com/identity/protocols/OAuth2InstalledApp
public static OAuthRequest BuildLoopbackRequest(params string[] scopes)
{
var request = new OAuthRequest
{
CodeVerifier = RandomDataBase64Url(32),
Scopes = scopes
};
string codeChallenge = Base64UrlEncodeNoPadding(Sha256(request.CodeVerifier));
const string codeChallengeMethod = "S256";
string scope = BuildScopes(scopes);
request.RedirectUri = string.Format("http://{0}:{1}/", IPAddress.Loopback, GetRandomUnusedPort());
request.State = RandomDataBase64Url(32);
request.AuthorizationRequestUri = string.Format("{0}?response_type=code&scope=openid%20profile{6}&redirect_uri={1}&client_id={2}&state={3}&code_challenge={4}&code_challenge_method={5}",
AuthorizationEndpoint,
Uri.EscapeDataString(request.RedirectUri),
ClientId,
request.State,
codeChallenge,
codeChallengeMethod,
scope);
return request;
}
// https://developers.google.com/identity/protocols/OAuth2InstalledApp Step 5: Exchange authorization code for refresh and access tokens
public OAuthToken ExchangeCodeForAccessToken(string code)
{
if (code == null)
throw new ArgumentNullException(nameof(code));
string tokenRequestBody = string.Format("code={0}&redirect_uri={1}&client_id={2}&code_verifier={3}&client_secret={4}&scope=&grant_type=authorization_code",
code,
Uri.EscapeDataString(RedirectUri),
ClientId,
CodeVerifier,
ClientSecret
);
return TokenRequest(tokenRequestBody, Scopes);
}
// this is not used in this sample, but can be used to refresh a token from an old one
// https://developers.google.com/identity/protocols/OAuth2InstalledApp Refreshing an access token
public OAuthToken Refresh(OAuthToken oldToken)
{
if (oldToken == null)
throw new ArgumentNullException(nameof(oldToken));
string tokenRequestBody = string.Format("refresh_token={0}&client_id={1}&client_secret={2}&grant_type=refresh_token",
oldToken.RefreshToken,
ClientId,
ClientSecret
);
return TokenRequest(tokenRequestBody, oldToken.Scopes);
}
private static T Deserialize<T>(string json)
{
if (string.IsNullOrWhiteSpace(json))
return default(T);
return Deserialize<T>(Encoding.UTF8.GetBytes(json));
}
private static T Deserialize<T>(byte[] json)
{
if (json == null || json.Length == 0)
return default(T);
using (var ms = new MemoryStream(json))
{
return Deserialize<T>(ms);
}
}
private static T Deserialize<T>(Stream json)
{
if (json == null)
return default(T);
var ser = CreateSerializer(typeof(T));
return (T)ser.ReadObject(json);
}
private static DataContractJsonSerializer CreateSerializer(Type type)
{
if (type == null)
throw new ArgumentNullException(nameof(type));
var settings = new DataContractJsonSerializerSettings
{
DateTimeFormat = new DateTimeFormat("yyyy-MM-dd'T'HH:mm:ss.fffK")
};
return new DataContractJsonSerializer(type, settings);
}
// https://stackoverflow.com/questions/223063/how-can-i-create-an-httplistener-class-on-a-random-port-in-c/
private static int GetRandomUnusedPort()
{
var listener = new TcpListener(IPAddress.Loopback, 0);
listener.Start();
var port = ((IPEndPoint)listener.LocalEndpoint).Port;
listener.Stop();
return port;
}
private static string RandomDataBase64Url(int length)
{
using (var rng = new RNGCryptoServiceProvider())
{
var bytes = new byte[length];
rng.GetBytes(bytes);
return Base64UrlEncodeNoPadding(bytes);
}
}
private static byte[] Sha256(string text)
{
using (var sha256 = new SHA256Managed())
{
return sha256.ComputeHash(Encoding.ASCII.GetBytes(text));
}
}
private static string Base64UrlEncodeNoPadding(byte[] buffer)
{
string b64 = Convert.ToBase64String(buffer);
// converts base64 to base64url.
b64 = b64.Replace('+', '-');
b64 = b64.Replace('/', '_');
// strips padding.
b64 = b64.Replace("=", "");
return b64;
}
private static OAuthToken TokenRequest(string tokenRequestBody, string[] scopes)
{
var request = (HttpWebRequest)WebRequest.Create(TokenEndpoint);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
byte[] bytes = Encoding.ASCII.GetBytes(tokenRequestBody);
using (var requestStream = request.GetRequestStream())
{
requestStream.Write(bytes, 0, bytes.Length);
}
var response = request.GetResponse();
using (var responseStream = response.GetResponseStream())
{
var token = Deserialize<OAuthToken>(responseStream);
token.ExpirationDate = DateTime.Now + new TimeSpan(0, 0, token.ExpiresIn);
var user = GetUserInfo(token.AccessToken);
token.Name = user.Name;
token.Picture = user.Picture;
token.Email = user.Email;
token.Locale = user.Locale;
token.FamilyName = user.FamilyName;
token.GivenName = user.GivenName;
token.Id = user.Id;
token.Profile = user.Profile;
token.Scopes = scopes;
return token;
}
}
private static UserInfo GetUserInfo(string accessToken)
{
var request = (HttpWebRequest)WebRequest.Create(UserInfoEndpoint);
request.Method = "GET";
request.Headers.Add(string.Format("Authorization: Bearer {0}", accessToken));
var response = request.GetResponse();
using (var stream = response.GetResponseStream())
{
return Deserialize<UserInfo>(stream);
}
}
private static string BuildScopes(string[] scopes)
{
string scope = null;
if (scopes != null)
{
foreach (var sc in scopes)
{
scope += "%20" + Uri.EscapeDataString(sc);
}
}
return scope;
}
// https://developers.google.com/+/web/api/rest/openidconnect/getOpenIdConnect
[DataContract]
private class UserInfo
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "kind")]
public string Kind { get; set; }
[DataMember(Name = "email")]
public string Email { get; set; }
[DataMember(Name = "picture")]
public string Picture { get; set; }
[DataMember(Name = "locale")]
public string Locale { get; set; }
[DataMember(Name = "family_name")]
public string FamilyName { get; set; }
[DataMember(Name = "given_name")]
public string GivenName { get; set; }
[DataMember(Name = "sub")]
public string Id { get; set; }
[DataMember(Name = "profile")]
public string Profile { get; set; }
[DataMember(Name = "gender")]
public string Gender { get; set; }
}
}
}
This code uses an embedded Internet Explorer control, but since Google doesn't support old Internet Explorer versions, it's likely that you also need to add some code to play with IE's compatibility features as described here for example: https://stackoverflow.com/a/28626667/403671
You can put that code in App.xaml.cs, like this:
public partial class App : Application
{
public App()
{
// use code from here: https://stackoverflow.com/a/28626667/403671
SetWebBrowserFeatures();
}
}
Note what the webbrowser will display depends entirely on Google, and it can considerably vary depending on the environment like cookies, language, etc.
I think you are missing the point on what the OAuth is, start by reading this and here is a simple description of the flow.
which will just make sure that user can also login with his Google e-mail-password pair, I don't need a returned token for the further use
There is no api for user/pass validation, and the token is the whole point of the OAuth. A user with existing email should be able to login if indeed you registered your application with google. Also i see no point in prior validation of user/pass, just add the button.
I found some new APIs in Windows 10 Mobile device portal that allows to run applications on user phone .
you can launch this like to see the result : http://{PhoneIP}/api/app/packagemanager/packages
and there's another API to launch applications :
api/taskmanager/app
Starts a modern app
HTTP verb: POST
Parameters
appid : PRAID of app to start, hex64 encoded
package : Full name of the app package, hex64 encoded
I have this code to run applications but doesn't work any idea ?
public class PackageInfoToRun
{
public string appid { get; set; }
public string package { get; set; }
public string PackageFamilyName { get; set; }
}
public class PhoneInstalledPackages
{
public Installedpackage[] InstalledPackages { get; set; }
}
public class Installedpackage
{
public string Name { get; set; }
public string PackageFamilyName { get; set; }
public string PackageFullName { get; set; }
public int PackageOrigin { get; set; }
public string PackageRelativeId { get; set; }
public bool IsXAP { get; set; }
}
private static string Encode(string strn)
{
var toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(strn);
string appName64 = System.Convert.ToBase64String(toEncodeAsBytes);
appName64 = appName64.Replace(" ", "20%");
return appName64;
}
public async Task<PhoneInstalledPackages> GetInstalledApps()
{
// /api/app/packagemanager/packages
HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create("http://127.0.0.1/api/app/packagemanager/packages");
string res = "";
webrequest.Method = "GET";
try
{
using (var webresponse = await webrequest.GetResponseAsync())
using (StreamReader loResponseStream = new StreamReader(webresponse.GetResponseStream()))
{
res = loResponseStream.ReadToEnd();
}
var des = JsonConvert.DeserializeObject<PhoneInstalledPackages>(res);
return des;
}
catch (Exception ex)
{
return null;
}
}
public async Task<bool> RunAppAsync(string appid, string packagename)
{
HttpResponseMessage http = new HttpResponseMessage();
string str;
try
{
var package = new PackageInfoToRun()
{
appid = Encode(appid),
package = Encode(packagename)
};
using (HttpClient client = new HttpClient())
{
var serial = JsonConvert.SerializeObject(package);
http = await client.PostAsync("http://127.0.0.1/api/taskmanager/app", new StringContent(serial, Encoding.UTF8, "application/json"));
using (HttpResponseMessage response = http)
{
str = await response.Content.ReadAsStringAsync();
string retur = str;
if (retur.Contains("true"))
{
return true;
}
return false;
}
}
}
catch (Exception ex)
{
return false;
}
}
what's going wrong in my codes ? thanks :)
I used your code with small changes and it works for me.
now RunAppAsync looks like this. Don't forget to specify a PORT.
HttpClient client = new HttpClient();
var serial = JsonConvert.SerializeObject(package);
var result = await client.PostAsync(String.Format("http://127.0.0.1:*PORT*/api/taskmanager/app?appid={0}&package={1}", package.appid, package.package), new StringContent(serial));
Where the package is
var package = new PackageInfoToRun()
{
appid = Encode(app.PackageRelativeId),
package = Encode(app.PackageFullName),
};
And the app variable is an instance of InstalledPackage class.
I have this class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Web.Script.Serialization;
using System.Json;
using System.Runtime.Serialization.Json;
using System.Web.Helpers;
namespace Automatic_Record
{
class Youtube_Video_Information
{
public const string ytKey = "";
public int Width { get; set; }
public int Height { get; set; }
public int Duration { get; set; }
public string Title { get; set; }
public string ThumbUrl { get; set; }
public string BigThumbUrl { get; set; }
public string Description { get; set; }
public string VideoDuration { get; set; }
public string Url { get; set; }
public DateTime UploadDate { get; set; }
public bool YouTubeImport(string VideoID)
{
try
{
WebClient myDownloader = new WebClient();
myDownloader.Encoding = System.Text.Encoding.UTF8;
string jsonResponse = myDownloader.DownloadString("https://www.googleapis.com/youtube/v3/videos?id=" + VideoID + "&key=" + ytKey + "&part=snippet");
JavaScriptSerializer jss = new JavaScriptSerializer();
var dynamicObject = Json.Decode(jsonResponse);
var item = dynamicObject.items[0].snippet;
Title = item.title;
ThumbUrl = item.thumbnails.#default.url;
BigThumbUrl = item.thumbnails.high.url;
Description = item.description;
UploadDate = Convert.ToDateTime(item.publishedAt);
jsonResponse = myDownloader.DownloadString("https://www.googleapis.com/youtube/v3/videos?id=" + VideoID + "&key=" + ytKey + "&part=contentDetails");
dynamicObject = Json.Decode(jsonResponse);
string tmp = dynamicObject.items[0].contentDetails.duration;
Duration = Convert.ToInt32(System.Xml.XmlConvert.ToTimeSpan(tmp).TotalSeconds);
Url = "http://www.youtube.com/watch?v=" + VideoID;
return true;
}
catch (Exception ex)
{
return false;
}
}
public bool VimeoImport(string VideoID)
{
try
{
WebClient myDownloader = new WebClient();
myDownloader.Encoding = System.Text.Encoding.UTF8;
string jsonResponse = myDownloader.DownloadString("http://vimeo.com/api/v2/video/" + VideoID + ".json");
JavaScriptSerializer jss = new JavaScriptSerializer();
var dynamicObject = Json.Decode(jsonResponse);
var item = dynamicObject[0];
Title = item.title;
Description = item.description;
Url = item.url;
ThumbUrl = item.thumbnail_small;
BigThumbUrl = item.thumbnail_large;
UploadDate = Convert.ToDateTime(item.upload_date);
Width = Convert.ToInt32(item.width);
Height = Convert.ToInt32(item.height);
Duration = Convert.ToInt32(item.duration);
return true;
}
catch (Exception ex)
{
return false;
}
}
}
}
In form1 constructor i did:
Youtube_Video_Information.ytKey = "myapikey";
Youtube_Video_Information yvi = new Youtube_Video_Information();
yvi.YouTubeImport("ee-myvideoid");
The problem is that i'm getting error on:
Youtube_Video_Information.ytKey
Error 3 The left-hand side of an assignment must be a variable, property or indexer
How can i solve the error ?
How do i assign a value to a public const string variable?
You cannot. Const values cannot have a value assigned in runtime. If you need to be able to assign value in runtime, pass the value to a constructor call and make the member readonly.
class Youtube_Video_Information
{
public readonly string ytKey;
public Youtube_Video_Information(string ytKey)
{
this.ytKey = ytKey;
}
}
I have a console application which needs to connect to SQL Reporting Services on SQL Server Express 2012.
All the exporting logic should be implemented in a separate dll, and the paths should be dynamic (I have loop through various settings for various servers/reports and export them to Excel one by one).
I tried to follow these tutorials:
http://www.aspose.com/docs/display/wordsreportingservices/Rendering+Reports+Programmatically
http://blogs.msdn.com/b/selvar/archive/2010/12/13/accessing-the-reportexecutionservice-render-method-when-reporting-service-2008-r2-is-in-forms-based-authentication.aspx
Basically, I added web references:
http://localhost:80/ReportServer_SQLEXPRESS12/ReportExecution2005.asmx
and
http://localhost:80/ReportServer_SQLEXPRESS12/ReportService2010.asmx
to my dll. Looks good so far, except those nasty app.config settings (I'll have to adjust them dynamically later).
Then I tried to do as in the example:
// Create Web service proxies.
ReportingService2010.ReportingService2010 rs = new ReportingService2010.ReportingService2010();
ReportExecutionService.ReportExecutionService rsExec = new ReportExecutionService.ReportExecutionService();
and got some troubles:
Error 76 The type or namespace name 'ReportExecutionService' does not exist in the namespace 'MyDllNamespace.ReportExecutionService' (are you missing an assembly reference?)
Error 74 The type or namespace name 'ReportingService2010' does not exist in the namespace 'MyDllNamespace.ReportingService2010' (are you missing an assembly reference?)
Now where do I go next, how do I use the Reporting Services API, if I cannot even create a proxy object? Or should I better use ServerReport class form the Winforms ReportViewer instead of these web references?
Even one of Microsoft examples is using ReportViewer in a console application, but it seems a bit awkward to import Winforms in a console app.
I hope the following will help (extract of pertinent parts of code)
using (ZUtilities.SSRS.Report report = new ZUtilities.SSRS.Report {
ReportServerPath = VParameter.GetValue("SSRS_WebServiceUrl", _repo.Parameters).ToString(),
Format = rformat,
ReportPath = "some_path_on_ssrs_server"
}) {
report.Params.Add("Id", id.ToString());
report.Credentials = nwc;
MemoryStream ms = new MemoryStream();
report.Render().CopyTo(ms);
FileContentResult fsr = new FileContentResult(ms.ToArray(), rctype);
fsr.FileDownloadName = String.Format("EPV-{0}-{1:yyyyMMdd}.{2}", epv.ExternalReference, DateTime.Now, fext);
ms.Close();
return fsr;
}
with the following (be carefull to the stream management)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
namespace ZUtilities.SSRS {
public enum ReportFormats {
Html = 1,
MHtml,
Pdf,
Xlsx,
Docx
}
public class ReportFormat {
static ReportFormat() {
Html = new ReportFormat { Code = ReportFormats.Html, Instruction = "HTML4.0" };
MHtml = new ReportFormat { Code = ReportFormats.MHtml, Instruction = "MHTML" };
Pdf = new ReportFormat { Code = ReportFormats.Pdf, Instruction = "PDF" };
Xlsx = new ReportFormat { Code = ReportFormats.Xlsx, Instruction = "EXCELOPENXML" };
Docx = new ReportFormat { Code = ReportFormats.Docx, Instruction = "WORDOPENXML" };
}
private ReportFormat() {
}
public ReportFormats Code { get; set; }
public String Instruction { get; set; }
public static ReportFormat Html { get; private set; }
public static ReportFormat MHtml { get; private set; }
public static ReportFormat Pdf { get; private set; }
public static ReportFormat Xlsx { get; private set; }
public static ReportFormat Docx { get; private set; }
public static ReportFormat ByCode(ReportFormats code) {
switch (code) {
case ReportFormats.Html: return Html;
case ReportFormats.MHtml: return Html; //<<======================
case ReportFormats.Pdf: return Pdf;
case ReportFormats.Xlsx: return Xlsx;
case ReportFormats.Docx: return Docx;
default : return null;
}
}
}
public class Report : IDisposable {
private HttpWebRequest _httpWReq;
private WebResponse _httpWResp;
public Report() {
_httpWReq = null;
_httpWResp = null;
Format = ReportFormats.Html;
Params = new Dictionary<String, String>();
}
public Dictionary<String, String> Params { get; set; }
public String ReportServerPath { get; set; }
public String ReportPath { get; set; }
public ReportFormats Format { get; set; }
public NetworkCredential Credentials { get; set; }
//public String PostData { get { return String.Format("rs:Command=Render&rs:Format={0}", ReportFormat.ByCode(Format).Instruction); } }
public String PostData { get {
StringBuilder sb = new StringBuilder(1024);
sb.AppendFormat("rs:Command=Render&rs:Format={0}", ReportFormat.ByCode(Format).Instruction);
if (Format == ReportFormats.Html) {
sb.Append("&rc:Toolbar=false");
}
foreach (var kv in Params) {
sb.AppendFormat("&{0}={1}", kv.Key, kv.Value);
}
return sb.ToString();
} }
public String ReportFullPath { get { return ReportServerPath + "?/" + ReportPath; } }
public Stream Render() {
_httpWReq = (HttpWebRequest)HttpWebRequest.Create(ReportFullPath);
_httpWReq.Method = "POST";
if (Credentials != null)
_httpWReq.Credentials = Credentials;
byte[] byteArray = Encoding.UTF8.GetBytes(PostData);
_httpWReq.ContentType = "application/x-www-form-urlencoded";
_httpWReq.ContentLength = byteArray.Length;
Stream dataStream = _httpWReq.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
if (_httpWResp != null )
_httpWResp.Close();
_httpWResp = _httpWReq.GetResponse();
return _httpWResp.GetResponseStream();
}
public void RenderTo(String fileName) {
Stream receiveStream = Render();
Stream ds = File.Open(fileName, FileMode.Create);
receiveStream.CopyTo(ds);
ds.Close();
receiveStream.Close();
}
public void Dispose() {
if (_httpWResp != null) {
_httpWResp.Close();
_httpWResp = null;
}
if (_httpWReq != null) {
_httpWReq = null;
}
}
}
}