How to convert an entity?

raysefo

Well-known member
Joined
Feb 22, 2019
Messages
361
Programming Experience
10+
Hi,

I would like to know if I can convert my entity into this format?

C#:
version=V1&signature=5e7efbcf0c9cb2211&ApplicationCode=52e7cf966b724749a

Thanks in advance.
 
You could, but why would you?

Normally most people avoid passing parameters as URLs nowadays because of:
- possibility of URL hacking -- somebody can start calling your WebAPI with invalid data in the query string that you weren't expecting
- potential exposure of sensitive information
- hitting URL length limits with different browsers -- yes, there's an RFC but not everybody follows it
- inconsistent URL encoding/decoding performed by browsers, proxies, and etc. -- yes there's an RFC but not everybody follows it

Anyway if you are only concerned with your specific class is fixed, then building up that query string is a simple concatenation exercise. If you need something generic, see some of the approaches on StackOverflow. All of them basically enumerate the properties of a class and start building a string based on the property names and values.
 
I am trying to generate a request, that's why I needed @Skydiver

C#:
//HTTPWebRequest
var request = (HttpWebRequest) WebRequest.Create("http://test/pinstore/" + url);
request.ContentType = "application/json";
request.Method = "POST";

//Generate Request
string requestString =
                      $"version={productRequest.version}&signature={productRequest.signature}&ApplicationCode={productRequest.ApplicationCode}";

using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
     streamWriter.Write(requestString);
}

HttpWebResponse httpResponse = (HttpWebResponse) (await request.GetResponseAsync());
string json;
using (Stream responseStream = httpResponse.GetResponseStream())
{
     json = new StreamReader(responseStream).ReadToEnd();
}

response = new HttpResponseMessage
{
        StatusCode = System.Net.HttpStatusCode.OK,
        Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json"),
};
                        
                  
return response;
 
Hmmm... if the content type for your request is JSON, why are you sending web forms content?
 
I would like to know if I can convert my entity into this format?
Not directly no. Kinda defeats the purpose of using a DB mapper. No?
I hope you're planning on encoding them urls. Edit, at a second glance, it doesn't look like gamesultan care about decoding if you're not encoding them. What protection do they have to prevent URI hijacking. . .

They should consider some encryption if you ask me. But they're not asking me so who cares i guess.
 
Last edited:
On viewing his code, he doesn't have to worry about the URL hacking and hijacking issues because he is not appending the string as a query string for the URL. Instead he is sending the string as the payload of his HTTP POST.

Personally, follow the KISS and YAGNI principles. If your payload only consists of those 3 fields, or a very limited set of fields across two different classes, then just use the code you have. No need to implement a generic solution that does reflection.

As noted above, you may need to worry about URL encoding, but really depends on what type of payload that game API is expecting.
 
If you are going async for getting the request stream, why are you also going async for getting the response stream? Is it because you believe that the entire response is small enough to come as a single packet when you got the response asynchronously?

Anyway, async here is orthogonal to the main topic of this thread: building up the payload string for your web request to the game web API that you are using.
 
Here is good news for you @Skydiver and @Sheepings :) I tried load test with 2100 users and there is no error. Thank you for all the support and sorry for the troubles I made. One last question I hope, the response may not be small so should I remove await from response?

Here is the code sample:
C#:
//HTTPWebRequest
var request = (HttpWebRequest) WebRequest.Create("http://qa-api.mol.com/pinstore/" + url);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";

var keyValueContent = productRequest.ToKeyValue();
var formUrlEncodedContent = new FormUrlEncodedContent(keyValueContent);
var urlEncodedString = await formUrlEncodedContent.ReadAsStringAsync();

using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
      streamWriter.Write(urlEncodedString);
}

HttpWebResponse httpResponse = (HttpWebResponse) (await request.GetResponseAsync());
string json;
using (Stream responseStream = httpResponse.GetResponseStream())
{
      json = new StreamReader(responseStream).ReadToEnd();
}
                    
            
return response;

Here is the ToKeyValues:

C#:
public static IDictionary<string, string> ToKeyValues(this object metaToken)

{

     if (metaToken == null)

     {

         return null;

     }


     JToken token = metaToken as JToken;

     if (token == null)

     {

         return ToKeyValues(JObject.FromObject(metaToken));

     }


     if (token.HasValues)

     {

         var contentData = new Dictionary<string, string>();


         foreach (var child in token.Children().ToList())

         {

              var childContent = child.ToKeyValues();

              if (childContent != null)

              {

                    contentData = contentData.Concat(childContent).ToDictionary(k => k.Key, v => v.Value);

              }

         }


         return contentData;

}


var jValue = token as JValue;

if (jValue?.Value == null)

{

     return null;

}


var value = jValue?.Type == JTokenType.Date

         ? jValue?.ToString("o", CultureInfo.InvariantCulture)

         : jValue?.ToString(CultureInfo.InvariantCulture);


return new Dictionary<string, string> {{token.Path, value}};

}
 
Since you are returning response on line 23, and not really doing anything with the HttpWebResponse because you just throw away the json string, you might as well just delete lines 15-22.
 
Also as an aside, why do you need lines 8-12? Why not just use CopyToAsync() ?
 
I somehow added missing code, here is the full code:
C#:
//HTTPWebRequest
var request = (HttpWebRequest)WebRequest.Create("http://qa-api.mol.com/pinstore/" + url);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";

var keyValueContent = gameRequest.ToKeyValue();
var formUrlEncodedContent = new FormUrlEncodedContent(keyValueContent);
var urlEncodedString = await formUrlEncodedContent.ReadAsStringAsync();

using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
      streamWriter.Write(urlEncodedString);
}

HttpWebResponse httpResponse = (HttpWebResponse)(await request.GetResponseAsync());
string json;
using (Stream responseStream = httpResponse.GetResponseStream())
{
      json = new StreamReader(responseStream).ReadToEnd();
}

response = new HttpResponseMessage
{
      StatusCode = System.Net.HttpStatusCode.OK,
      Content = new StringContent(json, System.Text.Encoding.UTF8, "application/json"),
};



return response;
 
Why not just use StreamContent on line 25? Just pass in the httpResponse.GetResponseStream(), so that you can get rid of lines 16-20.

Why not just use CopyToAsync() to replace lines 8-13?
 
@Skydiver I don't understand how to use copytoasync?

C#:
//HTTPWebRequest
var request = (HttpWebRequest) WebRequest.Create("http://qa-api.mol.com/pinstore/" + url);
request.ContentType = "application/x-www-form-urlencoded";
request.Method = "POST";

var keyValueContent = productRequest.ToKeyValue();
var formUrlEncodedContent = new FormUrlEncodedContent(keyValueContent);
var urlEncodedString = await formUrlEncodedContent.ReadAsStringAsync();
using (var streamWriter = new StreamWriter(await request.GetRequestStreamAsync()))
{
     streamWriter.Write(urlEncodedString);
}

HttpWebResponse httpResponse = (HttpWebResponse) (await request.GetResponseAsync());
                
response = new HttpResponseMessage
{
     StatusCode = httpResponse.StatusCode,
     Content = new StreamContent(httpResponse.GetResponseStream()),
};
                        
return response;
 
Do you even understand what your lines 8-12 are currently doing? Or did you just copy and paste it from someplace else? All it is doing is copying the contents into the stream. Sounds like a perfect match for a function that is actually named aptly so.
 
Back
Top Bottom