1
\$\begingroup\$

I have a WCF REST POST that has JSON data as input,

IService.cs:

 [OperationContract]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)]     
void ImportJSON(Stream request);

IService.svc:

 public void ImportJSON(Stream request)
    {
        using (var reader = new StreamReader(request))
        {

            var resultStream = reader.ReadToEnd();
            var model = JsonConvert.DeserializeObject<dynamic>(resultStream);
            var resHeaders = model.Headers;
            var resValues = model.Values;
            string str = "";
            string strValues = "";
            foreach (var item in resHeaders)
            {
                str = str + item.Header + ";";
            }
            var stringBuilder = new StringBuilder();
            stringBuilder.AppendLine(str);
            foreach (var item in resValues)
            {
                strValues = item.value + ";";
                stringBuilder.AppendLine(strValues);
                strValues = "";
            }
            System.Guid guid = Guid.NewGuid();
            var path = HttpContext.Current.Server.MapPath("~/App_Data/tmp/" + guid.ToString() + ".csv");
            using (StreamWriter writetext = new StreamWriter(path))
            {
                writetext.WriteLine(stringBuilder);
            }             
        }
    }

An exemple of JSON data:

{
    "Headers": [{"Header":"CA"},{"Header":"PE"},{"Header":"AMOUNT"}],
    "Values": [{"value":"toto;tata;titi"}, {"value":"A;2019;S100"}, {"value":"A;2019;S100"}, {"value":"A;2019;S300"},
                {"value":"A;2013;S23"}, {"value":"A;2013;S200"}, {"value":"A;2013;S200"}, {"value":"A;2019;S100"}]  
}

In fact, I don't use any classe : I use anonyme data directly, and I use dynamic on the Deserialization JSON,

I have my result as I wish : I get all the data from JSON then I saved all data in a txt/csv file, My result:

CA;PE;AMOUNT;
toto;tata;titi;
A;2019;S100;
A;2019;S100;
A;2019;S300;
A;2013;S23;
A;2013;S200;
A;2013;S200;
A;2019;S100;

Is my code is correct?

Are there any impact affect performance ?

And is there any problem if I have very long JSON data ?

And if there are any advise or feedback for my code.

\$\endgroup\$
  • \$\begingroup\$ Is my code is correct? you'd better be confident it works as intended, lest it was off topic at CR@SE. Code/program/algorithm correctness is a topic of computer science - over at CS@SE they'd prompt you to try and prove your code correct. \$\endgroup\$ – greybeard Dec 19 '19 at 18:06
  • \$\begingroup\$ Thanks for your reply.In fact, I am confident but maybe I ask the wrong answer.The question is : is my code is good performance level and if I must rectify anything \$\endgroup\$ – IngTun2018 Dec 20 '19 at 8:12
1
\$\begingroup\$

Is my code is correct?

Yes, but it needs just some tweaks in some areas. The only part I need to noted is when you declaring a StringBuilder and you're creating multiple string objects then append them to the StringBuilder. for this, you misused the StringBuilder, and what you need to do, is to use StringBuilder directly, and don't create strings outside the StringBuilder. Everything else looks fine to me.

for the dynamic part, it's fine to use dyanmic then using strong typed objects if you know the exact structure of the returned JSON. You'll only lose some of debugging auto-complete feature (aka code IntelliSense), and everything must be written manually. If you don't use any castings (like what you've know), the datatype will be assigned at run-time (the compiler will decide it). But it'll be better to cast objects when needed.

Are there any impact affect performance ?

Performance-wise, it actually performs almost same as strong typed objects with a slight margin of difference, you'll hardly even notice it. So, don't think too much about it.

And if there are any advise or feedback for my code,

Yes, you can simplify it :

public void ImportJSON(Stream request)
{
    using (var reader = new StreamReader(request))
    {

        var model = JsonConvert.DeserializeObject<dynamic>(reader.ReadToEnd());

        var stringBuilder = new StringBuilder(string.Empty);

        foreach (var item in model.Headers)
        {
            stringBuilder.Append($"{(string)item.Header};");
        }

        stringBuilder.AppendLine();

        foreach (var item in model.Values)
        {
            stringBuilder.AppendLine($"{(string)item.value};");
        }

        var path = HttpContext.Current.Server.MapPath($"~/App_Data/tmp/{Guid.NewGuid().ToString()}.csv");

        // you can use it directly in new StreamWriter(HttpContext.Current.Server.MapPath($"~/App_Data/tmp/{Guid.NewGuid().ToString()}.csv")) 

        using (var writetext = new StreamWriter(path))
        {
            writetext.WriteLine(stringBuilder);
        }

    }
}  
\$\endgroup\$
  • \$\begingroup\$ It is very clear! Thanks a lot for all the advices,I rectify my code with an object and remove the string, Thank you so much @iSR5 \$\endgroup\$ – IngTun2018 Dec 20 '19 at 8:52
0
\$\begingroup\$

Thanks a lot for all explanation,it is very clear,

I rectify my code to use strong typed objects :

IService.svc:

 public void ImportJSON(Stream request)
{
       using (var reader = new StreamReader(request))
        {                
            var model = JsonConvert.DeserializeObject<DataImportJsonObject>(reader.ReadToEnd());
            var stringBuilder = new StringBuilder(string.Empty);
            foreach (var item in model.Headers)
            {                   
                stringBuilder.Append($"{item.header};");
            }
            stringBuilder.AppendLine();
            foreach (var item in model.Values)
            {
                stringBuilder.AppendLine($"{item.value};");
            }
            var path = HttpContext.Current.Server.MapPath($"~/App_Data/tmp/{Guid.NewGuid().ToString()}.csv");               
            if (stringBuilder.ToString().EndsWith(Environment.NewLine))
            {
                stringBuilder.Remove(stringBuilder.Length - Environment.NewLine.Length, Environment.NewLine.Length);
            }
            using (var writetext = new StreamWriter(path))
            {
                writetext.WriteLine(stringBuilder);
            }
        }
    }
 }

And my classes:

   [DataContract]
    public class Header
    {
        [DataMember]
        public string header { get; set; }
    }
    [DataContract]
    public class Value
    {
        [DataMember]
        public string value { get; set; }
    }
    [DataContract]
    public class DataImportJsonObject
    {
        [DataMember]
        public List<Header> Headers { get; set; }
        [DataMember]
        public List<Value> Values { get; set; }
    }
\$\endgroup\$
0
\$\begingroup\$

I belive your WCF service should always be accepting the Models. Like JSON code should be converted into Entity Models and then pass to WCF service.

In this way you can make your code loosely coupled.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.