How does JHRS WPF framework call Web API

How does JHRS WPF framework call Web API? When using WPF to do projects, after using web API on the server-side, you naturally have to face the problem of how to call web API. If you don’t encapsulate the web API function well, you may write a lot of redundant code.

hen I started to build this framework, I was also considering this issue. At that time, I was thinking about using the ancestral web api access code, but I didn’t plan to find it anymore. I didn’t want to find it anymore, and the code was poorly written. Okay, so I don’t bother to show it to shame.

web api
How does JHRS WPF framework call Web API

WPF calls Web API

If the access to the web api is not properly encapsulated, the WPF calling Web API code is basically very uncomfortable to write. Just like the redundant call method below, one of the more parameters is passed, and the second is the processing method. It’s a little informal to use it when you get it in the project. Although you can realize the function, of course, if you don’t have high requirements on the code, in fact, you can do it whatever you want.

Redundant call method

How does JHRS WPF framework call Web API? WPF wants to call web api, the code that can often be seen is written like this:

 public  T CallWebAPi<T>(string userName, string password, Uri url, out bool isSuccessStatusCode)
        {
            T result = default(T);

            using (HttpClient client = new HttpClient())
            {
                client.BaseAddress = url;
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(
                    System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", userName, password))));

                HttpResponseMessage response = client.GetAsync(url).Result;
                isSuccessStatusCode = response.IsSuccessStatusCode;
                var JavaScriptSerializer = new JavaScriptSerializer();
                if (isSuccessStatusCode)
                {
                    var dataobj = response.Content.ReadAsStringAsync();
                    result = JavaScriptSerializer.Deserialize<T>(dataobj.Result);
                }
                else if (Convert.ToString(response.StatusCode) != "InternalServerError")
                {
                    result = JavaScriptSerializer.Deserialize<T>("{ \"APIMessage\":\"" + response.ReasonPhrase + "\" }");
                }
                else
                {
                    result = JavaScriptSerializer.Deserialize<T>("{ \"APIMessage\":\"InternalServerError\" }");
                }
            }
            return result;
        }

How does JHRS WPF framework call Web API

Code source: https://stackoverflow.com/questions/18631091/how-to-call-web-api-in-wpf-4-0

How does JHRS WPF framework call Web API? Here also show everyone how to access the web api in the previous project.

 public static class HttpHelper
    {
        public static string BaseURI { get; set; }
        public static string SessionId { get; set; }
        private static readonly Encoding Encoding = Encoding.GetEncoding("UTF-8");
        private static readonly int Timeout = 100000;
        private static readonly string ContentTypePost = "application/json";
        private static readonly string ContentTypePost2 = "application/x-www-form-urlencoded";
        /// <summary>
        /// Call the post request interface
        /// </summary>
        /// <param name="apiName">interface name</param>
        /// <param name="data">Parameter format (JOSN)</param>
        /// <param name="isParameter"></param>
        /// <returns></returns>
        async public static Task<string>PostAsyc(string apiName, string data, bool isParameter = false) 
        {
            return await Task.Run(() =>Send(apiName, data, isParameter));
        }
        /// <summary>
        ///Call the post request interface
        /// </summary>
        /// <param name="apiName">interface name</param>
        /// <param name="data">Parameter format</param>
        /// <param name="isParameter"></param>
        /// <returns></returns>
        public static string Post(string apiName, string data, bool isParameter = false)
        {
            returnSend(apiName, data, isParameter); 
        }
        private static string Send(string apiName, string data, bool isParameter)
        {
            string result = null;
            try
            {
                using(HttpWebResponse response = GetResponse(apiName, data, isParameter)) 
                {
                    if(string.IsNullOrEmpty(SessionId)) 
                    {
                        SessionId = response.Headers.Get("Set-Cookie");
                    }
                    Stream stream = response.GetResponseStream();
                    if(stream != null) 
                    {
                        StreamReader reader = newStreamReader(stream, Encoding); 
                        result = reader.ReadToEnd();
                    }
                }
                return result;
            }
            catch(Exception e) 
            {
                var ret  = newResultJsonBase(){ Succeeded = false, Message = e.Message, Data= "[]"};   
                return JsonHelper.SerializeObject(ret);                               
            }
        }
        private static HttpWebResponse GetResponse(string apiName, string data, bool isParameter)
        {
            
            StringBuilder baseURL = new StringBuilder ( BaseURI ) ; 
            baseURL. Append ( apiName ) ;
            string contentType = ContentTypePost;
            if ( isParameter ) 
            {
                contentType = ContentTypePost2;
                if(!string.IsNullOrWhiteSpace(data)) 
                {
                    data = data.ToLower();
                    JObject urlParam = ( JObject ) JsonConvert. DeserializeObject ( data ) ;
                    baseURL.Append("?");
                    var listParam = urlParam. Properties () . Select ( p = >
                    {
                        return string.Format("{0}={1}", p.Name, p.Value);
                    }) ;
                    string param = String.Join("&", listParam);
                    baseURL. Append ( param ) ;
                }
            }
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(baseURL.ToString());
            request.Method = "POST";
            request.UserAgent = "Mozilla/5.0";
            request.Timeout = Timeout;
            request.ContentType = contentType;
            request.ContentLength = 0;
            object accessToken = MemoryCacheManager.Get(UserContext.AccessToken);
            if(accessToken != null) 
            {
                //token format, set in Header
                request.Headers.Add("Authorization", string.Format("Bearer {0}", accessToken.ToString()));
            }
            if(!string.IsNullOrEmpty(SessionId)) 
            {
                request.CookieContainer = newCookieContainer(); 
                request. CookieContainer . SetCookies ( new Uri ( baseURL. ToString ()) , SessionId ) ; 
            }
            if ( ! isParameter ) 
            {
                if(!string.IsNullOrEmpty(data)) 
                {
                    byte[] bytes = Encoding.GetBytes(data);
                    request.ContentLength = bytes.Length;
                    request.GetRequestStream().Write(bytes, 0, bytes.Length);
                }
                else
                {
                    request.ContentLength = 0;
                }
            }
            try
            {
                return(HttpWebResponse)request.GetResponse(); 
            }
            catch(Exception ex) 
            {
                throw ex;
            }
        }
        /// <summary>
        /// Test whether the server is connected
        /// </summary>
        /// <param name="endPoint">Port number</param>
        /// <param name="ip">ip address</param>
        async public static Task<bool>ConnectTest(string ip, int endPoint) 
        {
            var client = new HttpClient () ; 
            client.BaseAddress = newUri($"http://{ip}:{endPoint}"); 
            client.Timeout = TimeSpan.FromSeconds(5);
            try
            {
                var response = await client.PostAsync("/api/Login/TestConnect", null);
                return response.StatusCode == HttpStatusCode.OK;
            }
            catch
            {
                returnfalse; 
            }
        }
        /// <summary>
        /// Call the universal upload file interface via post
        /// </summary>
        /// <param name="apiName">interface name</param>
        /// <param name="para">Parameter format (json format)</param>
        /// <param name="fileNames">file path</param>
        /// <returns></returns>
        public async static Task<string>PostFilesAsync(string apiName, string para, List<string> fileNames) 
        {
            if(fileNames != null&& fileNames.Count>0)    
            {
                var baseURL = new StringBuilder () ; 
                baseURL. Append ( BaseURI ) ;
                baseURL. Append ( apiName ) ;
                if(!string.IsNullOrWhiteSpace(para)) 
                {
                    JObject urlParam = ( JObject ) JsonConvert. DeserializeObject ( para ) ;
                    baseURL.Append("?");
                    var listParam = urlParam. Properties () . Select ( p = >
                    {
                        return string.Format("{0}={1}", p.Name, p.Value);
                    }) ;
                    string param = String.Join("&", listParam);
                    baseURL. Append ( param ) ;
                }
                var client = new RestClient ( baseURL. ToString ()) ; 
                client.Timeout = -1;
                var request = newRestRequest(Method.POST); 
                 //Set token and add upload file parameters
                object accessToken = MemoryCacheManager.Get(UserContext.AccessToken);
                if(accessToken != null) 
                    request.AddHeader("Authorization", string.Format("Bearer {0}", accessToken.ToString()));
                foreach(var item in fileNames) 
                    request.AddFile("files", item);
                IRestResponse response = await client.ExecuteAsync(request);
                return response.Content;
            }
            returnnull; 
        }
    }
     How does JHRS WPF framework call Web API?

How does JHRS WPF framework call Web API

The above code may be a common kind of encapsulation. Simply get a XXXHelper, and where you need to call it, you have to write it like this:

string jsonResult = HttpHelper.Post(url, strQuery, true);
var Result = JsonHelper.AnalyzeJsonString(jsonResult);

How does JHRS WPF framework call Web API

The above url parameter, which is the URL of the web api interface, is defined as follows:

public class ApiNames
    {
        /// <summary>
        /// Universal upload attachment interface
        /// </summary>
        public const string FileUpload = "/api/Common/Upload";
        /// <summary>
        /// Get patient information
        /// </summary>
        public const string GetPatientInfo = "/api/Common/GetPatientInfo";
    }

How does JHRS WPF framework call Web API

This may be the way we all do this to write the web api interface. The above method has to deal with the received response content and then deserialize it into the required object. I believe that the ape who often writes this kind of code is very distressed. of.

A better way to write code when you get off work early

Programmer, why not get off work early? Wouldn’t it be better to spend more time doing what you want to do, such as building your own website to earn passive income ?

In the JHRS framework , WPF access to web api introduces refit to solve the problem of redundant code and elegance, so in actual projects, you have to do two things.

The first one: write the interface corresponding to the web api

public interface IGitHubApi
{
    [Get("/users/{user}")]
    Task<User> GetUser(string user);
}
From the github refit sample interface, How does JHRS WPF framework call Web API.

How does JHRS WPF framework call Web API

The second one: call it to accomplish your purpose

var gitHubApi = RestService.For<IGitHubApi>("https://jhrs.com");
var octocat = await gitHubApi.GetUser("octocat");

How does JHRS WPF framework call Web API

From the above example, is it easy for WPF to call Web API? But the first to write the web api interface, in large projects, there are hundreds of interfaces, and manual writing is also a manual task; therefore, we have to think of some tricks to reduce these manual tasks, so in the framework, I wrote it easily. A tool for reverse analysis of swagger, although there may be bugs, it is not difficult to fix, because this tool has been used by team members in our project.

How does JHRS WPF framework call Web API
How does JHRS WPF framework call Web API

Is it easy? Some physical tasks should be handed over to the tools for you to complete.

Write at the end

This article introduces the encapsulation concept of WPF calling Web API with high-frequency code that is often written in real projects, as well as some of my lazy methods. The ultimate goal is to improve work efficiency. Let’s be honest. , Just to get off work early, don’t live like 996. How does JHRS WPF framework call Web API?

The next article will introduce how the client designs the entry project, that is, introduce some things in the code in the entry project library of JHRS.Shell , and why it did so.

Related reading in this series

  1. WPF enterprise development framework building guide, 2020 from entry to give up
  2. Introduction JHRS WPF development framework basic library
  3. Selection of third-party frameworks for JHRS development framework
  4. JHRS WPF framework reference library introduction
  5. How does JHRS WPF framework call Web API
  6. How to integrate the various subsystems of the JHRS development framework
  7. How to design a reasonable ViewModel base class in JHRS development framework
  8. Encapsulation of public component user control of JHRS development framework
  9. Some principles of cataloging documents followed by the recommendations of the JHRS development framework
  10. WPF data verification of JHRS development framework
  11. The solution of JHRS development framework’s ViewModel mutual parameter transfer and pop-up frame return parameter
  12. JHRS development framework of stepping on the pit (final chapter)

Leave a Comment