0

Im trying call to an action with Ajax and when i have one item request URL going to be like :

http://localhost:xxxx/User/getvarelinje?items=AAAADwCZbrc

And everything going to work, but when i have more items request URL going to be like :

http://localhost:xxxx/User/getvarelinje?items=AAAADwCZbrc=&items=AAAADwCZ0QU=

And than i will get following error :

The input is not a valid Base64 string, since it contains a character that is not a base 64 character, more than two fill characters, or an invalid character among the fill characters.

This is my Ajax:

<script>

    $("#BasketClick").click(function (e) {
        e.preventDefault();
        var holderHTML = '';
        var params = "?";
        var seperator = "";

        for (var i = 0; i < localStorage.length; i++) {

            let key = localStorage.key(i);
            params += seperator + "items=" + key;
            seperator = "&";

        }

        $.ajax({
            type: "GET",
            url: "/User/getvarelinje" + params,
            dataType: 'json',
            success: function (values) {

                console.log(values);
                for (var i = 0; i < values.length; i++) {
                    value = values[i]
                    console.log(value);

                    if (value != null) {

                        holderHTML += '<li>' + value.ItemName + '</li>';
                        holderHTML += '<li>' + value.Description + '</li>';
                    }
                }

             $('#RMABasket').html(holderHTML);
            },
        })

    });

This is my action :

[HttpGet]
public JsonResult getvarelinje(byte[] items) {

    var _getItemsLine = db.namespace.Where(s=>s.timestamp == items)
            .Select(t=>new GetItemslineVM {  Description = t.Description , ItemName = t.No_ })
            .ToList();

    return Json(_getItemsLine, JsonRequestBehavior.AllowGet);
}

And this is my modal :

public class tablenamespace
  {
        [Timestamp]
        public byte[] timestamp { get; set; }
  }

Can anyone please help me :)

  • 1
    you already added the right tag to your question: **base64url**. Normal **base64** encoding causes problems when used in URLs, that's why you should use **base64url** encoding instead. – jps Nov 27 '19 at 11:03
  • @jps my problem is i dont know how it should be done , dats way i just need litte help :) – The Professor and the Madman Nov 27 '19 at 11:12
  • 1
    Any data you put in a query string should be [url encoded](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI). For debugging, you can replace each `=` with the encoded value of `%3D`. Looking at your code, I'm skeptical it will work since you are checking something called timestamp is equal to multiple items? – Crowcoder Nov 27 '19 at 11:34
  • @Crowcoder when i pass one item code will be working , but when its more items URL going to have some characters as http://localhost:xxxx/User/getvarelinje?items=AAAADwCZbrc=&items=AAAADwCZ0QU= – The Professor and the Madman Nov 27 '19 at 11:41
  • 1
    First you should encode the base64 string as a url parameter. Something like this: let key = encodeURIComponent(localStorage.key(i)); – Lutti Coelho Nov 27 '19 at 12:16
  • 1
    Second: your are handle all items as one single array of bytes. Are you sure you want to do that? If not will better if you receive the base64 parameter as a string array and then converts each string to an array of bytes. – Lutti Coelho Nov 27 '19 at 12:19
  • for first , now my url like this : getvarelinje?items=AAAADwCZbrc%3D&items=AAAADwCZ0QU%3D – The Professor and the Madman Nov 27 '19 at 12:21
  • and for second, dat was i did for first time i changed back to string array and how can i converts each string to an array of bytes?! – The Professor and the Madman Nov 27 '19 at 12:22
  • To convert a string to byte[] you can use this function Encoding.Unicode.GetBytes(yourString) or this function Encoding.ASCII.GetBytes(yourString) – Lutti Coelho Dec 03 '19 at 09:44
  • 1
    Did you find an answer for your question? – Lutti Coelho Dec 12 '19 at 11:51
  • @LuttiCoelho yes lutti , i tried another solution :) – The Professor and the Madman Dec 18 '19 at 15:03
  • Could you add your solution as an answer to this question? It will help others users too. – Lutti Coelho Dec 18 '19 at 16:38

1 Answers1

1

In your ajax function, because the values will be send in url, you need to parse your parameters with function encodeURIComponent . Like this:

$("#BasketClick").click(function (e) {
    e.preventDefault();
    var holderHTML = '';
    var params = "?";
    var seperator = "";

    for (var i = 0; i < localStorage.length; i++) {

        let key = encodeURIComponent(localStorage.key(i));
        params += seperator + "items=" + key;
        seperator = "&";

    }

    $.ajax({
        type: "GET",
        url: "/User/getvarelinje" + params,
        dataType: 'json',
        success: function (values) {

            console.log(values);
            for (var i = 0; i < values.length; i++) {
                value = values[i]
                console.log(value);

                if (value != null) {

                    holderHTML += '<li>' + value.ItemName + '</li>';
                    holderHTML += '<li>' + value.Description + '</li>';
                }
            }

         $('#RMABasket').html(holderHTML);
        },
    })

});

In your controller I believe you don't want to join all base64 strings in a single one. So you need handle each one separetedly. Like this:

public JsonResult getvarelinje2(string[] items) 
{
    var temp = new List<byte[]>(); // Create a list for handle each array
    temp.AddRange(items.Select(i => Encoding.Unicode.GetBytes(i))); // Converts each string into one byte array

    // Here you needs to find if there is a better way to compare two byte arrays.
    var _getItemsLine = db.namespace.Where(s => temp.Contains(s))  
                .ToList();

    return Json(_getItemsLine, JsonRequestBehavior.AllowGet);
}
Lutti Coelho
  • 2,134
  • 15
  • 31
  • i tried , but it cant find any results , when its come to here: var _getItemsLine = db.namespace.Where(s => temp.Contains(s)) .ToList(); – The Professor and the Madman Nov 28 '19 at 10:03
  • Are you using entity framework? How do you store this data in you database column? – Lutti Coelho Nov 28 '19 at 14:43
  • yes , is a column in table with timestamp data type and its like this : 0x0000000F00965254 – The Professor and the Madman Nov 29 '19 at 08:44
  • i debug my method and i also debug yours . my method pass byte with 8 digits and than i will find results and than i tried with yours it pass byte with 24 digits and it cant find any results. – The Professor and the Madman Nov 29 '19 at 09:09
  • I tried to decode the base64 string that you share in your example, but it looks like this "n". Can you share the plain text value that you convert to base64 in the frontend. I believe yout will need to convert the byte[] to timestamp too, but i'd like to run a test before make any change on the answer. – Lutti Coelho Nov 29 '19 at 18:33