Ehsan Ghanbari

Experience, DotNet, Solutions

Sinch Wrapper for sending SMS

I was recently looking for a verification system and came across with Sinch. It's been satisfactory until now. After installing the library by nuget I created a wrapper for SMS, hope it be useful!

 

 public class SinchWrapper
    {
        public static async Task<SinchWrapperResult> SendSms(string countryCode, string number, string message)
        {
            try
            {
                number = number.Replace(" ", "").Replace("-", "");
                if (string.IsNullOrEmpty(message))
                    return new SinchWrapperResult { Faild = true, Message = "Message was empty" };
                var destinationNumber = countryCode + number;
                var smsApi = SinchFactory.CreateApiFactory("Your Key", "YourSecret).CreateSmsApi()");
                var sendSmsResponse = await smsApi.Sms(destinationNumber, message).Send();
                return new SinchWrapperResult { Faild = false, Message = message };
            }
            catch (Exception ex)
            {
                return new SinchWrapperResult { Faild = true, Message = ex.Message };
            }
        }
        public static async Task<SinchWrapperResult> SendVerificationSms(string countryCode, string number, string code)
        {
            var result = await SendSms(countryCode, number, $"your verification code is: {code}");
            result.Data = code;
            return result;
        }
    }
    public class SinchWrapperResult
    {
        public bool Faild { get; set; }
        public string Message { get; set; }
        public string Data { get; set; }
    }

 

Rather than above which is available almost in every SMS panels, there is another cool option that verifies by a Missed Call! Instead of entering the receiving and entering the verification code via SMS, you enter the number that you been called with! For using that feature you simply change the configuration:

 


            var api = SinchFactory.CreateApiFactory("key", "secret").CreateVerificationApi();
            var initiate = await api.Verification(number).WithReference("A Reference number").WithCustom("A Custom number").Initiate(VerificationMethod.FlashCall);
            var report = await api.Verification(number).WithCli(initiate.FlashCall.CliFilter).Report(VerificationMethod.FlashCall);
   

 



Working with Static Files in asp.net core

In asp.net core,  the wwwroot folder treated as a web root folder. Static files can be stored in any folder under the web root and accessed with a relative path to that root. By default, static files are not accessible:

In order to access a file you should add the related configuration in Configure method of Startup class:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseStaticFiles();
         }

By running again the project, the image will be accessible:

Now if you want to do more configuration for other paths inside wwwroot, for example, directory browsing or inner static file, you can add the configuration below:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseStaticFiles();

            app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider = new PhysicalFileProvider(
                Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Images")),
                RequestPath = "/Images"
            });

            app.UseDirectoryBrowser(new DirectoryBrowserOptions
            {
                FileProvider = new PhysicalFileProvider(
                    Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "Images")),
                RequestPath = "/Images"
            });

            app.UseHttpsRedirection();
            app.UseMvc();
        }

It's obviously shown that the Images is a folder inside wwwroot, look at the output below:



Custom C# wrapper for calling web API

I've used a custom wrapper for calling asp.net web API services in some projects. I just wanted to share it over here. It's been tested for hundreds of times!

 

 

   public class MyCustomWrapper<T> where T : class

    {

        private static readonly HttpClient Client = new HttpClient();

 

        public async Task<T> GetItemAsync(string apiUrl, CancellationToken cancellationToken)

        {

            var result = default(T);

            try

            {

                var response = await Client.GetAsync(apiUrl, cancellationToken).ConfigureAwait(false);

                if (response.IsSuccessStatusCode)

                {

                    await response.Content.ReadAsStringAsync().ContinueWith(x =>

                    {

                        if (typeof(T).Namespace != "System")

                        {

                            var data = x?.Result;

                            result = JsonConvert.DeserializeObject<T>(data);

                        }

                        else result = (T)Convert.ChangeType(x?.Result, typeof(T));

                    }, cancellationToken);

                }

                else

                {

                    var content = await response.Content.ReadAsStringAsync();

                    response.Content?.Dispose();

                    throw new HttpRequestException($"{response.StatusCode}:{content}");

                }

            }

            catch (Exception)

            {

                return result;

            }

 

            return result;

        }

 

        public async Task<T[]> GetItemsRequestAsync(string apiUrl, CancellationToken cancellationToken)

        {

            T[] result = null;

            var response = await Client.GetAsync(apiUrl, cancellationToken).ConfigureAwait(false);

            if (response.IsSuccessStatusCode)

            {

                await response.Content.ReadAsStringAsync().ContinueWith((Task<string> x) =>

                {

                    result = JsonConvert.DeserializeObject<T[]>(x.Result);

                }, cancellationToken);

            }

            else

            {

                var content = await response.Content.ReadAsStringAsync();

                response.Content?.Dispose();

                throw new HttpRequestException($"{response.StatusCode}:{content}");

            }

            return result;

        }

 

        public async Task<T> PostRequestAsync(string apiUrl, T postObject, CancellationToken cancellationToken)

        {

            T result = default(T);

            var json = JsonConvert.SerializeObject(postObject);

            var content = new StringContent(json.ToString(), Encoding.UTF8, "application/json");

            var response = await Client.PostAsync(apiUrl, content);

 

            if (response.IsSuccessStatusCode)

            {

                await response.Content.ReadAsStringAsync().ContinueWith((Task<string> x) =>

                {

                    result = JsonConvert.DeserializeObject<T>(x.Result);

                }, cancellationToken);

            }

            else

            {

                var unSuccesscontent = await response.Content.ReadAsStringAsync();

                response.Content?.Dispose();

                throw new HttpRequestException($"{response.StatusCode}:{unSuccesscontent}");

            }

            return result;

        }

 

        public async Task PutRequestAsync(string apiUrl, T putObject, CancellationToken cancellationToken)

        {

            var response = await Client.PutAsync(apiUrl, new JsonContent(putObject), cancellationToken).ConfigureAwait(false);

            if (!response.IsSuccessStatusCode)

            {

                var content = await response.Content.ReadAsStringAsync();

                response.Content?.Dispose();

                throw new HttpRequestException($"{response.StatusCode}:{content}");

            }

        }

 

        public async Task DeleteRequestAsync(string apiUrl, CancellationToken cancellationToken)

        {

            var response = await Client.DeleteAsync(apiUrl, cancellationToken).ConfigureAwait(false);

            if (!response.IsSuccessStatusCode)

            {

                var content = response.Content.ReadAsStringAsync();

                response.Content?.Dispose();

                throw new HttpRequestException($"{response.StatusCode}:{content}");

            }

        }

    }

 

    public class JsonContent : StringContent

    {

        public static JsonContent From(object data) => data == null ? null : new JsonContent(data);

 

        public JsonContent(object data)

            : base(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json")

        {

        }

    }

 

And about the usage of this wrapper:

 

 var wrapperResult = new MyCustomWrapper<YourClass>();

        var result = wrapperResult.GetItemAsync("https://localhost/api/user/GetInfo?username=" + "userName", new CancellationToken());

        var data = result.Result;

that's it! 



Private protected in C# 7.2

If you remember protected internal which introduced in earlier versions of C#, it can be accessed by any code in the assembly in which it is declared, or from within a derived class in another assembly. For example, if you look at the following code:

 

namespace namespace1

{

    public class BaseClass1

    {

        protected internal void ProtectedInternalMethod()

        {

 

        }

    }

}

 

namespace namespace2

{

    public class BaseClass2 : BaseClass1

    {

        public void Method1()

        {

            ProtectedInternalMethod();

        }

    }

 

    public class BaseClass3

    {

        public void Method2()

        {

            var baseClass1 = new BaseClass1();

            baseClass1.ProtectedInternalMethod();

        }

    }

}

 

We defined a method in BaseClass1 as protected internal and we used that method in other classes named BaseClass2 and BaseClass3. Notice that BaseClass2 is deriving from BaseClass1 But and BaseClass3 Does NOT but we can use ProtectedInternalMethod() in both of them.

Now look at the following example:

 

namespace namespace3

{

    public class BaseClass4

    {

        private protected void PrivateProtectedMethod()

        {

 

        }

    }

}

 

namespace namespace4

{

    public class BaseClass5 : BaseClass4

    {

        public void Method2()

        {

            PrivateProtectedMethod();

        }

    }

 

    public class BaseClass6

    {

        public void Method1()

        {

            var BaseClass4 = new BaseClass4();

            BaseClass4.PrivateProtectedMethod(); //it's compile error! We don't have access to private protected method here

        }

    }

}

 

 

We used the same structure but with a private protected access modifier. If you consider the above samples, you will find out the Protected internal is so-called protected OR internal so it's accessible in the same assembly or the derived class(even in another assembly) whereas the private protected is Protected AND internal, so it's accessible in the same assembly AND derived classes! 



Communicate between Windows Service and SignalR Client

Today I had to make a connection between an old windows service and SignalR client. After tackling for an hour I decided to reference the Microsoft.AspNet.SignalR.Client library to my web service project and use it like below by overriding the OnStart method, actually I created the SignalR hub connection in the web service method:

 

 protected override async void OnStart(string[] args)
        {
               var hubConnection = new HubConnection("http://www.MySignalRDomain.com/signalr", useDefaultUrl: false);
               IHubProxy myProjectHub= hubConnection.CreateHubProxy("myProjectHub");

               await hubConnection.Start();

               await myProjectHub.Invoke("HiToYou", "an invoked message, for example");
         }

 

And in the SignalR service, I created the target hub to get the string ("an invoked message,  for example") from the web service in HiToYou method :

 
   

 public class myProjectHub: Hub
    {
       public void HiToYou(string message)
        {
                  Clients.All.addNewMessageToPage(message);

         }

       }

 

Needless to say, if you are using OwinStartup, you need to register SignalR middleware:

 

 

using Microsoft.Owin;

using Owin;

 

[assembly: OwinStartup(typeof(MyApplication.Startup))]

namespace MyApplication

{

    public class Startup

    {

        public void Configuration(IAppBuilder app)

        {                  

            app.MapSignalR("/signalr", new HubConfiguration());

        }

    }

}

 

Hope it would be useful!



About Me

Ehsan Ghanbari

Hi! my name is Ehsan. I'm a developer, passionate technologist, and fan of clean code. I'm interested in enterprise and large-scale applications architecture and design patterns and I'm spending a lot of my time on architecture subject. Since 2008, I've been as a developer for companies and organizations and I've been focusing on Microsoft ecosystem all the time. During the&nb Read More

Post Tags
Pending Blog Posts
Strategic design
Factory Pattern
time out pattern in ajax
Selectors in Jquery
Peridic pattern
How to query over Icollection<> of a type with linq
How to use PagedList In asp.net MVC
Domain driven design VS model driven architecture
What's the DDD-lite?
Using Generic type for type casting in F#