1
\$\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
            }
        }
\$\endgroup\$
3
\$\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);
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.