|
It's been my experience over the last 16 years of Webforms, Razor, pretty much any Microsoft Web GUI technology to not touch it even with a 10 foot pole. I'll wait for someone else to try it and talk about first and see what they say.
I suppose if one is still using Razor, and wants to get sort of Angular, React like in design, jumping to Blazer may offer a fast solution to learn and deploy.
But most developers haven't even adopted my thoughts of "JQuery is dead", and haven't transitioned to a non JQuery environment or framework. So I can't see those folks giving it up, or being able to pry JQuery out of their hands.
As far as Garbage collection goes, that's another subject that I'm not an expert on, and just OK at. I think Richard is the King of that!
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
jkirkerx wrote: But most developers haven't even adopted my thoughts of "JQuery is dead",
Is it dead?
Yeah I am also seeing that in various situations, they will fight till the end to prove jQuery is best - its OK, we all are the same, I am also like you, I will wait until it picks-up little bit in the market at least, its hard to jump-in here and there. Thanks for answering buddy
|
|
|
|
|
I go to these meet-ups, and listen to experts, and they say that modern browsers all support modern JavaScript. Modern browsers had a mandate to support certain features by a certain year, which was over 6 years ago I think. Modern Javascript does everything JQuery does and better. The argument is that there is no need to have a 4Mb payload to support JQuery, that adds to the initial first page download.
So using a popular library like popper, tether and animate that requires the huge JQuery payload can be replaced with a Modern JavaScript library that is much smaller like 14K, and JavaScript is builtin to the browser to support it.
JQuery was needed when it came out and made life easier, but it's no longer required. For me, making the transition from JQuery to JavaScript was really hard to do.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
This is a much bigger question than a simple forum post can really do justice to. Let's start by breaking down your statement:simpledeveloper wrote: is the MS Blazor going to be the next Client-side programming tool from MS Given that it's due for version 1 release early next year, I would say that this is a fairly safe assumption to make.simpledeveloper wrote: I heard it uses C# to write even client side coding That's correct, but possibly not in the way you are imagining here. We need to start here by understanding that Blazor is targeting web assembly, which we can think of as, effectively, assembly language for browsers. So the C# code targets web assembly (aka WASM), which runs in the browser.simpledeveloper wrote: will it come with Garbage Collection too This is where things get tricky, and why thinking of C# in the way you are used to is more complicated. Blazor does load the garbage collector into wasm (unless things have changed recently, this is the Mono garbage collector), but that is only going to cope with the managed side of the application; what we don't get from web assembly is direct access to the DOM, so we have to rely on a JavaScript interop layer interacting with the DOM, and this is still susceptible to leaks,
|
|
|
|
|
Much better thank you so much my friend
|
|
|
|
|
|
Hello JS experts.
I'm using below code to open base64 encoded pdf file using javascript. It works well with small pdf files below 1MB. But it doesn't work if the file size is greater than 2MB. Please let me know if you have a working code for similar scenario.
var base64 = "base64 content";
let pdfWindow = window.open("");
pdfWindow.document.write("<iframe width='100%' height='100%' src='data:application/pdf;base64, " + base64 + "'></iframe>");
|
|
|
|
|
Are you sure it's the base64 string size?
Think about this. If I were to put a 4 meg image of base64, it will display in a <img /> element.
Perhaps it's when the PDF has 2 or more pages, or an image or something and the browser doesn't know how to handle it.
Or how to handle it within a iFrame.
I think you need to look at the PDF, and study how others are doing it, and perhaps come up with a new plan instead of just asking for code.
Perhaps create a pdf object instead of using an iFrame or embed the object in the frame.
javascript - how to display base64 encoded pdf? - Stack Overflow
If it ain't broke don't fix it
Discover my world at jkirkerx.com
modified 21-Oct-19 18:33pm.
|
|
|
|
|
|
I didn't know that. The Stack post is good info to know.
You just got me thinking about my latest design.
I just designed and coded my new image system on the back end of my experimental project, and used base64.
In the front I use Image Url's to a static location.
Like in my Mongo Document, I keep a copy of the image in base64. So I can drag and drop, or select an image, client script it to base64, and send that to the API for further image processing like square it up, flip it around (iPhone) and scale it down to 1024x1024, then write the base64 to a Mongo document, write it to the website and send the base64 back for preview.
What's cool about this, is that I'm hosting in a Docker container with Kubernetes support, so I can spawn more website containers, and my .Net Core API's will rewrite the images requested from Mongo to the newly created spawned container.
I'm just excited about it, because it's working pretty good so far and it's base64 talk.
At 1024x1024, I'm within the limits.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
var objbuilder = '';
objbuilder += ('<object width="100%" height="100%" data="data:application/pdf;base64,');
objbuilder += (base64PDF);
objbuilder += ('" type="application/pdf" class="internal">');
objbuilder += ('<embed src="data:application/pdf;base64,');
objbuilder += (base64PDF);
objbuilder += ('" type="application/pdf" />');
objbuilder += ('');
Then either add to the existing page or open a new window:
var win = window.open("","_blank","titlebar=yes");
win.document.title = "My Title";
win.document.write('');
win.document.write(objbuilder);
win.document.write('');
layer = jQuery(win.document);
|
|
|
|
|
I have a Web Api that is returning FileStreamResult, I want to download the file that's in zip format, I could able to download if Web Api is returning the raw byte array, but for some reason lead wanted it only from FileStreamResult, can somebody please help me how can I write to a file using the FileStreamResult - thank you. I am putting the code here, the Web Api method which is returning as FileStreamResult, but the client code of javascript functions and react events I am putting which is working but with bytes array, so that somebody can suggest me what modifications I can make to the client script to make work and download the zip file. I need some help please - thank you.
Below is my Web Api Code:
[EnableCors("AnotherPolicy")]
[HttpPost]
public FileStreamResult Post([FromForm] string communityName, [FromForm] string files)
{
var removedInvalidCharsFromFileName = removeInvalidCharsFromFileName(files);
var tFiles = removedInvalidCharsFromFileName.Split(',');
string rootPath = Configuration.GetValue<string>("ROOT_PATH");
string communityPath = rootPath + "\\" + communityName;
byte[] theZipFile = null;
FileStreamResult result = null;
using (MemoryStream zipStream = new MemoryStream())
{
using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
foreach (string attachment in tFiles)
{
var zipEntry = zip.CreateEntry(attachment);
using (FileStream fileStream = new FileStream(communityPath + "\\" + attachment, FileMode.Open))
using (Stream entryStream = zipEntry.Open())
{
fileStream.CopyTo(entryStream);
}
}
}
theZipFile = zipStream.ToArray();
result = new FileStreamResult(zipStream, "application/zip") { FileDownloadName = $"{communityName}.zip" };
}
return result;
}
Here is my React event for the download
handleDownload = (e) => {
e.preventDefault();
var formData = new FormData();
formData.append('communityname', this.state.selectedCommunity);
formData.append('files', JSON.stringify(this.state['checkedFiles']));
let url = clientConfiguration['filesApi.local'];
axios({
method: 'post',
responseType: 'application/blob',
contentType: 'application/blob',
url: url,
data: formData
})
.then(res => {
console.log(res);
console.log(res.data);
let fileName = `${this.state['selectedCommunity']}`
const arrayBuffer = base64ToArrayBuffer(res.data);
createAndDownloadBlobFile(arrayBuffer, fileName, 'zip');
})
.catch(error => {
console.log(error.message);
});
};
Here are the common fuctions I have written in CommonFuncs.js file:
export function createAndDownloadBlobFile(body, filename, extension = 'pdf') {
const blob = new Blob([body]);
const fileName = `${filename}.${extension}`;
if (navigator.msSaveBlob) {
navigator.msSaveBlob(blob, fileName);
} else {
const link = document.createElement('a');
if (link.download !== undefined) {
const url = URL.createObjectURL(blob);
link.setAttribute('href', url);
link.setAttribute('download', fileName);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
}
export function base64ToArrayBuffer(base64) {
const binaryString = window.atob(base64);
const bytes = new Uint8Array(binaryString.length);
return bytes.map((byte, i) => binaryString.charCodeAt(i));
}
Any help would be very helpful please- thanks in advance
modified 17-Oct-19 19:45pm.
|
|
|
|
|
Well, I had to Google around and read several different examples and explanations for how it works.
I basically searched "FileStreamResult" and this was the most popular answer for using "FileStreamResult" .
According to the documentation, this will return a stream with the appropiate header info that will make it look like a download to the browser, and trigger the browser to prompt for a download.
return new FileStreamResult(stream, new MediaTypeHeaderValue("application/zip"))
{
FileDownloadName = "application.zip"
};
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Thank you jkikerx, I did it in the following way, its completed ready to demo (just in case if somebody wants implement this I am putting my implementation here) - thanks for jumping in to help me.
Here is Web Api code C#:
[EnableCors("AnotherPolicy")]
[HttpPost]
public FileStreamResult Post([FromForm] string communityName, [FromForm] string files)
{
var removedInvalidCharsFromFileName = removeInvalidCharsFromFileName(files);
var tFiles = removedInvalidCharsFromFileName.Split(',');
string rootPath = Configuration.GetValue<string>("ROOT_PATH");
string communityPath = rootPath + "\\" + communityName;
MemoryStream zipStream = new MemoryStream();
using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
foreach (string attachment in tFiles)
{
var zipEntry = zip.CreateEntry(attachment);
using (FileStream fileStream = new FileStream(communityPath + "\\" + attachment, FileMode.Open))
{
using (Stream entryStream = zipEntry.Open())
{
fileStream.CopyTo(entryStream);
}
}
}
}
zipStream.Position = 0;
return File(zipStream, "application/octet-stream");
}
Then my client side React code is here:
handleDownload = (e) => {
e.preventDefault();
var formData = new FormData();
formData.append('communityname', this.state.selectedCommunity);
formData.append('files', JSON.stringify(this.state['checkedFiles']));
let url = clientConfiguration['filesApi.local'];
axios({
method: 'post',
responseType: 'arraybuffer',
url: url,
data: formData
})
.then(res => {
let extension = 'zip';
let tempFileName = `${this.state['selectedCommunity']}`
let fileName = `${tempFileName}.${extension}`;
const blob = new Blob([res.data], {
type: 'application/octet-stream'
})
saveAs(blob, fileName)
})
.catch(error => {
console.log(error.message);
});
};
this event is called when button is clicked or form submitted. Thanks for all the support the SO has given - thanks a lot.
|
|
|
|
|
What is the "saveAs"?
Is that from a NPM package?
KendoReact?
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
npm package file-saver, it is one of the beauties of the React, even though its PIB while learning, but once its, then its all just imports. But still have to learn a lot. If you want guide me better and easier examples to learn regarding like store, react-redux, modal implementation (a new page url opening in a modal and communicating with parent Window), thunk. If you can write brief introductions about the above things also very sweet. But I understand its tough for you and I understand you have gone through this same situations like me, I am reading as well, too many things confusing a lot . Thank you my friend.
|
|
|
|
|
Like I said, I haven't used react yet, just the first version of it. All I can do is help with the .Net Core issues and use Angular knowledge to help with React. But this is discussion forum platform in which you talk about an issue, and not a quick answer platform.
I still wonder why the use of the plugin is needed to save a file. I really don't think the saveAs is needed, and don't see a link or relationship to saveAs in the API call. Your API just takes a POST of body data, generates a file and returns the file with the appropriate header info to save to a target, or just download depending on how the browser is setup.
I'm just scratching my head on this. Perhaps I'll experiment with it later on.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
jkirkerx wrote: I'm just scratching my head on this. Perhaps I'll experiment with it later on.
Thanks welcome any suggestions my buddy
|
|
|
|
|
I am calling the a Web Api from the my react component using fetch, when I used to run it as one application, there was no problem, but when I am running the application react separate from api, I am getting the CORS error, my fetch call is as below,
componentDidMount() {
console.log(clientConfiguration)
fetch(clientConfiguration['communitiesApi.local'])
.then((response) => {
return response.json();
})
.then(data => {
console.log(data);
let communitiesFromApi = data.map(community => { return { value: community, display: community } });
this.setState({ communities: [{ value: '', display: 'Select a Community...' }].concat(communitiesFromApi) });
}).catch(error => {
console.log(error);
});
};
and my post call using axios as below also.
handleDownload = (e) => {
e.preventDefault();
var formData = new FormData();
formData.append('communityname', this.state.selectedCommunity);
formData.append('files', JSON.stringify(this.state['checkedFiles']));
let url = clientConfiguration['filesApi.local'];
let tempFiles = clientConfiguration['tempFiles.local'];
axios({
method: 'post',
responseType: 'application/zip',
contentType: 'application/zip',
url: url,
data: formData
})
.then(res => {
var fileName = `${this.state['selectedCommunity']}.zip`;
saveAs(`https:
});
};
Here is my api code:
[HttpGet("{communityName}")]
public string Get(string communityName)
{
string rootPath = Configuration.GetValue<string>("ROOT_PATH");
string communityPath = rootPath + "\\" + communityName;
string[] files = Directory.GetFiles(communityPath);
List<string> strippedFiles = new List<string>();
foreach (string file in files)
{
strippedFiles.Add(file.Replace(communityPath + "\\", ""));
}
return JsonConvert.SerializeObject(strippedFiles);
}
[HttpPost]
public string Post([FromForm] string communityName, [FromForm] string files)
{
var removedInvalidCharsFromFileName = removeInvalidCharsFromFileName(files);
var tFiles = removedInvalidCharsFromFileName.Split(',');
string rootPath = Configuration.GetValue<string>("ROOT_PATH");
string communityPath = rootPath + "\\" + communityName;
byte[] theZipFile = null;
using (MemoryStream zipStream = new MemoryStream())
{
using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
foreach (string attachment in tFiles)
{
var zipEntry = zip.CreateEntry(attachment);
using (FileStream fileStream = new FileStream(communityPath + "\\" + attachment, FileMode.Open))
using (Stream entryStream = zipEntry.Open())
{
fileStream.CopyTo(entryStream);
}
}
}
theZipFile = zipStream.ToArray();
}
string tempFilesPath = Configuration.GetValue<string>("Temp_Files_Path");
if (!System.IO.Directory.Exists(tempFilesPath))
System.IO.Directory.CreateDirectory(tempFilesPath);
System.IO.File.WriteAllBytes($"{tempFilesPath}\\{communityName}.zip", theZipFile);
return $"{communityName}.zip";
}
And I am getting the error for Get as below: "
Access to fetch at 'https://localhost:44368/api/communities' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. "
modified 15-Oct-19 19:24pm.
|
|
|
|
|
I don't think it has anything to do with the code you posted.
CORS means Cross Origin Request. It's a security feature that secures your API's access and is part of the API server and your code in React. It prevents someone from spoofing your API's
https://medium.com/@dtkatz/3-ways-to-fix-the-cors-error-and-how-access-control-allow-origin-works-d97d55946d9
I have an Angular Project wrapped in .Net Core which hosts the API's in a controller. Technically my project is using Kestrel as a web server. Kestrel is a lightweight blazing fast web server which will serve .Net Projects. In my case, I had to fully program Kestrel as a web server in Programs.cs and Startup.cs, and then align my Angular project to the API's so that I don't get a CORS error. So like services.AddCors is what you add to startup.cs. I had to do a few other things in Angular to get things to align as well. And write some code to handle developing in VS using localhost:5000 to the actual production URL.
I don't know how you structured your React application and back-end API so I'm not able to answer the question as a code fix.
At some point in time, your going to have to figure out how to handle SSL certificates, setup Kestrel and listening ports in .Net Core if that is what your using. You will have to figure out how to host it in a production environment.
If it ain't broke don't fix it
Discover my world at jkirkerx.com
|
|
|
|
|
Google for how to solve CORS problems, this is a well-documented problem. Your API and client are running on separate sites (different ports on the same machine count as different sites) so the API needs to add a header to its return to say that the client host can have access. There are various ways of doing this.
|
|
|
|
|
Hi, thank you I could able to resolve this issue by implementing CORS on my Web API, here is the Code change I did in my Web API. Thank you for all the support you Geeks have given me - thanks for the help
public void ConfigureServices(IServiceCollection services)
{
string configValue = Configuration.GetValue<string>("CORSComplianceDomains");
string[] CORSComplianceDomains = configValue.Split("|,|");
services.AddCors(options =>
{
options.AddDefaultPolicy(
builder =>
{
builder.WithOrigins("http://localhost:3000");
});
options.AddPolicy("AnotherPolicy",
builder =>
{
builder.WithOrigins(CORSComplianceDomains)
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/build";
});
}
And added the urls in the appsettings.json file so that any user can add the new urls without much sweating.
"CORSComplianceDomains": "http://localhost:3000|,|http://www.contoso.com"
Thank you very much - I put my answer here so that someone can get it - thanks for jumping in and helping please - I appreciated it - thank you so much.
|
|
|
|
|
Hi I have React application, which is calling api on download button click, on the button click the values are being posted properly and api is returning the zip file, but I want to let the zip file to be downloaded on the client side.
Here is my code for the API
[HttpPost]
public FileContentResult Post([FromForm] string communityName, [FromForm] string files)
{
var removedInvalidCharsFromFileName = removeInvalidCharsFromFileName(files);
var tFiles = removedInvalidCharsFromFileName.Split(',');
string rootPath = Configuration.GetValue<string>("ROOT_PATH");
string communityPath = rootPath + "\\" + communityName;
byte[] theZipFile = null;
using (MemoryStream zipStream = new MemoryStream())
{
using (ZipArchive zip = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
{
foreach (string attachment in tFiles)
{
var zipEntry = zip.CreateEntry(attachment);
using (FileStream fileStream = new FileStream(communityPath + "\\" + attachment, FileMode.Open))
using (Stream entryStream = zipEntry.Open())
{
fileStream.CopyTo(entryStream);
}
}
}
theZipFile = zipStream.ToArray();
}
return File(theZipFile, "application/zip", communityName + ".zip");
}
And my React components download method is as below:
handleDownload = (e) => {
e.preventDefault();
var formData = new FormData();
formData.append('communityname', this.state.selectedCommunity);
formData.append('files', JSON.stringify(this.state['checkedFiles']));
let url = clientConfiguration['filesApi.local'];
axios({
method: 'post',
url: url,
data: formData
});
window.open(url, '_blank');
}
This window.open(url, '_blank'); is not letting me download the zip files, aren't the path of the zip file and path of the api the same? What can I do to make sure the file downloads on the client side - any help - thanks in advance.
|
|
|
|
|
The problem is, you're making two separate requests - an AJAX POST request, which throws away the response; and a regular GET request with no parameters, which doesn't match your controller action.
Probably the simplest option would be to create a hidden <form> element, populate the values, and then submit that form.
handleDownload = (e) => {
e.preventDefault();
let form = document.createElement("form");
form.action = clientConfiguration['filesApi.local'];
form.method = "POST";
form.target = "_blank";
let input = document.createElement("input");
input.type = "hidden";
input.name = "communityname";
input.value = this.state.selectedCommunity;
form.appendChild(input);
this.state['checkedFiles'].forEach((f) =>
{
let input = document.createElement("input");
input.type = "hidden";
input.name = "files";
input.value = f;
});
document.body.appendChild(form);
form.submit();
}
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hi Richard, after researching online a little bit I could able to do the following, now the zip file is being downloaded but the problem it seems its not downloading correctly
handleDownload = (e) => {
e.preventDefault();
var formData = new FormData();
formData.append('communityname', this.state.selectedCommunity);
formData.append('files', JSON.stringify(this.state['checkedFiles']));
let url = clientConfiguration['filesApi.local'];
axios({
method: 'post',
url: url,
data: formData
})
.then(res => {
console.log(res.data);
var binaryData = [];
binaryData.push(res.data);
const src = window.URL.createObjectURL(new Blob(binaryData, { type: "application/zip" }));
var fileName = `${this.state['selectedCommunity']}.zip`;
saveAs(src, fileName);
});
}
The error that I am getting when uzipping the file is as below:
Can not open the file as zip archive, is not archiving, Warning Headers error. Any help please?
modified 14-Oct-19 18:16pm.
|
|
|
|
|