How can I convert Serialized stream to a string? - c#

I need to serialize and deserialize a list and write it on a JSON file to use later.
I successfully desirialize the file but failed to write after serialization. How can I do that?
Here is the code I have written.
StorageFile savedFile = await storageFolder.GetFileAsync("SavedData.json");
string text = await FileIO.ReadTextAsync(savedFile);
var serializer = new DataContractJsonSerializer(typeof(DataFormat));
var ms = new MemoryStream(Encoding.UTF8.GetBytes(text));
List<DataFormat> data = (List<DataFormat>)serializer.ReadObject(ms);
if (data == null)
{
data = new List<DataFormat>();
}
data.Add(new DataFormat
{
firstName = fnbox.Text,
lastName = lnbox.Text,
country = cbox.Text
});
MemoryStream stream = new MemoryStream();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DataFormat));
ser.WriteObject(stream, data);
DataFormat Class -
[DataContract]
public class DataFormat : IEquatable<DataFormat>
{
[DataMember]
public string firstName{ get; set; }
[DataMember]
public string lastName { get; set; }
[DataMember]
public string country { get; set; }
public bool Equals(DataFormat other)
{
if (other == null)
{
return false;
}
return (firstName.Equals(other.firstName));
}
}
Additionally If there is any way to just add lines into an existing
file without replacing all the text, please let me know.

See if the following code is what you need. I'm not so sure whether you mean you don't understand how to write to stream.
private async void Button_Click(object sender, RoutedEventArgs e)
{
Windows.Storage.StorageFolder storageFolder = Windows.Storage.ApplicationData.Current.LocalFolder;
Windows.Storage.StorageFile sampleFile =await storageFolder.GetFileAsync("sample.json");
DataFormat data = new DataFormat();
data.firstName = "Barry";
data.lastName = "Wang";
data.country = "China";
Stream mystream = await sampleFile.OpenStreamForWriteAsync();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(DataFormat));
ser.WriteObject(mystream, data);
}

Here what you need, you can use LosFormatter class - see
https://weblog.west-wind.com/posts/2006/Oct/13/LosFormatter-for-easy-Serialization

Related

How to use streams, to generate csv file, using CsvHelper in .NET Core 3.1?

I am developing an api, which has to return csv file on some endpoint. Here's my controller responsible for csv generation:
[ApiController]
[Route("api/[controller]")]
[Authorize]
public sealed class ReportController : BaseController
{
public ReportController(ICommandBus commandBus,
IQueryBus queryBus)
: base(commandBus, queryBus)
{
}
[HttpGet]
public async Task<IActionResult> GetReportAsync([FromQuery] GenerateReportRequest request)
{
try
{
var report = await QueryBus
.SendAsync<GenerateReportQuery, Report>(new GenerateReportQuery
{
Filters = request.Filters,
ResponseFileFormat = request.ResponseFileFormat,
WithPodOnly = request.WithPodOnly
});
return File(report.Content,
report.Type,
report.Name);
}
catch (Exception e)
{
// ToDo: Handle exception in proper way
return StatusCode(StatusCodes.Status500InternalServerError,
e.Message);
}
}
}
When the request comes to my api, certain handler is invoked, and the csv generation starts in CsvGenerationStrategy class, which is attached below:
public class CsvGenerationStrategy : IReportGenerationStrategy
{
public async Task<Report> GenerateReportAsync(ICollection<ShipmentEntity> shipmentEntities)
{
var shipment = shipmentEntities
.Select(s => (Shipment) s)
.ToList();
await using var memoryStream = new MemoryStream();
await using var streamWriter = new StreamWriter(memoryStream);
await using var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture);
csvWriter.Configuration.Delimiter = ";";
await csvWriter.WriteRecordsAsync(shipment);
var content = memoryStream.ToArray();
var report = new Report
{
Content = content,
Type = ReportConstants.CsvFileType,
Name = ReportConstants.CsvReportFileName
};
return report;
}
private class Shipment
{
[Name(ReportConstants.IssueColumnName)]
public string Issue { get; set; }
[Name(ReportConstants.MaterialReleaseReceiptColumnName)]
public string MaterialReleaseReceipt { get; set; }
[Name(ReportConstants.FreightBillIssueColumnName)]
public string FreightBillIssue { get; set; }
[Name(ReportConstants.InvoiceNumberColumnName)]
public string InvoiceNumber { get; set; }
[Name(ReportConstants.TaxCodeColumnName)]
public string TaxCode { get; set; }
[Name(ReportConstants.ContractorIdColumnName)]
public string ContractorId { get; set; }
[Name(ReportConstants.AddressIdColumnName)]
public string AddressId { get; set; }
[Name(ReportConstants.ContractorNameColumnName)]
public string ContractorName { get; set; }
[Name(ReportConstants.ShipmentCountryColumnName)]
public string ShipmentCountry { get; set; }
public static explicit operator Shipment(ShipmentEntity entity) =>
entity != null
? new Shipment
{
Issue = entity.Issue,
MaterialReleaseReceipt = entity.MaterialReleaseReceipt,
FreightBillIssue = entity.FreightBillIssue,
InvoiceNumber = entity.InvoiceNumber,
TaxCode = entity.TaxCode,
ContractorId = entity.ContractorId,
AddressId = entity.AddressId,
ContractorName = entity.ContractorName,
ShipmentCountry = entity.ShipmentCountry
}
: null;
}
}
The code looks properly, but the behavior of the class is quite strange. In most cases, the generation runs properly, but few times i have noticed a situation, when the MemoryStream object contains no data, even if shipment collection is correct. I believe, such a behavior does not depend on data passed as a parameter. Probably i've made something wrong with the streams. How to use them properly? How to generate csv file correctly using CsvHelper library?
I've found a solution. StreamWriter has to be flushed, after writing records, so now the function looks like:
public async Task<Report> GenerateReportAsync(ICollection<ShipmentEntity> shipmentEntities)
{
var shipment = shipmentEntities
.Select(s => (Shipment) s)
.ToList();
await using var memoryStream = new MemoryStream();
await using var streamWriter = new StreamWriter(memoryStream);
await using var csvWriter = new CsvWriter(streamWriter, CultureInfo.InvariantCulture);
csvWriter.Configuration.Delimiter = ";";
await csvWriter.WriteRecordsAsync(shipment);
await streamWriter.FlushAsync();
var report = new Report
{
Content = memoryStream.ToArray(),
Type = ReportConstants.CsvFileType,
Name = ReportConstants.CsvReportFileName
};
return report;
}
And it works properly :)

Object to base 64 JSON file

I have an object T. I need to send the file representation of it into a web service. Without saving the file to a temp file.
WebService method:
myClient.SendFile(
new SendFileData{
id = "1",
fileName = "Foo",
fileType = "json",
fileContent = base64, // string Base64 variable here
}
To get the Base64 of a file I use :
public static string FileToBase64(string path) => FileToBase64(File.ReadAllBytes(path));
public static string FileToBase64(Byte[] bytes) => Convert.ToBase64String(bytes);
I have made those method to work on a temp file stored in a directory. saving the Json to file using :
using (StreamWriter file = File.CreateText(tempPath))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, _data);
}
And reading it like:
Directory.GetFiles(directory).Where().Select(x=> new {
fi = new FileInfo(f),
name = Path.GetFileNameWithoutExtension(f),
ext = Path.GetExtension(f).Trim('.'),
content = FileBase64Helper.FileToBase64(f)
})
I try to make a in memory file and convert it to b64 like:
public void Demo()
{
var myObject = new CustomType { Id = 1, Label = "Initialisation of a custom object" };
var stringRepresentation =
JsonConvert.SerializeObject(myObject, Formatting.Indented, new JsonSerializerSettings { });
SendFileData dataProjection = new SendFileData { };
var result = FakeClient.SendFile(dataProjection);
}
public class CustomType
{
public string Label { get; set; }
public int Id { get; set; }
}
public static class FakeClient
{
public static bool SendFile(SendFileData data) => true;
}
public class SendFileData
{
public string id { get; set; }
public string fileName { get; set; }
public string fileType { get; set; }
public string fileContent { get; set; }
}
Comparaison between direct convertion and FileReadByte:
var myObject = new CustomType { Id = 1, Label = "Initialisation of a custom object" };
var stringRepresentation = JsonConvert.SerializeObject(myObject, Formatting.Indented, new JsonSerializerSettings { });
var directSerialization = Convert.ToBase64String(Encoding.UTF8.GetBytes(stringRepresentation));
var tempPath = #"test.json";
using (StreamWriter file = File.CreateText(tempPath))
{
JsonSerializer serializer = new JsonSerializer();
serializer.Serialize(file, myObject);
}
var fromFile = FileBase64Helper.FileToBase64(tempPath);
SendFileData dataProjection = new SendFileData { };
var result = FakeClient.SendFile(dataProjection);
Direct serialization:
ew0KICAiTGFiZWwiOiAiSW5pdGlhbGlzYXRpb24gb2YgYSBjdXN0b20gb2JqZWN0IiwNCiAgIklkIjogMQ0KfQ==
From file
eyJMYWJlbCI6IkluaXRpYWxpc2F0aW9uIG9mIGEgY3VzdG9tIG9iamVjdCIsIklkIjoxfQ==
If you're question is as follows and if i understand it correctly:
"Does File.ReadAllBytes add additional information about the file in it's return value, or is the return value equal to just having the content of the file as a byte array?"
Answer:
According to Microsoft Documentation, it will return the content of the file as a byte array.
Hope this helps!
Source: https://learn.microsoft.com/en-us/dotnet/api/system.io.file.readallbytes?view=netframework-4.7.2
EDIT: Decoding the base64, i found this:
The difference in the base64 encoded values is the json formatting, nothing else :D
Direct serialization:
From file:

How to write json format in C# string?

How i cab write a json format in C# string:
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string strNJson = #"{to:'topics/extrafx',notification:{title:{0},text:{1},sound: 'default'}}";
strNJson = string.Format(strNJson, not_title, not_body);
streamWriter.Write(strNJson);
streamWriter.Flush();
}
Please advice?
Json is the text serialisation of an object. So you simply have to create an object with those property and serialise it. To assit in creating the class that represent your object you can simply paste a Valid Json to Json 2 C#.
public class Notification
{
public string title { get; set; }
public string text { get; set; }
public string sound { get; set; }
}
public class RootObject
{
public string to { get; set; }
public Notification notification { get; set; }
}
And use it like :
var item = new RootObject {
to = "topics/extrafx",
notification = new Notification {
title = variableFoo,
text = variableBar,
sound = "default"
}
};
var result = JsonConvert.SerializeObject(item);
Try this version:
string not_title, not_body;
not_title = "title";
not_body = "body";
string strNJson = #"{{'to':'topics/extrafx','notification':{{'title':'{0}','text':'{1}','sound': 'default'}}}}";
strNJson = string.Format(strNJson, not_title, not_body);
private const string DATA = #"{
""uuid"": ""27c0f81c-23bc-4878-a6a5-49da58cd30dr"",
""status"": ""Work"",
""job_address"": ""Somewhere"",
""job_description"": ""Just a Test API CALL, John Mckinley's Job""}";
"" Calling the Data to this one
content = new StringContent(DATA, Encoding.UTF8, "application/json");
You can try this.

Reading content from a file stream c#

I have a web api service that accepts file uploads. The content of the file is a small JSON string like the following:
{ "name":"John", "age":31, "city":"New York" }
How do I get the file content while it is a stream instead of having to save the stream as a file on the web server and then open the file?
The following is my snippet:
byte[] fileData = null;
using(var binaryReader = new BinaryReader(httpRequest.Files[0].InputStream))
{
fileData = binaryReader.ReadBytes(httpRequest.Files[0].ContentLength);
}
I'm using the 4.0 .NET Framework
You can use a StreamReader class. Try this code:
using (var reader = new StreamReader(httpRequest.Files[0].InputStream))
{
var content = reader.ReadToEnd();
var json = JObject.Parse(content);
var name = json["name"];
}
Another option is to create a class for your json (manually or by http://json2csharp.com/):
public class Person
{
public string name { get; set; }
public int age { get; set; }
public string city { get; set; }
}
Then change your code to this:
using (var reader = new StreamReader(httpRequest.Files[0].InputStream))
{
var content = reader.ReadToEnd();
var person = JsonConvert.DeserializeObject<Person>(content);
var name = person.name;
}

How to get UserContactLists from constant contact using c#

I am going to use Constant contact for email marketing. I am not getting how to get userContactList which are all there in my constant contact account.If anyone have any idea please help me.
Thanks in advance
Here is some code I wrote a while ago that returns the user list ID based on the name of an existing user list. its all C# and uses RESTSharp library which you can install inside your VS project using Nuget.
public static string GetContactListIDByListName(string listname)
{
feedData = string.Empty;
id = string.Empty;
name = string.Empty;
status = string.Empty;
modified_date = string.Empty;
created_date = string.Empty;
contact_count = 0;
Stream stream = null;
StreamReader streamReader = null;
var client = new RestClient(ccURL);
var request = new RestRequest("/v2/lists?modified_since=[DATE]&api_key=[API-KEY]", Method.GET);
request.AddHeader("Authorization", "Bearer [ACCESS-TOKEN]");
request.AddHeader("X-Originating-Ip", "[SERVER-IP]");
request.AddHeader("Accept", "application/json");
IRestResponse response = client.Execute(request);
feedData = response.Content;
// DESERIALIZE Mashery JSON Response
byte[] byteArray = Encoding.ASCII.GetBytes(feedData);
MemoryStream myStream = new MemoryStream(byteArray);
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Mashery.GetAllListsDef[]));
object result = serializer.ReadObject(myStream);
Mashery.GetAllListsDef[] jsonObj = result as Mashery.GetAllListsDef[];
foreach (Mashery.GetAllListsDef myResult in jsonObj)
{
if (myResult.name.ToUpper().Equals(listname.ToUpper()))
{
return myResult.id.ToString();
}
}
return "";
}
// JSON Definition For [GET All Lists] End Point Method
[Serializable, XmlRoot("GetAllListsDef"), DataContract(Name = "GetAllListsDef")]
public class GetAllListsDef
{
[XmlElement("id"), DataMember(Name = "id")]
public string id { get; set; }
[XmlElement("name"), DataMember(Name = "name")]
public string name { get; set; }
[XmlElement("status"), DataMember(Name = "status")]
public string status { get; set; }
[XmlElement("created_date"), DataMember(Name = "created_date")]
public string created_date { get; set; }
[XmlElement("modified_date"), DataMember(Name = "modified_date")]
public string modified_date { get; set; }
[XmlElement("contact_count"), DataMember(Name = "contact_count")]
public string contact_count { get; set; }
}

Categories

Resources