AM reading data from port in the form of bytes.my data will be like
<book name="xxx">
<title>First</title>
</book>
and i want this data to pass in
var xml:XML=new XML();
to show in the grid in run time of my desktop application.When i pass the data
var socket:Socket = event.target as Socket;
var bytes:ByteArray = new ByteArray();
socket.readBytes(bytes);
var xml:XML=new XML(bytes);
its not working. but when i pass
var xml:XML=new XML("<book name="xxx"><title>First</title></book>");
is works fine.
please guide me to get solve.
If you are only going to be using the socket for XML data I suggest you have a look at the XMLSocket.
An XML object does not expect to receive bytes in its constructor, which you are currently giving it. That's the reason why it isn't working.
The XML class uses the global XML() converter function to read the contents of the data. This will not understand a byteArray, so you will need to convert your byteArray to something more readable. You could try (untested):
var xml:XML=new XML(bytes.readUTFBytes(bytes.length));
You can load your XML file by using an URLRequest. With this request you can load your data and with a eventlistener you can use the loaded data to parse it into XML.
Here's an example.
protected function getXMLfile():void
{
// TODO Auto-generated method stub
try{
var req:URLRequest = new URLRequest("yourURL");
var loader:URLLoader = new URLLoader(req);
loader.addEventListener(Event.COMPLETE, loaderCompleteHandler);
loader.load(req);
}
catch(err:Error){
Alert.show(err.message);
}
}
private function loaderCompleteHandler(evt:Event):void {
try {
var niveau:uint = 0;
var xmlFile:XML = new XML(evt.target.data);
} catch (err:Error) {
Alert.show("Could not parse the XML file.");
}
}
This should work fine. For more information you can contact me.
Hope this will help you.
Related
I am creating an app where user can upload their text file and find out about its most used word.
I have tried to follow this doc to get used to the idea of using AZURE STORAGE BLOBS - https://learn.microsoft.com/en-us/azure/storage/blobs/storage-quickstart-blobs-dotnet
But I am super newbie and having a hard time figuring it out how to adapt those blobs methods for my POST method.
This my sudo - what I think I need in my controller and what needs to happen when POST method is triggered.
a.No need for DELETE or PUT, not replacing the data nor deleting in this app
b.Maybe need a GET method, but as soon as POST method is triggered, it should pass the text context to the FE component
POST method
connect with azure storage account
if it is a first time of POST, create a container to store the text file
a. how can I connect with the existing container if the new container has already been made? I found this, but this is for the old CloudBlobContainer. Not the new SDK 12 version.
.GetContainerReference($"{containerName}");
upload the text file to the container
get the chosen file's text content and return
And here is my controller.
public class HomeController : Controller
{
private IConfiguration _configuration;
public HomeController(IConfiguration Configuration)
{
_configuration = Configuration;
}
public IActionResult Index()
{
return View();
}
[HttpPost("UploadText")]
public async Task<IActionResult> Post(List<IFormFile> files)
{
if (files != null)
{
try
{
string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
string containerName = "textdata" + Guid.NewGuid().ToString();
BlobContainerClient containerClient = await blobServiceClient.CreateBlobContainerAsync(containerName);
//Q. How to write a if condition here so if the POST method has already triggered and container already created, just upload the data. Do not create a new container?
string fileName = //Q. how to get the chosen file name and replace with newly assignmed name?
string localFilePath = //Q. how to get the local file path so I can pass on to the FileStream?
BlobClient blobClient = containerClient.GetBlobClient(fileName);
using FileStream uploadFileStream = System.IO.File.OpenRead(localFilePath);
await blobClient.UploadAsync(uploadFileStream, true);
uploadFileStream.Close();
string data = System.IO.File.ReadAllText(localFilePath, Encoding.UTF8);
//Q. If I use fetch('Home').then... from FE component, will it receive this data? in which form will it receive? JSON?
return Content(data);
}
catch
{
//Q. how to use storageExeption for the error messages
}
finally
{
//Q. what is suitable to execute in finally? return the Content(data) here?
if (files != null)
{
//files.Close();
}
}
}
//Q. what to pass on inside of the Ok() in this scenario?
return Ok();
}
}
Q1. How can I check if the POST method has been already triggered, and created the Container? If so how can I get the container name and connect to it?
Q2. Should I give a new assigned name to the chosen file? How can I do so?
Q3. How can I get the chosen file's name so I can pass in order to process Q2?
Q4. How to get the local file path so I can pass on to the FileStream?
Q5. How to return the Content data and pass to the FE? by using fetch('Home').then... like this?
Q6. How can I use storageExeption for the error messages
Q7. What is suitable to execute in finally? return the Content(data) here?
Q8. What to pass on inside of the Ok() in this scenario?
Any help is welcomed! I know I asked a lot of Qs here. Thanks a lot!
Update: add a sample code, you can modify it as per your need.
[HttpPost]
public async Task<IActionResult> SaveFile(List<IFormFile> files)
{
if (files == null || files.Count == 0) return Content("file not selected");
string connectionString = "xxxxxxxx";
BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString);
string containerName = "textdata" + Guid.NewGuid().ToString();;
BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient(containerName);
containerClient.CreateIfNotExists();
foreach (var file in files)
{
//use this line of code to get file name
string fileName = Path.GetFileName(file.FileName);
BlobClient blobClient = containerClient.GetBlobClient(fileName);
//directly read file content
using (var stream = file.OpenReadStream())
{
await blobClient.UploadAsync(stream);
}
}
//other code
return View();
}
Original answer:
When using List<IFormFile>, you should use foreach code block to iterate each file in the list.
Q2. Should I give a new assigned name to the chosen file? How can I do
so?
If you want to keep the file original name, in the foreach statement like below:
foreach (var file in myfiles)
{
Path.GetFileName(file.FileName)
//other code
}
And if you want to assign a new file name when uploaded to blob storage, you should define the new name in this line of code: BlobClient blobClient = containerClient.GetBlobClient("the new file name").
Q3. How can I get the chosen file's name so I can pass in order to
process Q2?
refer to Q2.
Q4. How to get the local file path so I can pass on to the FileStream?
You can use code like this: string localFilePath = file.FileName; to get the path, and then combine with the file name. But there is a better way, you can directly use this line of code Stream uploadFileStream = file.OpenReadStream().
Q5. How to return the Content data and pass to the FE? by using
fetch('Home').then... like this?
Not clear what's it meaning. Can you provide more details?
Q6. How can I use storageExeption for the error messages
The storageExeption does not exist in the latest version, you should install the older one.
You can refer to this link for more details.
#Ivan's answer is what the documentation seems the recommend; however, I was having a strange issue where my stream was always prematurely closed before the upload had time to complete. To anyone else who might run into this problem, going the BinaryData route helped me. Here's what that looks like:
await using var ms = new MemoryStream();
await file.CopyToAsync(ms);
var data = new BinaryData(ms.ToArray());
await blobClient.UploadAsync(data);
This is actually a 2-part question related directly to .net core 3.0 and specifically with PipeWriter: 1) How should I read in the HttpResponse body? 2) How can I update the HttpResponse? I'm asking both questions because I feel like the solution will likely involve the same understanding and code.
Below is how I got this working in .net core 2.2 - note that this is using streams instead of PipeWriter and other "ugly" things associated with streams - eg. MemoryStream, Seek, StreamReader, etc.
public class MyMiddleware
{
private RequestDelegate Next { get; }
public MyMiddleware(RequestDelegate next) => Next = next;
public async Task Invoke(HttpContext context)
{
var httpResponse = context.Response;
var originalBody = httpResponse.Body;
var newBody = new MemoryStream();
httpResponse.Body = newBody;
try
{
await Next(context);
}
catch (Exception)
{
// In this scenario, I would log out the actual error and am returning this "nice" error
httpResponse.StatusCode = StatusCodes.Status500InternalServerError;
httpResponse.ContentType = "application/json"; // I'm setting this because I might have a serialized object instead of a plain string
httpResponse.Body = originalBody;
await httpResponse.WriteAsync("We're sorry, but something went wrong with your request.");
return;
}
// If everything worked
newBody.Seek(0, SeekOrigin.Begin);
var response = new StreamReader(newBody).ReadToEnd(); // This is the only way to read the existing response body
httpResponse.Body = originalBody;
await context.Response.WriteAsync(response);
}
}
How would this work using PipeWriter? Eg. it seems that working with pipes instead of the underlying stream is preferable, but I can not yet find any examples on how to use this to replace my above code?
Is there a scenario where I need to wait for the stream/pipe to finish writing before I can read it back out and/or replace it with a new string? I've never personally done this, but looking at examples of PipeReader seems to indicate to read things in chunks and check for IsComplete.
To Update HttpRepsonse is
private async Task WriteDataToResponseBodyAsync(PipeWriter writer, string jsonValue)
{
// use an oversized size guess
Memory<byte> workspace = writer.GetMemory();
// write the data to the workspace
int bytes = Encoding.ASCII.GetBytes(
jsonValue, workspace.Span);
// tell the pipe how much of the workspace
// we actually want to commit
writer.Advance(bytes);
// this is **not** the same as Stream.Flush!
await writer.FlushAsync();
}
The old version of this question got too long so by the end of numerous attemts to solve this issue I came up that all can be taken down to a simple question. Why does this produce a SystemObjectDisposed.
private async void PickPhotoButton_OnClicked(object sender, EventArgs e)
{
_globalStream = await DependencyService.Get<IPicturePicker>
().GetImageStreamAsync();
_globalArray = StreamToByteArray(_globalStream);
var gal = new GalleryResource()
{
Pic = _globalArray
};
MemoryObjects.CurrentGallery = gal;
var ctr = HelperMethods.GetInstance<GalleryController>();
await ctr.Post();
}
public byte[] StreamToByteArray(Stream input)
{
using (MemoryStream ms = new MemoryStream())
{
input.CopyTo(ms);
return ms.ToArray();
}
}
The stream arrives from the native side, I turn it into a byte array and pass it into my repository. Everyting work with a dummy byte array so something is wrong with the stream object that possibly gets closed or disposed at point.
The exception is thrown in the repository at this point:
var response = await _client.PostAsync(endPoint, _repService.ConvertObjectToStringContent(obj));
ConvertObjectToStringContent(obj) - not this part of it. From here it actually returns with a value and the byte array is seen inside the debug ie. the byte array stay with a valid lenght all way through.
The only event that does take place when we do finish picking the photo from the library is the following:
void OnImagePickerFinishedPickingMedia(object sender,
UIImagePickerMediaPickedEventArgs args)
{
UIImage image = args.EditedImage ?? args.OriginalImage;
if (image != null)
{
// Convert UIImage to .NET Stream object
NSData data = image.AsJPEG(1);
Stream stream = data.AsStream();
// Set the Stream as the completion of the Task
taskCompletionSource.SetResult(stream);
}
else
{
taskCompletionSource.SetResult(null);
}
imagePicker.DismissModalViewController(true);
}
However it doesn't seem to dispose the stream and even if it did we already got a byte array from it.
Tried even doing this inside Native code
var client = new HttpClient();
var c = new MultipartFormDataContent();
c.Add(new StreamContent(image.AsJPEG(1).AsStream()));
var response = await client.PostAsync(Settings.EndPoint + "api/gallery/", c);
Same error.
I think your problem lies somewhere in this line _byteArray = ToByteArray(_array);
ToByteArray(stream) seems to return you the byte array maybe via conversion from a stream, and this stream might still have a reference to the bytearray. And it might have become disposed.
If it's inside this method, please post it, I wanna knowww
I'm not quite experienced enough to exactly tell what it is about, but maybe my suggestions will be hitting the right spot!
Btw your code looks real clean, I like it!
So, although this issue did come up in the first place with the CrossMedia plugin https://github.com/jamesmontemagno/MediaPlugin it did the same error.
However the error only comes up if you for instance pick a photo like this:
var _mediaFile = await CrossMedia.Current.PickPhotoAsync();
So, when I did this:
var _mediaFile = await CrossMedia.Current.PickPhotoAsync(new
Plugin.Media.Abstractions.PickMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Small,
CompressionQuality = 90,
});
The error went away. No idea why.
My server has an API to upload files and convert them to PDF. Right now, the file gets uploaded, saved to disk and then converted. See the (trimmed down) code below:
public class ConversionController : ApiController {
public async Task<HttpResponseMessage> PostData() {
var root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
await Request.Content.ReadAsMultipartAsync(provider);
var file = provider.FileData.First();
var originalName = file.Headers.ContentDisposition.FileName;
var fileStream = new FileStream(file.LocalFileName, FileMode.Open, FileAccess.Read);
// convert file stream and return the PDF response ...
}
}
As you can see, I read the file to disk but then immediately get a stream for it so I can feed it to our conversion function (which takes a stream). This seems like a waste to save the file to disk every time. So instead of ReadAsMultipartAsync() which saves to disk, I can use ReadAsStreamAsync() which will give me the stream that I can give directly to the conversion function.
The problem that I'm having with ReadAsMultipartAsync() is that I can't figure out how to get the original file name without having the MultipartFileData instance to work with. I know that the name comes with the request as part of the body, but I can't figure out how to access it. How can I get the name of the uploaded file without writing the uploaded file to disk?
You can use MultipartMemoryStreamProvider, for example:
var provider = new MultipartMemoryStreamProvider();
var task = Request.Content.ReadAsMultipartAsync(provider).ContinueWith(t =>
{
var file = provider.Contents.First();
var fileContents = await file.ReadAsByteArrayAsync();
var filename = file.Headers.ContentDisposition.FileName.Replace("\"", string.Empty);
/// do other stuff
return Request.CreateResponse(HttpStatusCode.OK);
});
In this case the content is read as a byte array, but the same applies to streams.
I am new to jquery and don't know to fetch json data from another domain(Cross domain).
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
request.onload = function() {
// ...
};
request.onreadystatechange = handler;
request.send();
}
I found this program from here Ways to circumvent the same-origin policy
This is saying by using above code we can access cross domain json data.
I copied the code. This is saying handler is undefined
I don't know how to define handler .
I also don't know what to write inside request.onload
where I will get the json result
Please help
Thanks in advance
The handler is a function
it should be something like
function handler(){
var response = xhr.responseText;
// do more with your response.
}
Also you xhr should be defined outside of the function createCORSrequest.
See docs on XDR
I know you said you are new to jquery but you should also look into $.getJSON. Its much easier.