MVC 5 + $Post() function not working after hosted on server - c#

I have developed an application in MVC5. Onclick of a link on the View below code gets invoked -
// Code in View File
$.post('../ControllerName/FunctionName', //this is your url
{
id: image,
}, function (data) {
alert("Successfully published");
}
).error(function () {
alert("Failed to publish");
});
//Code in Controller
[HttpPost]
public void ISPPDF(string id)
{}
Issue that i am facing is the ISPPDF() function gets invoked when i run it through visual studio.However after i hosted my application on server it does not seem to call the function..
I feel there is some issue with the path i have specified -
i also tried specifying path the below ways but no luck!
/ControllerName/FunctionName
ControllerName/FunctionName
Any help would be appreciated.
Thanks,

You should never hard-code URLs in MVC.
Instead use #Url.Action.
$.post('#Url.Action("FunctionName", "ControllerName")', //this is your url
If you need to send parameters, you do it like this:
$.post('#Url.Action("FunctionName", "ControllerName", new { id = Model.ID })', //this is your url
And there are two important reasons why I recommend this:
1. The chances of mistyping the URL are huge. This Questions proves it, the OP mistyped the URL.
2. Url.Action takes into account your route. If your route changes, Url.Action will know how to build the correct URL. This way you will not have to go through multiple views to change all the hard-coded values.

Try this as your post method is in view file
$.post('../FunctionName',{ id: image,}, function (data) { alert("Successfully published");}).error(function () {alert("Failed to publish"); });

Related

AJAX Request to Method Contained in Class File

I'm trying to make an AJAX request on a Razor Page, calling a method contained in separate class file (NOT in the pagemodel for the page - as I eventually want to make the same request from multiple different pages).
Unfortunately, the request fails. I think it may have to do with the syntax I've used, or perhaps the class I'm trying to call being of the wrong type. Note that the request DOES work if I change the url to a method in the pagemodel (no other changes required).
I'm fairly new to ASP.NET Core Razor Pages, and AJAX requests, so if there's a fundamental misunderstanding here, let me know.
AJAX Request Code (jQuery):
$(document).ready(function () {
$.ajax({
dataType: 'json',
url: '/Tools/Redirect?handler=AccessRedirect',
type: 'GET',
success: function (data) {
alert("Request Success, Data = " + data);
},
error: function () {
alert("Request Failed");
}
});
})
(I've also tried url: /Tools/Redirect/AccessRedirect using a method simply called AccessRedirect, with the [HttpGet] attribute, but that didn't work either)
C# Class Code (File is Redirect.cs in folder Tools):
public class Redirect
{
public JsonResult OnGetAccessRedirect()
{
return new JsonResult("test");
}
}
Any help is greatly appreciated. Thanks.
Your fundamental misunderstanding is that Razor Pages requests must target a handler method in a PageModel class. You can't map URLs to arbitrary methods in class files. Handler methods must be in a class that derives from PageModel, and they must follow certain conventions.
You can read more about handler methods in Razor Pages here: https://www.learnrazorpages.com/razor-pages/handler-methods
If you have code that you want to centralise, you can put that in a C# class, and then call the method in your handler method

Angular Material AutoComplete Not Loading Options MVC

I am working on my AutoComplete widget, using Angular JS - Material, in C# ASP.NET MVC.
In this example, I'm trying to get an AutoComplete of States to work. I started with this tutorial, but need to have the options come from the database (at this point, just static list of options in the controller).
Here is a link to my current code (relevant files).
When I run the code, I can see that the list of objects from the controller are pulling through properly - an array of 4 objects, each with an Id and a Name (as shown in my controller method). However, the options are not being loaded into the input form.
When I click into the textbox, I get an "option" that says No states matching "" were found. If I type in 'a', I get the "option" that says No states matching "a" were found. This is what I would expect to happen if there actually were no matching results.
My question: How do I change my code to load the options with what I'm pulling from the controller?
Thanks in advance!
Here's a screen shot of the results:
Here's the key JavaScript/AngularJS code:
//TODO: Replace data.json with /Home/GetStates
$http.get('data.json')
.then(function(response) {
self.states = response.data.map(function(state) {
return {
value: state.Name.toLowerCase(),
display: state.Name
};
});
});
You'll need to replace 'data.json' with '/Home/GetStates' for it to call your backend MVC JSON RESTful API Service. Note that I also left the functions querySearch(query) and createFilterFor(query) in place and changed self.states=loadStates() to self.states=null since the $http.get() service will now load the states.
I did test your C# MVC controller code and everything looks good with it.
Here's a working Plunker, http://plnkr.co/edit/tDC6KcO1O8VSGwVghBo7?p=preview.
Hope this helps. Let me know if you need anything else.
Here's what I did to fix the problem:
Changed to POST
Set variable = result, then returned the results
Here's the code:
function querySearch(query) {
if (query == undefined) {
console.log("invalid");
return;
}
$http({
method: 'POST',
url: self.URL_Get + query,
searchTerm: query
}).then(function(response) {
self.states = response.data;
});
return self.states;
}

JSON data POST to Web API works in Fiddler but "Not Found" error from JQuery AJAX

my stuff works fine with Fiddler and I get desired result. But when i do it on web page thru JQuery AJAx, it says "Not Found". I am struggling since sometime but couldn't get around.
My Controller method is like this
[Route("AddDonors/")]
[HttpPost]
public dynamic addDonors(localDonor localDonor)
{
return localDonor;
}
This is how i am calling from web page
var userInput = { 'FullName': 'Lakshman', 'Mobile': '9924210053' };
$.ajax({
type: "POST",
url: "/AddDonors",
data: userInput,
error: function (result) {
alert(result);
},
datatype: "json"
});
this is the model class
public class localDonor
{
public String FullName { get; set; }
public String Mobile { get; set; }
}
API registering and other settings are just fine since this works in fiddler.
Please help. Thanks.
I strongly suspect that the url in your AJAX request is to blame (404 - Not Found) the request can't be routed to a controller for processing.
Without knowing what your full controller looks like and if you have a RoutePrefixAttribute on this specific controller I can't say what the url should be.
I would suggest you monitor network traffic in your browser developer tools (press F12) and compare the request url for your failing POST request to those of your successful requests in Fiddler
If your webpage is created in ASP.Net MVC as part of the same web project you may want to generate the url server side in future see Construct url in view for Web Api with attribute routing. The #Url helper is only available within your .cshtml files though so you will not be able you shift your JavaScript code to a separate .js file.
i was able to solve the issue by changing the url to url: "AddDonors",
Try to put [WebMethod] attribute.
[Route("AddDonors/")]
[HttpPost]
[WebMethod]
public dynamic addDonors(localDonor localDonor)
{
return localDonor;
}
Hope this works!
Try this for your POST data
var userInput = JSON.stringify({ 'FullName': 'Lakshman', 'Mobile': '9924210053' }),
I had the same error.
As you are using ASP.NET, try making all AJAX calls using the #Url.Action helper.I don't know why, but in some situations in ASP.NET passing the URL as a String doesn't work.And try passing your data like the code belowYour modified code should look something like this:
$.ajax({
type: "POST",
url: "#Url.Action("AddDonors", "ControllerName")",
data: { localDonor: userInput },
error: function (result) {
alert(result);
},
datatype: "json"
});

Using Angular to Download a File via Ajax

I have a service that generates a CSV file and returns it to the page via an http/ajax get. I'd like a user to click a button, have the service get called, and then have the file get downloaded to the user's browser.
I would like to do this The Angular Way, although I recognize this may have more to do with Ajax or the browser than Anguler per se.
The service is in C#, and this is what it returns:
return File(Encoding.UTF8.GetBytes(WriteCSV(assetList)), "text/csv", "results.csv");
The controller code that calls the service looks like the following. It works, but I don't know what to do on success:
$scope.exportCSV = function () {
$http({
method: "get",
url: "ExportCSV"
}).
error(function (data, status, headers, config) {
alert("Error exporting data to CSV.");
});
};
You can't initiate a download from a normal ajax GET or POST, you have to do the traditional way, eg window.location='url' and set the correct http header with the correct content-type which will prompt the download dialog in the users browser
Possibly a more 'angulary' way is to have your controller set a flag to trigger the download, but put the core functionality in a directive that builds an element with a "download" attribute, and on display, a callback/watch calls the ng-click.
For example:
// put this in a template related to a given controller
<downloader ng-if="downloadready"></downloader>
// controller just needs to trigger the directive into action
module.controller(..., function($scope){
$scope.downloadready = true; // trigger the directive to be created
});
// and the directive code will build the element and click the button
module.directive('downloader', function ($compile) {
return {
restrict: 'E',
replace: true,
// values here can be placed in the template as variables and accessed in link()
// but this is shortest to get the idea across
template: '<a id="downloadbtn" class="btn" download="backup.json"></a>',
link:function (scope, elm, attrs) {
// this clicks the button outside the digest loop which the scope was updated in
$timeout(function() {
angular.element($('#downloadbtn')).triggerHandler('click');
}, 0);
}
}
});
Though I admit, it's more mind-bending than changing redirect on window.location.

How the form data is converted to a model in C# .Net MVC3 , entity framework?

I have a code like below
View:
$("form").live('submit', function () {
var formData = $(this).toObject();
$.ajax({
url: "../Home/Index",
type: "POST",
dataType: "json",
data: formData,
success: function (data) {<<Some handling>>
}
Controller:
public JsonResult Index(Task task)
{
//operations on the task object like getting data from task and setting to it.
}
Task is a model here.
Here when the form is submitted, the form object is directly sent to the controller and the controller is receiving it as a model.
How this conversion takes place? I have added a file component to the form now
<input type="file" name = "file" id="file"/>
and added the file attribute to model Task.
public HttpPostedFileBase file{ get; set; }
But I am getting null for the file in the controller. But all other values are coming well.
Please help me out. Please let me know if you need any additional info to understand my question correctly.
Normally it's the model binder that is responsible for converting the request values into a model.
But in your case you seem to be attempting to send a file using AJAX. This is not supported. The reason for that is because jQuery's ajax method doesn't support that. You could use HTML5 File API if the client browser supports it because the XHR2 object allows you to asynchronously upload files to the server. Here's an example:
$(document).on('submit', 'form', function () {
var xhr = new XMLHttpRequest();
xhr.open(this.method, this.action);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText); // handle response.
}
};
xhr.send(new FormData(this));
return false;
}
Also notice that I have used the .on() method to subscribe to the submit event instead of .live() which is obsolete and has been removed in jQuery 1.9.
If on the other hand you need to support legacy browsers you could use a plugin such as Fine Uploader or jQuery form to achieve this task. What those plugins do is detect the capabilities of your browser and if it supports XHR2 it will use it, and if it doesn't it will use a different technique (such as hidden iframes, flash, ...).
You can not file upload using jquery ajax post directly. You should you some plug-in for this.
May be you can use this plug-in
This question will show you a start point for using this plug in.
Also, I learned it from #DarinDimitov suggestions, too :)

Categories

Resources