I have a class containing:
[Serializable]
public class ClsStatus
{
public byte[] Image { get; set; }
public string Status { get; set; }
public List<string> Servers { get; set; }
}
Now i am doing:
System.Drawing.Image image = null;
byte[] imageBytes = null;
// Create an image of the chart.
using (MemoryStream s = new MemoryStream())
{
chart.ExportToImage(s, System.Drawing.Imaging.ImageFormat.Jpeg);
image = System.Drawing.Image.FromStream(s);
imageBytes = s.ToArray();
}
ClsStatus status = new ClsStatus();
List<string> servers = new List<string>();
servers.Add("Server1");
servers.Add("Server2");
servers.Add("Server2");
status.Image = imageBytes;
status.Status = "Up & Running";
status.Servers = servers;
//XML Serialization
XmlDocument doc = new XmlDocument();
XmlSerializer serializer = new XmlSerializer(status.GetType());
MemoryStream stream = new MemoryStream();
try
{
serializer.Serialize(stream, status);
stream.Position = 0;
doc.Load(stream);
Response.ContentType = "text/xml";
Response.Clear();
Response.Write(doc.InnerXml);
}
catch
{
throw;
}
My Desired out put and what i am getting fro the above code is here:
http://i.stack.imgur.com/YgKgH.jpg
Is there any one who can help me in solving my issue?
Regards,
Mohin
XML is pretty much a text-based format, which means you're not going to be able to "see the image" in your XML document.
The closest you can get is to encode the binary image data into a "text" string (typically through Base64 encoding) and then embed the string into the XML document. That's exactly what you're getting now.
Related
I'm trying to learn how mongodb store each and every data type under the hood.
I have found it stores data in BSON format.
In order to store binary data in mongodb, it requires users to convert byte array in base64 then pass that base64 converted string to BinData(subtype,content in base64) class.
What is the reason behind storing binary data in this format. Why mongodb doesn't allow us to store raw binary?
According to the BSON specification, binary is stored as a 32-bit length followed by a type identifier and then by a series of bytes. Not a base64 string, bytes.
A shamelessly copied function from codementor.io shows that in languages that have the capability to handle binary data directly, it can be directly stored:
public class Question
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Category { get; set; }
public string Type { get; set; }
public string QuestionHeading { get; set; }
public byte[] ContentImage { get; set; }
public decimal Score { get; set; }
}
public class QuestionService
{
private readonly IMongoCollection<Question> _questions;
public QuestionService(IDatabaseSettings settings)
{
var client = new MongoClient("<YOUR CONNECTION STRING>");
var database = client.GetDatabase("<YOUR DATABASE NAME>");
_questions = database.GetCollection<Question>("Questions");
}
public Question Get(string id)
{
var result = _questions.Find(
q => q.Id == id).FirstOrDefault();
return result;
}
public Question Create(Question question)
{
_questions.InsertOne(question);
return question;
}
}
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
var service = new QuestionService();
// CONVERT JPG TO A BYTE ARRAY
byte[] binaryContent = File.ReadAllBytes("image.jpg");
var question = new Question
{
Category = "Children's Quizzes",
Type = "Puzzles",
QuestionHeading = "Find the cat in the below image",
ContentImage = binaryContent, // Store the byte array in ContentImage property
Score = 10
};
service.Create(question);
}
BinData() is a constructor that permits specifying binary data directly in the source code text.
geeksforgeeks.org has an example for how to Upload and Retrieve Image on MongoDB using Mongoose
So far I have used this code to grab our azure devops project data. I have poked around the data and any urls returned looking for data related to pipelines and found nothing
string credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalAccessToken)));
ListofProjectsResponse.Projects viewModel = null;
//use the httpclient
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://acme.visualstudio.com"); //url of our account
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
HttpResponseMessage response = client.GetAsync("/DefaultCollection/_apis/projects?stateFilter=All&api-version=1.0").Result;
//check to see if we have a succesfull respond
if (response.IsSuccessStatusCode)
{
//set the viewmodel from the content in the response
viewModel = response.Content.ReadAsAsync<ListofProjectsResponse.Projects>().Result;
}
}
public class ListofProjectsResponse
{
public class Projects
{
public int count { get; set; }
public Value[] value { get; set; }
}
public class Value
{
public string id { get; set; }
public string name { get; set; }
public string description { get; set; }
public string url { get; set; }
public string state { get; set; }
}
}
Did some changes on your main work code and share it below, just have a try:
string credentials = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", "{PAT}")));
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://acme.visualstudio.com"); //url of our account
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", credentials);
//HttpResponseMessage response = client.GetAsync("/_apis/projects?stateFilter=All&api-version=1.0").Result;
using (HttpResponseMessage response = await client.GetAsync("/ForMerlin/_apis/projects"))
{
response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
// Console.WriteLine(response);
}
For BaseAddress, what you were using is an old URL format which like https://{org name}.visualstudio.com. This URL format has contain the organization name in it, so you can ignore the organization name when calling GetAsync. Just make it be /_apis/projects?stateFilter=All&api-version=1.0 is okay.
The way I found is to enumerate the builds for each project using the same code as above except
HttpResponseMessage response = client.GetAsync("/{org name}/{project
name}/_apis/build/builds?api-version=5.1").Result;
The url for each build will return a json collection with any azure build pipline data inside of "queue"
I have .NET Core Web App with the following controller:
[HttpPost]
public async Task<IActionResult> Update(StudentDetailsViewModel vm)
{
var tokenNo = HttpContext.Session.GetString("Token");
vm.ID = Convert.ToInt32(HttpContext.Session.GetString("StudentId"));
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokenNo);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var putStudentUrl = _appSettings.Value.Apis.GSRTCApi.Url + _appSettings.Value.Apis.GSRTCApi.StudentsEndpoint + vm.ID;
var settings = new JsonSerializerSettings();
var stringData = JsonConvert.SerializeObject(vm);
var contentData = new StringContent(stringData, Encoding.UTF8, "application/json");
var response = await client.PutAsync(putStudentUrl, contentData); // contentData);
return RedirectToAction("Index", "Home");
}
The controller calls my Web API and everything works fine until I upload a file through my html form. When this happens the file is picked up in the IFormFile property of the StudentDetailsViewModel on the client side but when the API call is made the whole object is null. The API controller is:
[HttpPut("{id}")]
public async Task<IActionResult> Put(int? id, [FromBody]StudentViewModel student)
{
// API operations here
}
My suspicion is that I am not serializing the StudentDetailsViewModel object properly since I have a property IFormFile, which is an interface. However, I am not sure exactly how I need to customize the Json.Newsoft object.
For sending IFormFile, you need to use FromForm which is default when you remove FromBody and MultipartFormDataContent.
Here are complete steps:
Web App Model
public class StudentDetailsViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public IFormFile File { get; set; }
}
Web App Controller
public async Task<IActionResult> Update(StudentDetailsViewModel vm)
{
HttpClient client = new HttpClient();
var putStudentUrl = #"url";
byte[] data;
using (var br = new BinaryReader(vm.File.OpenReadStream()))
{
data = br.ReadBytes((int)vm.File.OpenReadStream().Length);
}
ByteArrayContent bytes = new ByteArrayContent(data);
MultipartFormDataContent multiContent = new MultipartFormDataContent();
multiContent.Add(bytes, "file", vm.File.FileName);
multiContent.Add(new StringContent(vm.Id.ToString()),"Id");
multiContent.Add(new StringContent(vm.Name), "Name");
var response = await client.PutAsync(putStudentUrl, multiContent);
return RedirectToAction("Index", "Home");
}
Web API Model
public class StudentViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public IFormFile File { get; set; }
}
Web API Controller
[HttpPut("{id}")]
public async Task<IActionResult> Put(int? id,StudentViewModel student)
{
using (var stream = new FileStream(#"file path", FileMode.Create))
{
await student.File.CopyToAsync(stream);
}
return Ok();
}
Pay attention to multiContent.Add(bytes, "file", vm.File.FileName);, the second parameter is the name for IFormFile field.
In our project, we are getting response from wcf service in xml format which we want to deserialize using datacontract serializer.
Below is the xml response.
<ArrayOfCustomerData xmlns="http://schemas.datacontract.org/2004/07/PACRM.QCT">
<CustomerData>
<AccountID>String content</AccountID>
<AccountName1>String content</AccountName1>
</CustomerData>
<CustomerData>
<AccountID>String content</AccountID>
<AccountName1>String content</AccountName1>
</CustomerData>
</ArrayOfCustomerData>
We have written the following DataContract class to deserialize the xml.
[DataContract]
public class ArrayOfCustomerData
{
[DataMember(Name="CustomerData")]
public CustomerData[] customerData { get; set; }
}
[DataContract]
public class CustomerData
{
[DataMember(IsRequired = true, Name = "AccountID")]
public string new_AccountID { get; set; }
[DataMember(IsRequired = true, Name = "AccountName1")]
public string new_accountname1 { get; set; }
}
C# code for deserialization is given below.
DataContractSerializer dcs = new DataContractSerializer(typeof(ArrayOfCustomerData));
ArrayOfCustomerData data=new ArrayOfCustomerData();
using (var stream = new StreamReader(response.GetResponseStream()))
{
var text=stream.ReadToEnd();
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(text));
XmlDictionaryWriter xdw = XmlDictionaryWriter.CreateTextWriter(ms, Encoding.UTF8);
dcs.WriteObject(xdw, data);
}
when i check the data.cusotmerData, it is returning null.
Can anyone please provide solution for this issue? Thanks!
You don't need the class ArrayOfCustomerData - that is just adding an unecessary extra element to the expected XML. You can use CustomerData[], as the type passed to the DataContractSerializer constructor, as shown below:
public class StackOverflow_24673714
{
const string XML = #"<ArrayOfCustomerData xmlns=""http://schemas.datacontract.org/2004/07/PACRM.QCT"">
<CustomerData>
<AccountID>String content ID 1</AccountID>
<AccountName1>String content name 1</AccountName1>
</CustomerData>
<CustomerData>
<AccountID>String content ID 2</AccountID>
<AccountName1>String content name 2</AccountName1>
</CustomerData>
</ArrayOfCustomerData>";
[DataContract(Name = "CustomerData", Namespace = "http://schemas.datacontract.org/2004/07/PACRM.QCT")]
public class CustomerData
{
[DataMember(IsRequired = true, Name = "AccountID")]
public string new_AccountID { get; set; }
[DataMember(IsRequired = true, Name = "AccountName1")]
public string new_accountname1 { get; set; }
}
public static void Test()
{
var ms = new MemoryStream();
var ws = new XmlWriterSettings { Indent = true, IndentChars = " ", OmitXmlDeclaration = true, Encoding = Encoding.UTF8 };
var w = XmlWriter.Create(ms, ws);
var dcs = new DataContractSerializer(typeof(CustomerData[]));
var obj = new CustomerData[] {
new CustomerData { new_AccountID = "String content 1", new_accountname1 = "String content 2" },
new CustomerData { new_AccountID = "String content 3", new_accountname1 = "String content 4" }
};
dcs.WriteObject(w, obj);
w.Flush();
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
ms = new MemoryStream(Encoding.UTF8.GetBytes(XML));
var cds = (CustomerData[])dcs.ReadObject(ms);
Console.WriteLine(cds.Length);
foreach (var cd in cds)
{
Console.WriteLine(" {0} - {1}", cd.new_AccountID, cd.new_accountname1);
}
}
}
Can anyone point me to a working example of how to POST JSON to a RESTful API (e.g. Web API) using Windows Phone 8? I have a working example for GET but can't seem to find any working examples for POST. All of the POST examples I've found for C# don't work on Windows Phone 8 (due to the stripped down .NET framework).
Ok, I was finally able to come up with a working solution so I wanted to post it back for completeness. However, if anyone knows of a better way to do this in Windows Phone 8, I'd love to see it!
public void SendPost(Uri uri, string json)
{
var webClient = new WebClient();
webClient.Headers[HttpRequestHeader.ContentType] = "application/json";
webClient.UploadStringCompleted += this.sendPostCompleted;
webClient.UploadStringAsync(uri, "POST", json);
}
private void sendPostCompleted(object sender, UploadStringCompletedEventArgs e)
{
// Handle result
Console.WriteLine("HTTP POST Result: {0}", e.Result);
}
The best way to do that would be to use Restsharp:
Dim client As New RestSharp.RestClient("https://stuff.com/api/")
Dim req As New RestSharp.RestRequest("dothings", Method.POST)
req.RequestFormat = DataFormat.Json
req.AddBody(New reqAuth With {.param1 = "stuff1", .param2= "stuff2"})
client.ExecuteAsync(req, Sub(res)
Console.WriteLine(res.Content)
End Sub)
string email = txtEmailAddress.Text;
string password = txtPassword.Text;
string confirmPassword = txtConfirmPassword.Text;
string dd = txtDD.Text;
string mm = txtMM.Text;
string yyyy = txtYYYY.Text;
UserDetails ud = new UserDetails
{
DateofBirth = DateTime.Now.ToString(),
EmailAddress=email,
Password=password,
ProfileImage="",
UserID="0"
};
WebClient wc = new WebClient();
wc.Headers["Content-Type"] = "application/json";
MemoryStream ms = new MemoryStream();
DataContractJsonSerializer serializertoUpload = new DataContractJsonSerializer(typeof(UserDetails));
serializertoUpload.WriteObject(ms, ud);
string data = Encoding.UTF8.GetString(ms.ToArray(), 0, (int)ms.Length);
wc.UploadStringAsync(new Uri("<wcfserviceurl>"), "POST", data);
Here is the definition of UserDetails class
public class UserDetails
{
public string UserID { get; set; }
public string EmailAddress { get; set; }
public string Password { get; set; }
public string DateofBirth { get; set; }
public string ProfileImage { get; set; }
}
public async void makeRequest(String resourceUri)
{
HttpClient httpClient = new HttpClient();
try
{
HttpResponseMessage response = await httpClient.GetAsync(resourceUri);
}
catch (HttpRequestException hre)
{
Console.Write(hre.Message);
}
catch (TaskCanceledException)
{
}
}
remember to add Nuget packages: httpclient