3
\$\begingroup\$

This is a follow up question of this one.

Since the original question was posted, it has turned out that in some cases I want the code to be synchronous and in others to be async. I have updated the code the 'handle registration' method is now fully sync I believe:

public void HandleRegistration(IProgress<string> progressInfo = null)
 {
 Task.Run((() => HandleRegistrationAsync(progressInfo))).Wait();
 }

Since that I have also created a 'handle updates' logic (which is more or less identical). Method returns true if new version is available and false if it is not.

 public bool HandleUpdates(IProgress<string> progressInfo = null)
 {
 return Task.Run((() => HandleUpdatesAsync(progressInfo))).Result;
 }

And I have made their async counterparts public as well.

Now, when I am using the code, and I want to block the main thread, I use simply updateHelper.HandleUpdates(prog);. This blocks the thread pretty well. However, I am not sure about the following - what is the difference between:

Task.Run(() => regHelp.HandleRegistration(progressInfo1)); //appears to not block the thread
Task.Run(() => regHelp.HandleRegistrationAsync(progressInfo1)); //appears to not block the thread
regHelp.HandleRegistrationAsync(prog0); //without 'await', appears to block the thread, but not 'fully'

Also, I believe that I could only use await regHelp.HandleRegistrationAsync(prog0); in an async method. If I am using it for example in the constructor (e.g. public MainWindow() or in static void Main(string[] args)), the proper way would be to use Task.Run(); for it?

As for other changes, I have replaced const value for connString in my app with a connection string settings from Azure. As for naming of instances of RegistrationHelper, I will keep that in mind - though in my non-English head it sounds pretty good. It's only used once per app in two lines of code anyways.

As for the security, I have already introduced something very basic a couple of weeks ago.

I am sending a little string (a 'password' let's say) along with the HTTP request. And at the beginning of each API method I check if the 'password' provided is correct. If not, then return with an error code.

 [Route("api/getver/{programname}")]
 public async Task<string> GetLatestVersionNumberAsync(string programname)
 {
 if (!BasicAuthProvider.PerformBasicAuthentication(this.Request))
 {
 return "-960";
 }
 //rest of code 
 }
public static class BasicAuthProvider
{
 private static string BasicAuthenticationKey
{
 get { return ConfigurationManager.ConnectionStrings["BasicAuthenticationKey"].ConnectionString; }
 //I keep it as connection string because it's not 'visible' by default in manage interface of Azure, though I suppose it's //a litte difference if any
}
public static bool PerformBasicAuthentication(HttpRequestMessage message)
{
 var authorization = message.Headers.Authorization;
 var decodedHeader = System.Text.Encoding.ASCII.GetString(Convert.FromBase64String(authorization.Parameter));
 if (decodedHeader.Equals(BasicAuthenticationKey))
 {
 return true;
 }
 return false;
}
}

Now, as for the HttpPost, I have handled it as follows:

For the data that I want to post, I have created a class in my UserController:

public class UserInfo
 {
 public string Email { get; set; }
 public string UserName { get; set; }
 public string MachineName { get; set; }
 }

Then, the action is as follows:

 [Route("registerbyemail")]
 [HttpPost]
 public async Task<int> RegisterUserByEmailAsync(UserInfo info)
 {
 if (!string.IsNullOrEmpty(info.Email) && !string.IsNullOrEmpty(info.UserName) && !string.IsNullOrEmpty(info.MachineName))
 {
 return await RegisterUserEmailAsync(info.Email, info.UserName, info.MachineName);
 }
 else
 {
 return (int)(ResultCodes.Post | ResultCodes.IncorrectInputParameters | ResultCodes.RegisterUser);
 }
 }

And the generic extension method that calls it is:

internal static async Task<string> SendPostMessageAsync(Uri apiUri, string action, Dictionary<string, string> values, bool throwExceptions)
 {
 try
 {
 using (var client = new HttpClient())
 {
 client.BaseAddress = apiUri;
 client.DefaultRequestHeaders.Accept.Clear();
 var byteArray = Encoding.ASCII.GetBytes(ApiHelper.DefaultApiCreds);
 client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
 var content = new FormUrlEncodedContent(values);
 HttpResponseMessage response = await client.PostAsync(action, content);
 return response.IsSuccessStatusCode
 ? response.Content.ReadAsStringAsync().Result
 : string.Format("-{0}", Bj.ConcatInts(100, (int)response.StatusCode));
 }
 }
 catch (Exception)
 {
 //handle it
 }
 }
asked Nov 16, 2015 at 23:07
\$\endgroup\$

1 Answer 1

5
\$\begingroup\$
if (decodedHeader.Equals(BasicAuthenticationKey))
{
 return true;
}
return false;

Whenever you've got something like this, you can just directly return the result to simplify the code:

return decodedHeader.Equals(BasicAuthenticationKey);
answered Mar 24, 2016 at 13:24
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.