Passing Large Html Content to API Controller in Asp.net MVC - c#

I have created an api controller which is supposed to receive some html content. When the call fires, chrome shows the status of PUT request as pending for a looong long time.
Initially i thought the problem is with the html tags but once i tried small tags i discovered it worked.
Now i am guessing the problem is with the size of content which is the content of a full html page.
here is the code:
<script>
$("#createHtmlElement").click(function (event) {
$.ajax({
url: "/api/PageElements/#Model.Id",
contentType: 'application/json; charset=utf-8',
type: "PUT",
data: JSON.stringify({
Content: $("#newHtmlContent").val()
}),
success: function (html) {
}
});
});
</script>
here is the c# code for the API:
public class PageElementsController : ApiController
{
[ValidateInput(false)]
public void Put(int id, HtmlElement value)
{
HtmlContent contents = new HtmlContent(value.Content);
this.htmlElementBL.SaveHtmlContentElements(contents, id);
}
}
I need to either change my approach as to how i am passing data or find out what is the problem that it is not working with the large content.

Related

ASP.NET Core MVC RedirectToAction isn't working

I have seen lots of questions regarding this issue but none of those resolved my problem.
My problem: my redirect action method hits the method I am redirected to, but the view stays on the same page it never changes to the redirected one.
From my Index.chstml I am creating a partial view.
From that partial view using AJAX I am submitting a request to my controller. AJAX code is below
$.ajax({
method: 'POST',
url: "/Home/SubmitTest",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(arr),
success: function (response) {
}
});
My controller code is here. I am receiving data from AJAX method and performing some jobs. In the end, I am trying to redirect the user to another method.
[HttpPost]
public IActionResult SubmitTest([FromBody] List<TestSubmitViewModel> data)
{
// Rest of the code goes here
return RedirectToAction(nameof(PipelineList));
}
The method I am redirecting to is below. Both methods are in the same controller. After redirection, I am getting hit to this method. But my view still stays in the previous URL which is
https://localhost:44339/Home/Index
but it supposed to redirected to
https://localhost:44339/Home/PipelineList
Code:
[HttpGet]
[AllowAnonymous]
public async Task<IActionResult> PipelineList()
{
List<PipelineViewModel> itemList = new List<PipelineViewModel>();
/// my other code goes here
return View(itemList);
}
Note: my PipelineList() works fine when I am coming to this action method directly from UI. What am I doing wrong here and what can I do to redirect to the URL?
I am using .NET Core 5.
Here is my routing information from StartUp.cs:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller}/{action}/{id?}",
defaults: new { controller = "Home", action="SignIn"});
});
UPDATE
Thank you guys for pointing out the problem I was having.
Using AJAX was necessary for me to pass the selected values (which were from a table created by JS) from UI.
Finally, I made it work by changing my Controller and AJAX code.
Updated Controller:
[HttpPost]
public async Task<JsonResult> SubmitTest([FromBody]
List<TestSubmitViewModel> data)
{
try
{
// my codes goes here
return Json(new {StatusCode = statusCode });
}
catch (Exception)
{
return Json(new {StatusCode = 500 });
}
}
Updated AJAX:
$.ajax({
method: 'POST',
url: "/Home/SubmitTest",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(arr),
success: function (response) {
if (response.statusCode == 200) {
var url = "/GitLab/PipelineList";
window.location.href = url;
} else {
alert("error");
}
}
});
I know this might not be the best solution but for now, it did work. Thanks a lot to #Sergey and #Filipe
As #Sergey says, you used the wrong senior for ajax. Ajax is normally used when you want to update part of the page instead of refreshing the whole page to increase the customer experience and page load speed. If you want to redirect to another page and there is no other specific reason, there is no need to use ajax.
You could find the ajax server has returned the right 302 redirect to the client side and it redirect to the new page:
The right way is directly redirect to the new page like this:
<form asp-action="SubmitTest" asp-controller="Home" method="post">
#*Other input value you want to submit*#
<input type="submit" value="Click"/>
</form>
Result:

Return view after ajax post to controller

I'm sending some json data with ajax by post
function SendF() {
$.ajax({
url: '#Url.Action("Summary")',
type: 'POST',
data: JSON.stringify(flags),
contentType: "application/json;charset=utf-8",
success: function() {
},
error: function() {
alert("Oops! We've experienced a connection problem!");
}
});
}
to my controller
[HttpPost]
public ActionResult Summary(List<string> flagsChecked)
{
[...]
return View(flags);
}
and tried returning a view with data I've processed, but I guess it's not gonna happen since ajax is all about asynchronous http requests. How do I change my code to be synchronous?
The whole idea behind using ajax is to give the user the partial page update experience. If you are making an ajax call and once that is done and you are doing a redirect to another page, it does not give the partial page update experience to user. It looks very similar to the normal form submit(full page submit).
If you absolutely have to send the data to server via ajax , but want to do the redirect after the ajax call is successfully finished, you can do that using javascript in the success or done callback event on the $.ajax method.
All you have to do is, set the location.href property to the new url.
var flags = ["aa", "bb", "cc"];
$.ajax({
url: '#Url.Action("Summary")',
type: 'POST',
data: JSON.stringify(flags),
contentType: "application/json;charset=utf-8"
}).done(function(res) {
window.location.href = res.newUrl;
}).fail(function(xhr, a, error) {
console.log(error);
});
This assumes that your server action method returns a JSON response with the newUrl property which contains the url you want to redirect to .
[HttpPost]
public ActionResult Summary(List<string> flagsChecked)
{
return Json(new { newUrl = Url.Action("Index","Home") });
}
One way to do this would be to send the request to the controller via ajax and then render a partial view on your page. The easiest way would be to use the built in ajax helpers in ASP MVC. Here is a link to another post that gives a pretty good overview:
How to render partial view in MVC5 via ajax call to a controller and return HTML

ASP.NET MVC submit empty string to WebApi Controller on jquery serialize()

I'm trying to POST data from ASP.NET MVC View to WebApi Controller via j Query $.post(), but I'm always receiving just empty string (what's interesting - this work fine with Web Forms).
Here is JS.
$("#searchbtn").click(function () {
var ser = $("div#hotels").serialize();
$.post('/api/hotelsavailablerq', { '': ser });
});
Here is how ApiController signature look like:
[HttpPost]
public void PostHotelsAvailableRq([FromBody] string q)
View using just pure HTML forms - div, select, input type=text. Nothing Binded from model.
try another:
$.ajax({
url: '/api/hotelsavailablerq',
type: "POST",
contentType: 'application/json; charset=utf-8',
dataType: 'json'
data: JSON.stringify(ser)
});
Please try the below code to hit the controller. Make sure there is hotelsavailablerq action method in api controller.
$("#searchbtn").click(function () {
$.ajax({
url: '/api/hotelsavailablerq',
type: 'POST',
data: $('div#hotels').serialize(),
success: function (result) {
});});
Well, I found answer - RTFM.
When I read carefully jQuery documentation about serizlization, I found that:
1. <form> tag should exist.
2. Each control should have name attribute.
All these things has by default in web form, but in MVC I should add its manually.
Try
$.post('/api/hotelsavailablerq', { 'q': ser });
string q should be of the same type which you are sending from the jQuery.

Cannot pass large json string to another Page with asp.net c# and knockoutjs

I got a problem while working with knockoutJs and asp.net c#.
When I passed a json string from page to another popup page using jquery ajax and knockoutJs for printing.
The problem occur:
When the Json string is small. It works fine, the popup page shows string data in table.
However, when the json string is large. It doesn't work anymore. The error occurs with message:
"Uncaught Sys.ArgumentException: Sys.ArgumentException: Cannot deserialize. The data does not correspond to valid JSON.
Parameter name: data"
Here is my code:
$.ajax({
type: "POST",
url: 'InProgressBrief.aspx/PrintReport',
data: ko.toJSON({ reportData: ko.toJSON(InProgressBriefs.Briefs) }),
async: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
window.open("PrintInProgressBrief.aspx?month=" + InProgressBriefs.Month() + "&year=" + InProgressBriefs.Year(), "", "status=0,toolbar=0,width=1000,height=900");
}
})
Here is my webMethod
[WebMethod]
public static void PrintReport(string reportData)
{
PSCDialog.DataShare = reportData;
}
The popup page recieves the Json tring:
if (PSCDialog.DataShare != null)
return PSCDialog.DataShare as string;
In the popup page UI, I set the knockoutjs variable, my UI javascript code is something like follow:
var InProgressBriefs = {
Briefs: ""
;
$(function(){
InProgressBriefs.Briefs = Sys.Serialization.JavaScriptSerializer.deserialize('<%=ReportJSONData%>');
ko.applyBindings(InProgressBriefs, $('#mainDivPrint')[0]);
})
Would anyone please tell me what is the problem here? I will appreciate your help alot.
Thank you in advance.
One thing that's a little suspicious is the line
data: ko.toJSON({ reportData: ko.toJSON(InProgressBriefs.Briefs) }),
When that's deserialized, you wind up with reportData being a JSON-encoded string rather than a native object. I doubt that's what you want. More likely what you need is
data: ko.toJSON({ reportData: ko.toJS(InProgressBriefs.Briefs) }),
which serializes only once.

Calling a C# method with jquery

I am trying to call a method with jQuery on a button click.This is waht I have so far:
$("a.AddToCart").click(function () {
var link = document.URL;
$.ajax({
type:"POST",
url: "/Account/AddToCartHack",
data: {url : link},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
});
[WebMethod]
public void AddToCartHack(string url)
{
GeneralHelperClass.URL = url;
}
What I am trying to do here is when I click the link with class add to cart I want to call the method AddToCartHack and pass it the curent URL as a parameter.
I must be doing something wrong because it seems that AddToCartHack is not being called.
What am I doing wrong?
There are quite a lot of issues with your code, I don't know where to start. So let's conduct an interactive refactoring session with you (if you don't care about my comments but just want to see the final and recommended solution, just scroll down at the end of answer).
First: you don't seem to be canceling the default action of the anchor by returning false from the .click() event handler. By not doing this you are actually leaving the browser perform the default action of the anchor (which as you know for an anchor is to redirect to the url that it's href attribute is pointing to. As a consequence to this your AJAX call never has the time to execute because the browser has already left the page and no more scripts are ever running). So return false from the handler to give your AJAX script the possibility to execute and stay on the same page:
$("a.AddToCart").click(function () {
var link = document.URL;
$.ajax({
type:"POST",
url: "/Account/AddToCartHack",
data: {url : link},
contentType: "application/json; charset=utf-8",
dataType: "json"
});
return false;
});
Second: You have specified contentType: 'application/json' request header but you are not sending any JSON at all. You are sending a application/x-www-form-urlencoded request which is the default for jQuery. So get rid of this meaningless parameter in your case:
$("a.AddToCart").click(function () {
var link = document.URL;
$.ajax({
type:"POST",
url: "/Account/AddToCartHack",
data: {url : link},
dataType: "json"
});
return false;
});
Third: You have specified that your server side code will return JSON (dataType: 'json') but your server side code doesn't return anything at all. It's a void method. In ASP.NET MVC what you call C# method has a name. It's called a controller action. And in ASP.NET MVC controller actions return ActionResults, not void. So fix your contoller action. Also get rid of the [WebMethod] attribute - that's no longer to be used in ASP.NET MVC
public class AccountController: Controller
{
public ActionResult AddToCartHack(string url)
{
GeneralHelperClass.URL = url;
return Json(new { success = true });
}
}
Fourth: you have hardcoded the url to the controller action in your javascript instead of using server side helpers to generate this url. The problem with this is that your code will break if you deploy your application in IIS in a virtual directory. And not only that - if you decide to modify the pattern of your routes in Global.asax you will have to modify all your scripts because the url will no longer be {controller}/{action}. The approach I would recommend you to solve this problem is to use unobtrusive AJAX. So you would simply generate the anchor using an HTML helper:
#Html.ActionLink(
"Add to cart",
"AddToCartHack",
"Account",
null,
new { #class = "AddToCart" }
)
and then unobtrusively AJAXify this anchor:
$('a.AddToCart').click(function () {
var link = document.URL;
$.ajax({
type: 'POST',
url: this.href,
data: { url : link }
});
return false;
});
Fifth: You seem to be employing some document.URL variable inside your .click() handler. It looks like some global javascript variable that must have been defined elsewhere. Unfortunately you haven't shown the part of the code where this variable is defined, nor why is it used, so I cannot really propose a better way to do this, but I really feel that there's something wrong with it. Or oh wait, is this supposed to be the current browser url??? Is so you should use the window.location.href property. Just like that:
$('a.AddToCart').click(function () {
$.ajax({
type: 'POST',
url: this.href,
data: { url : window.location.href }
});
return false;
});
or even better, make it part of the original anchor (Final and recommended solution):
#Html.ActionLink(
"Add to cart",
"AddToCartHack",
"Account",
new { url = Request.RawUrl },
new { #class = "AddToCart" }
)
and then simply:
$('a.AddToCart').click(function () {
$.ajax({
type: 'POST',
url: this.href
});
return false;
});
Now that's much better compared to what we had initially. Your application will now work even with javascript disabled on the page.
place script method this way as shown below
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
Add Success and error function to check your ajax functionality
...
$.ajax({
type:"POST",
url: "/Account/AddToCartHack",
data: {url : link},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(){
alert('success');
},
error:function(){
alert('error');
}
});
....
If this is Asp.Net webforms you will need to make the webmethod static or the method cannot be accessed through JavaScript.
$(document).ready(function () {
$.ajax({
url: "Testajax.aspx/GetDate",
data: "f=GetDate",
cache: false,
success: function (content) {
$('#tableData').append('My Dear Friend');
alert(content);
},
failure: function (response) {
alert("no data found");
}
});
});

Categories

Resources