Large file streaming confusion - asp.net

I want to handle large files in my application and microsoft documentation about File Uploads looks so bizarre. Why would I need MultipartReader whereas I would simply achieve what I want with the following:
#model SampleVM
<form method="post" enctype="multipart/form-data">
<input asp-for="Prop1" />
<input asp-for="Prop2" />
<input type="button" value="Ok" onclick="post();"/>
</form>
#section Scripts{
<script>
function post() {
var formData = new FormData();
formData.append('Prop1', $('#Prop1').val());
formData.append('Prop2', $('#Prop2')[0].files[0]);
$.ajax({
url: '#Url.Action("Index")',
type: 'POST',
processData: false,
contentType: false,
data: formData
});
}
</script>
}
and in the controller I can simply get the stream with
var stream = vm.Prop2.OpenReadStream()
and do whatever I want. What does Microsoft documentation achieve with that spaghetti code that I don't with this simple sample?

Related

Multiple submit button fail to find the handler method in asp.net core 3.1 razor page application

I have a single form which has two button one to upload image using ajax call & other is main submit button which saves all the data.
I am still very new to asp.net core and trying different thing to learn asp.net core with razor page.
I read lot of article about multiple form submit but most of then where using two form with submit button for each.
My issue is when i hit the submit button it fails to find the handler method, after full days troubleshoot nothing worked and last few article point to error/failure to antiforgery, i not sure how to implement it in below code as i tried few but they gave error may be article where old referencing core 2.2 etc example1 example2
I am not sure about the what exactly is causing the issue any help would be appreciate.
I am trying to upload Image using Ajax method in asp.net core Razor pages, I am main form in will all input fields are kept and with the form for Fileupload i am also added addition button which is for file upload using Ajax, When i hit the
<input type="submit" value="Upload Image" asp-page-handler="OnPostUploadImage" id="btnUploadImage" />
i want it to call OnPostUploadImage method in pageModel file but it alway goes to default OnPost method. when i rename the OnPost to OnPost2 nothing happend..
How can i call OnPostUploadImage() on button btnUploadImage click event.
When i hit click btnUploadImage it generates following error on browser console
Error in FF
XML Parsing Error: no root element found Location:
https://localhost:44364/Admin/News/NewsCreate?handler=OnPostUploadImage
Line Number 1, Column 1:
Error in Chrome
jquery.min.js:2 POST
https://localhost:44364/Admin/News/NewsCreateMultipleSubmit?handler=OnPostUpLoadImage
400 (Bad Request)
event though path looks fine but it cant find it as per error message
#page
#model BookListRazor.Pages.Admin.News.NewsCreateModel
#{
ViewData["Title"] = "News Create";
Layout = "~/Pages/Shared/_LayoutAdmin.cshtml";
}
<div class="border container" style="padding:30px;">
<form method="post" enctype="multipart/form-data">
<div class="text-danger" asp-validation-summary="ModelOnly"></div>
<input hidden asp-for="News.NewsImage" />
<input id="fileName" hidden value="" />
<div class="form-group row">
<div class="col-2">
<label asp-for="News.NewsHeading"></label>
</div>
<div class="col-10">
<input asp-for="News.NewsHeading" class="form-control" />
</div>
<span asp-validation-for="News.NewsHeading" class="text-danger"></span>
</div>
<div class="form-group row">
<div class="col-2">
<label asp-for="News.NewsImage"></label>
</div>
<div class="col-10">
#*<input asp-for="News.NewsImage" type="file" class="form-control" id="NewsImage">*#
#*Photo property type is IFormFile, so ASP.NET Core automatically creates a FileUpload control *#
<div class="custom-file">
<input asp-for="NewsImageForUpload" class="custom-file-input form-control">
<label class="custom-file-label">Click here to change photo</label>
<input type="submit" value="Upload Image" asp-page-handler="OnPostUploadImage" id="btnUploadImage" />
</div>
</div>
<span id="imageStatus" class="text-danger"></span>
<span asp-validation-for="NewsImageForUpload" class="text-danger"></span>
</div>
<div class="form-group row">
<div class="col-3 offset-3">
<input id="btnSave" type="submit" value="Create" class="btn btn-primary form-control" />
</div>
<div class="col-3">
<a asp-page="Index" class="btn btn-success form-control">Back to List</a>
</div>
</div>
</form>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="https://cdn.ckeditor.com/4.14.0/full/ckeditor.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script>
$(document).ready(function () {
$("#btnSave").addClass("disable-button");
$('.custom-file-input').on("change", function () {
var fileName = $(this).val().split("\\").pop();
$(this).next('.custom-file-label').html(fileName);
$("#fileName").val(fileName);
$("#btnSave").removeClass("disable-button");
});
if ($("#fileName").val() == "") {
//alert("Select Image...");;
}
});
</script>
</div>
#section Scripts{
<partial name="_ValidationScriptsPartial" />
<script>
$(function () {
$('#btnUploadImage').on('click', function (evt) {
console.log("btnUploadImage");
evt.preventDefault();
console.log("btnUploadImage after evt.preventDefault()");
$.ajax({
url: '#Url.Page("", "OnPostUploadImage")',
//data: new FormData(document.forms[0]),
contentType: false,
processData: false,
type: 'post',
success: function () {
alert('Uploaded by jQuery');
}
});
});
});
</script>
}
.cs file CODE
public async Task<IActionResult> OnPost()
{
if (ModelState.IsValid)
{
return Page();
}
else
{
return Page();
}
}
public IActionResult OnPostUploadImage()
{
//Some code here
}
Verify that you add the following code to the ConfigureServices method of startup.cs:
services.AddAntiforgery(o => o.HeaderName = "XSRF-TOKEN");
If you want to enter the OnPostUploadImage method, the url of the Ajax request needs to be changed to #Url.Page("", "UploadImage") without adding OnPost.
And the Ajax request should send the anti-forgery token in request header to the server.
Change your ajax as follow:
#section Scripts{
<partial name="_ValidationScriptsPartial" />
<script>
$(function () {
$('#btnUploadImage').on('click', function (evt) {
console.log("btnUploadImage");
evt.preventDefault();
console.log("btnUploadImage after evt.preventDefault()");
$.ajax({
url: '#Url.Page("", "UploadImage")',
//data: new FormData(document.forms[0]),
contentType: false,
processData: false,
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN",
$('input:hidden[name="__RequestVerificationToken"]').val());
},
type: 'post',
success: function () {
alert('Uploaded by jQuery');
}
});
});
});
</script>
}
You can refer to this for more details.

Fetch data from HTTP POST with CURL

i'm new with curl
I want to try fetch simple text from html input using curl and send it to another website using simple JSON
this is the simple html code i make
<form action="http:test.com" method="post">
<input type="text" id="text">
<input type="submit" value="submit">
</form>
is there a way to do it?
Thank you!
Since you need to fetch the data from Slack, the nice way is to use AJAX to post the data. The following JS codes are modified based on achavez's gist: Post to Slack using javascript and use jQuery.ajax.
<form action="http:test.com" method="post" id="the-form">
<input type="text" id="text">
<input type="submit" value="submit">
</form>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$('#the-form').submit(function(e) {
e.preventDefault();
var url = "http:test.com"; // Webhook URL
var text = $('#text').text(); // Text to post, get from your form
$.ajax({
data: 'payload=' + JSON.stringify({
"text": text
}),
dataType: 'json',
processData: false,
type: 'POST',
url: url
}).done(function(data) {
// do whatever you want with `data`, `data` is the response
});;
});
</script>

Use AJAX to submit data from HTML form to WebMethod

So I'm taking in data from an HTML form and then using AJAX to send the data to a web method to then be sent to a sqlite database, but my AJAX call is failing. What did I mess up? Am I doing it correctly?
HTML Form
<form id="addForm" >
<input type="text" name="playername" id="playername" placeholder="Player"/>
<input type="text" name="points" id="points" placeholder="Points" />
<input type="text" name="steals" id="steals" placeholder="Steals" />
<input type="text" name="blocks" id="blocks" placeholder="Blocks" />
<input type="text" name="assists" id="assists" placeholder="Assists" />
<input type="text" name="mpg" id="mpg" placeholder="MPG" />
<input type="text" name="shotpct" id="shotpct" placeholder="Shot %" />
<input type="text" name="threepct" id="3pct" placeholder="3 %" />
<input type="button" value="add player" id="addbtn" name="addbtn" />
</form>
AJAX
$("#addbtn").click(function () {
var form = $("#addForm").serializeArray();
$.ajax({
type: 'POST',
url: "players.aspx/addRow",
data: JSON.stringify(form),
dataType: 'json',
success: function () {
alert('success');
},
error: function () {
alert('failure');
}
});
});
and the web method(not finished, was just testing to see if I was getting data)
[WebMethod]
public static void addRow(object form)
{
var stuff = form;
}
I'm still learning how to use a lot of this stuff so any help will be greatly appreciated.
Replace
type: 'POST',
with
method: 'POST',
dataType: 'json'
is not needed since you're not receiving data back. The data returned from the server, is formatted according to the dataType parameter.
Also remove JSON.stringify(form),this is already done with the .serialize();
replace
JSON.stringify(form)
with
$('form').serializeArray()
So you will have:
$("#addbtn").click(function () {
var form = $("form").serializeArray();
$.ajax({
type: 'POST',
url: "players.aspx/addRow",
data: form,
dataType: 'json',
success: function () {
alert('success');
},
error: function () {
alert('failure');
}
});
});
If you still get error. there might be a server side problem in the page you are calling. to make sure of that I suggest you use the 'Advanced REST client' witch is a Google Chrome extension and you can test posting values with it and see the result.

Post Asp.net Form Using AJAX

I am a little new to JQuery. let's suppose that we have this jquery function :
var f = $("#myForm");
var url = f.attr("action");
var formData = f.serialize();
$.post(url, formData, function(data) {
$("#postResult").html(data);
});
and this form :
<form id="myForm" action="/Monitor/Test/FormPost" method="post">
<div>First Name: <input name="FirstName" type="text" value="Bob" /></div>
<div>Last Name: <input name="LastName" type="text" value="Cravens" /></div>
<div>Age: <input name="Age" type="text" value="43" /></div>
<input type="submit" value="Save Contact" />
<div id="postResult">?</div>
</form>
How can I bind the save button with the jquery function ? Thank you
One simple way would be to bind to the click event of the button. Something like this:
$('#myForm input[type="submit"]').click(function () {
var f = $("#myForm");
var url = f.attr("action");
var formData = f.serialize();
$.post(url, formData, function(data) {
$("#postResult").html(data);
});
});
This specifically looks for the submit input that's a child of the form of id "myForm" (in case there are other buttons, etc.) and responds to its click event with the function in question.
Just to be safe, since you're essentially short-circuiting the form and posting via AJAX, you should also probably change the submit to a normal button:
<input type="button" value="Save Contact" />
Or perhaps:
<button value="Save Contact" />
Which would change your jQuery selector to:
$('#myForm input[type="button"]')
Or:
$('#myForm button')
$(document).on("click","input[type=submit]",function(e)
{
e.preventDefault();
var form = $(this).closest("form");
$.post(form.attr("action",form.serialize(),function(d){
//result
});
});
more general way.
//this handler can work on any form that need to post all values
$("form input[type='submit']", f).click(function(e){
e.preventDefault();
var $this = $(this);
var f = $this.parents('form');
var url = f.attr("action");
var formData = f.serialize();
$.post(url, formData, function(data) {
$("#postResult").html(data);
});
return false;
})
In this code you are subscribing click event.
[e.preventDefault();][1] will stop your form from premature submittion and you can do the work you want.

KnockoutJS, updating ViewModel after ajax call

I am using Knockout and the Knockout Mapping plugin.
My MVC3 Action returns a View and not JSON directly as such I convert my Model into JSON.
This is a data entry form and due to the nature of the system validation is all done in the Service Layer, with warnings returned in a Response object within the ViewModel.
The initial bindings and updates work correctly its the "post-update" behavior that is causing me a problem.
My problem is after calling the AJAX POST and and receiving my JSON response knockout is not updating all of my bindings... as if the observable/mappings have dropped off
If I include an additional ko.applyBindings(viewModel); in the success things do work... however issues then arise with multiple bindings and am certain this is not the correct solution.
This is the HTML/Template/Bindings
<!-- Start Form -->
<form action="#Url.Action("Edit")" data-bind="submit: save">
<div id="editListing" data-bind="template: 'editListingTemplate'"></div>
<div id="saveListing" class="end-actions">
<button type="submit">Save Listings</button>
</div>
</form>
<!-- End Form -->
<!-- Templates -->
<script type="text/html" id="editListingTemplate">
<div class="warning message error" data-bind="visible: Response.HasWarning">
<span>Correct the Following to Save</span>
<ul>
{{each(i, warning) Response.BusinessWarnings}}
<li data-bind="text: Message"></li>
{{/each}}
</ul>
</div>
<fieldset>
<legend>Key Information</legend>
<div class="editor-label">
<label>Project Name</label>
</div>
<div class="editor-field">
<input data-bind="value: Project_Name" class="title" />
</div>
</fieldset>
</script>
<!-- End templates -->
And this is the Knockout/Script
<script type="text/javascript">
#{ var jsonData = new HtmlString(new JavaScriptSerializer().Serialize(Model)); }
var initialData = #jsonData;
var viewModel = ko.mapping.fromJS(initialData);
viewModel.save = function ()
{
this.Response = null;
var data = ko.toJSON(this);
$.ajax({
url: '#Url.Action("Edit")',
contentType: 'application/json',
type: "POST",
data: data,
dataType: 'json',
success: function (result) {
ko.mapping.updateFromJS(viewModel, result);
}
});
}
$(function() {
ko.applyBindings(viewModel);
});
</script>
And this is the response JSON returned from the successful request including validation messages.
{
"Id": 440,
"Project_Name": "",
"Response": {
"HasWarning": true,
"BusinessWarnings": [
{
"ExceptionType": 2,
"Message": "Project is invalid."
}, {
"ExceptionType": 1,
"Message": "Project_Name may not be null"
}
]
}
}
UPDATE
Fiddler Demo Is a trimmed live example of what I am experiencing. I have the Project_Name updating with the returned JSON but the viewModel.Response object and properties are not being updated through their data bindings. Specifically Response.HasWarning().
I've changed back to ko.mapping.updateFromJS because in my controller I am specifically returning Json(viewModel).
Cleaned up my initial code/question to match the demo.
I guess Response is reserved, when I change "Response" to "resp", everything went fine. See http://jsfiddle.net/BBzVm/
Should't you use ko.mapping.updateFromJSON on your success event? Chapter Working with JSON strings on Knockout Mapping site says:
If your Ajax call returns a JSON string (and does not deserialize it into a JavaScript object), then you can use the functions ko.mapping.fromJSON and ko.mapping.updateFromJSON to create and update your view model instead.

Resources