برچسب: JSON

  • How to parse JSON Lines (JSONL) with C# | Code4IT


    JSONL is JSON’s less famous sibling: it allows you to store JSON objects separating them with new line. We will learn how to parse a JSONL string with C#.

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    For sure, you already know JSON: it’s one of the most commonly used formats to share data as text.

    Did you know that there are different flavors of JSON? One of them is JSONL: it represents a JSON document where the items are in different lines instead of being in an array of items.

    It’s quite a rare format to find, so it can be tricky to understand how it works and how to parse it. In this article, we will learn how to parse a JSONL file with C#.

    Introducing JSONL

    As explained in the JSON Lines documentation, a JSONL file is a file composed of different items separated by a \n character.

    So, instead of having

    [{ "name": "Davide" }, { "name": "Emma" }]
    

    you have a list of items without an array grouping them.

    { "name" : "Davide" }
    { "name" : "Emma" }
    

    I must admit that I’d never heard of that format until a few months ago. Or, even better, I’ve already used JSONL files without knowing: JSONL is a common format for logs, where every entry is added to the file in a continuous stream.

    Also, JSONL has some characteristics:

    • every item is a valid JSON item
    • every line is separated by a \n character (or by \r\n, but \r is ignored)
    • it is encoded using UTF-8

    So, now, it’s time to parse it!

    Parsing the file

    Say that you’re creating a videogame, and you want to read all the items found by your character:

    class Item {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Category { get; set; }
    }
    

    The items list can be stored in a JSONL file, like this:

    {  "id": 1,  "name": "dynamite",  "category": "weapon" }
    {  "id": 2,  "name": "ham",  "category": "food" }
    {  "id": 3,  "name": "nail",  "category": "tool" }
    

    Now, all we have to do is to read the file and parse it.

    Assuming that we’ve read the content from a file and that we’ve stored it in a string called content, we can use Newtonsoft to parse those lines.

    As usual, let’s see how to parse the file, and then we’ll deep dive into what’s going on. (Note: the following snippet comes from this question on Stack Overflow)

    List<Item> items = new List<Item>();
    
    var jsonReader = new JsonTextReader(new StringReader(content))
    {
        SupportMultipleContent = true // This!!!
    };
    
    var jsonSerializer = new JsonSerializer();
    while (jsonReader.Read())
    {
        Item item = jsonSerializer.Deserialize<Item>(jsonReader);
        items.Add(item);
    }
    return items;
    

    Let’s break it down:

    var jsonReader = new JsonTextReader(new StringReader(content))
    {
        SupportMultipleContent = true // This!!!
    };
    

    The first thing to do is to create an instance of JsonTextReader, a class coming from the Newtonsoft.Json namespace. The constructor accepts a TextReader instance or any derived class. So we can use a StringReader instance that represents a stream from a specified string.

    The key part of this snippet (and, somehow, of the whole article) is the SupportMultipleContent property: when set to true it allows the JsonTextReader to keep reading the content as multiline.

    Its definition, in fact, says that:

    //
    // Summary:
    //     Gets or sets a value indicating whether multiple pieces of JSON content can be
    //     read from a continuous stream without erroring.
    //
    // Value:
    //     true to support reading multiple pieces of JSON content; otherwise false. The
    //     default is false.
    public bool SupportMultipleContent { get; set; }
    

    Finally, we can read the content:

    var jsonSerializer = new JsonSerializer();
    while (jsonReader.Read())
    {
        Item item = jsonSerializer.Deserialize<Item>(jsonReader);
        items.Add(item);
    }
    

    Here we create a new JsonSerializer (again, coming from Newtonsoft), and use it to read one item at a time.

    The while (jsonReader.Read()) allows us to read the stream till the end. And, to parse each item found on the stream, we use jsonSerializer.Deserialize<Item>(jsonReader);.

    The Deserialize method is smart enough to parse every item even without a , symbol separating them, because we have the SupportMultipleContent to true.

    Once we have the Item object, we can do whatever we want, like adding it to a list.

    Further readings

    As we’ve learned, there are different flavors of JSON. You can read an overview of them on Wikipedia.

    🔗 JSON Lines introduction | Wikipedia

    Of course, the best place to learn more about a format it’s its official documentation.

    🔗 JSON Lines documentation | Jsonlines

    This article exists thanks to Imran Qadir Baksh’s question on Stack Overflow, and, of course, to Yuval Itzchakov’s answer.

    🔗 Line delimited JSON serializing and de-serializing | Stack Overflow

    Since we’ve used Newtonsoft (aka: JSON.NET), you might want to have a look at its website.

    🔗SupportMultipleContent property | Newtonsoft

    Finally, the repository used for this article.

    🔗 JsonLinesReader repository | GitHub

    Conclusion

    You might be thinking:

    Why has Davide written an article about a comment on Stack Overflow?? I could have just read the same info there!

    Well, if you were interested only in the main snippet, you would’ve been right!

    But this article exists for two main reasons.

    First, I wanted to highlight that JSON is not always the best choice for everything: it always depends on what we need. For continuous streams of items, JSONL is a good (if not the best) choice. Don’t choose the most used format: choose what best fits your needs!

    Second, I wanted to remark that we should not be too attached to a specific library: I’d generally prefer using native stuff, so, for reading JSON files, my first choice is System.Text.Json. But not always it’s the best choice. Yes, we could write some complex workaround (like the second answer on Stack Overflow), but… does it worth it? Sometimes it’s better to use another library, even if just for one specific task. So, you could use System.Text.Json for the whole project unless for the part where you need to read a JSONL file.

    Have you ever met some unusual formats? How did you deal with it?

    Happy coding!

    🐧



    Source link

  • Postman's pre-request scripts: how to perform HTTP POST requests (with JSON body) and how to set Cookie authentication.

    Postman's pre-request scripts: how to perform HTTP POST requests (with JSON body) and how to set Cookie authentication.


    In Postman, you can define scripts to be executed before the beginning of a request. Can we use them to work with endpoints using Cookie Authentication?

    Table of Contents

    Just a second! 🫷
    If you are here, it means that you are a software developer.
    So, you know that storage, networking, and domain management have a cost .

    If you want to support this blog, please ensure that you have disabled the adblocker for this site.
    I configured Google AdSense to show as few ADS as possible – I don’t want to bother you with lots of ads, but I still need to add some to pay for the resources for my site.

    Thank you for your understanding.
    Davide

    Nowadays, it’s rare to find services that use Cookie Authentication, yet they still exist. How can we configure Cookie Authentication with Postman? How can we centralize the definition using pre-request scripts?

    I had to answer these questions when I had to integrate a third-party system that was using Cookie Authentication. Instead of generating a new token manually, I decided to centralize the Cookie creation in a single place, making it automatically available to every subsequent request.

    In order to generate the token, I had to send a request to the Authentication endpoint, sending a JSON payload with data coming from Postman’s variables.

    In this article, I’ll recap what I learned, teach you some basics of creating pre-request scripts with Postman, and provide a full example of how I used it to centralize the generation and usage of a cookie for a whole Postman collection.

    Introducing Postman’s pre-request scripts

    As you probably know, Postman allows you to create scripts that are executed before and after an HTTP call.

    These scripts are written in JavaScript and can use some objects and methods that come out of the box with Postman.

    You can create such scripts for a single request or the whole collection. In the second case, you write the script once so that it becomes available for all the requests stored within that collection.

    Postman&rsquo;s pre-request section on a Collection

    The operations defined in the Scripts section of the collection are then executed before (or after) every request in the collection.

    Here, you can either use the standard JavaScript code—like the dear old console.log— or the pm object to reference the context in which the script will be executed.

    For example, you can print the value of a Postman variable by using:

    const tokenUrl = pm.variables.get("TokenUrl")
    console.log(tokenUrl)
    

    How to send a POST request with JSON body in Postman pre-request scripts

    How can we issue a POST request in the pre-request script, specifying a JSON body?

    Postman’s pm object, along with some other methods, exposes the sendRequest function. Its first parameter is the “description” of the request; its second parameter is the callback to execute after the request is completed.

    pm.sendRequest(request, (errorResponse, successfulResponse) => {
      // do something here
    })
    

    You have to carefully craft the request, by specifying the HTTP method, the body, and the content type:

    var authenticationBody = {
      UserName: username,
      Password: password,
    }
    
    const request = {
      method: "POST",
      url: tokenUrl,
      body: {
        mode: "raw",
        raw: JSON.stringify(authenticationBody),
        options: {
          raw: {
            language: "json",
          },
        },
      },
    }
    

    Pay particular attention to the options node: it tells Postman how to treat the body content and what the content type is. Because I was missing this node, I spent too many minutes trying to figure out why this call was badly formed.

    options: {
      raw: {
        language: "json"
      }
    }
    

    Now, the result of the operation is used to execute the callback function. Generally, you want it to be structured like this:

    pm.sendRequest(request, (err, response) => {
      if (err) {
        // handle error
      }
      if (response) {
        // handle success
      }
    })
    

    Storing Cookies in Postman (using a Jar)

    You have received the response with the token, and you have parsed the response to retrieve the value. Now what?

    You cannot store Cookies directly as it they were simple variables. Instead, you must store Cookies in a Jar.

    Postman allows you to programmatically operate with cookies only by accessing them via a Jar (yup, pun intended!), that can be initialized like this:

    const jar = pm.cookies.jar()
    

    From here, you can add, remove or retrieve cookies by working with the jar object.

    To add a new cookie, you must use the set() method of the jar object, specifying the domain the cookie belongs to, its name, its value, and the callback to execute when the operation completes.

    const jar = pm.cookies.jar()
    
    jar.set(
      "add-your-domain-here.com",
      "MyCustomCookieName",
      newToken,
      (error, cookie) => {
        if (error) {
          console.error(`An error occurred: ${error}`)
        } else {
          console.log(`Cookie saved: ${cookie}`)
        }
      }
    )
    

    You can try it now: execute a request, have a look at the console logs, and…

    CookieStore: programmatic access  is denied

    We’ve received a strange error:

    An error occurred: Error: CookieStore: programmatic access to “add-your-domain-here.com” is denied

    Wait, what? What does “programmatic access to X is denied” mean, and how can we solve this error?

    For security reasons, you cannot handle cookies via code without letting Postman know that you explicitly want to operate on the specified domain. To overcome this limitation, you need to whitelist the domain associated with the cookie so that Postman will accept that the operation you’re trying to achieve via code is legit.

    To enable a domain for cookies operations, you first have to navigate to the headers section of any request under the collection and click the Cookies button.

    Headers section in a Postman request

    From here, select Domains Allowlist:

    Cookies list page

    Finally, add your domain to the list of the allowed ones.

    Allowed domains list

    Now Postman knows that if you try to set a cookie via code, it’s because you actively want it, allowing you to add your cookies to the jar.

    If you open again the Cookie section (see above), you will be able to see the current values for the cookies associated with the domain:

    Domain-related cookies in Postman

    Further readings

    Clearly, we’ve just scratched the surface of what you can do with pre-request scripts in Postman. To learn more, have a look at the official documentation:

    🔗 Write pre-request scripts to add dynamic behavior in Postman | Postman docs

    This article first appeared on Code4IT 🐧

    If you want to learn more about how to use the Jar object and what operations are available, you can have a look at the following link:

    🔗 Scripting with request cookie | Postman docs

    Wrapping up (with complete example)

    In this article, we learned what pre-request scripts are, how to execute a POST request passing a JSON object as a body, and how to programmatically add a Cookie in Postman by operating on the Jar object.

    For clarity, here’s the complete code I used in my pre-request script.

    const tokenUrl = pm.variables.get("TokenUrl")
    const username = pm.variables.get("ClientID")
    const password = pm.variables.get("ClientSecret")
    
    var authBody = {
      UserName: username,
      Password: password,
    }
    
    const getTokenRequest = {
      method: "POST",
      url: tokenUrl,
      body: {
        mode: "raw",
        raw: JSON.stringify(authBody),
        options: {
          raw: {
            language: "json",
          },
        },
      },
    }
    
    pm.sendRequest(getTokenRequest, (err, response) => {
      if (err) {
        throw new Error(err)
      }
      if (response) {
        var jresponse = response.json()
    
        var newToken = jresponse["Token"]
    
        console.log("token: ", newToken)
    
        if (newToken) {
          const jar = pm.cookies.jar()
    
          jar.set(
            "add-your-domain-here.com",
            "MyCustomCookieName",
            newToken,
            (error, cookie) => {
              if (error) {
                console.error(`An error occurred: ${error}`)
              } else {
                console.log(`Cookie saved: ${cookie}`)
              }
            }
          )
        } else {
          throw new Error("Token not available")
        }
      }
    })
    

    Notice that to parse the response from the authentication endpoint I used the .json() method, that allows me to access the internal values using the property name, as in jresponse["Token"].

    I hope you enjoyed this article! Let’s keep in touch on Twitter or LinkedIn! 🤜🤛

    Happy coding!

    🐧





    Source link