Append additional HTML result in calling MVC action by Ajax in DNN8 - html

I'm new in DNN development.
I have created a very simple module in Visual studio--- A textbox and a button.
I just want to call the action in a controller by click the button, then show the return result in the textbox.
The code call the action success, but not sure why append lots of HTML inforation in the result.
Here is the action in the controller:
public ActionResult test1()
{
return Content("Return something");
}
Here is the Ajax code from the View:
$(document).ready(function () {
$("#btnSub").click(function () {
//alert(this.action);
$.ajax({
type:"GET",
contentType:"application/text",
url: "#Url.Action("test1", "Sky")",
data:"",
dataType: "text",
success: function (data) { $("#txtResult").val(data); alert("Success!") },
error:function(){alert("Failed!")}
});
});
});
And here is the result show in the textbox:
Anyone can let me know why the HTML information returned? Actually, I don't need it.
Thanks

Unfortunately, as described in DNN8 MVC unsupported features, it's not yet possible to return a JsonResult. So the solution I used is to return an ActionResult (although the function returns Json):
public ActionResult Test()
{
return Json(new { success = true });
}
On jquery side, I setup ajax call to receive result as html. This avoid the browser to display a parsing error. Finally, just need to remove the html part and manually parse the response. It's not very clean, but the only solution I found until DNN support JsonResult.
$.ajax({
url: '#Url.Action("Index", "Contact")',
type: 'POST',
dataType: 'html',
data: $('#contact-form input').serialize(),
success: function (response) {
jsonPart = response.substring(0, response.indexOf("<!DOCTYPE html>"));
var data = JSON.parse(jsonPart);
if (data.success) {
alert("Great");
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert("Error!");
}
});
EDIT : Improved solution
DNN8 now support IMvcRouteMapper. You can then register a route in RouteConfig.cs. Once done, you can call the function using following URL :
/DesktopModules/MVC/ModuleName/Controller/Action
The action can return a JsonResult. But pay attention, if you just call that function, it will fail with a null exception on ModuleContext. You have to include in the ajax call the following header :
headers: {
"ModuleId": #Dnn.ModuleContext.ModuleId,
"TabId": #Dnn.ModuleContext.TabId,
"RequestVerificationToken": $("input[name='__RequestVerificationToken']").val()
}
You can find the module complete code here.

This is a working ajax call in DNN 9. You dont have to use #urlaction it will give whole html as well as data. dnn.getVar("sf_siteRoot", "/") +
"DesktopModules/MVC/ModuleName/Controller/Action", this does the trick and don't forget to add the header otherwise it will throw 500 error.
$.ajax({
url: dnn.getVar("sf_siteRoot", "/") +
"DesktopModules/MVC/ModuleName/Controller/Action",
type: 'POST',
contentType: "application/json; charset=utf-8",
dataType: 'json',
data: "{ 'id':" + JSON.stringify(3543)+" }",
headers: {
"ModuleId": #Dnn.ModuleContext.ModuleId,
"TabId": #Dnn.ModuleCon`enter code here`text.TabId,
"RequestVerificationToken":
$("input[name='__RequestVerificationToken']").val()
},
success: function (response) {
debugger;
},
error: function (errmsg) {
alert("Error!");
}
});
Your controller should be
[HttpPost]
public ActionResult ActionName(int id)
{
var data = id;
return BuidJsonResult(true,data);
}
Happy Coding :)

Related

AJAX/JSON MVC method not being called

The MVC controller method is not being called with the following code and the issue isn't clear. $("#screeners").val() returns a list of strings:
<script>
$(document).ready(function () {
$("#submitScreeners").click(function () {
var selected = $("#screeners").val();
$.ajax({
contentType: 'application/json; charset=utf-8',
dataType: 'json',
type: 'POST',
url: '/Applicant/PassScreeners',
data: "selected=" + JSON.stringify(selected),
success: function () {
$('#result').html('"PassScreeners()" successfully called.');
},
failure: function (response) {
$('#result').html(response);
}
});
});
});
</script>
Method in controller:
public void PassScreeners(List<string> selected)
{
Session["SelectedApplicants"] = selected.Select(e => Int32.Parse(e.ToString())).ToList();
}
If I understand you correctly, the "selected" parameter is being passed in as a null value. I believe this is because you are using an incorrect data format. You tell the server to expect JSON formatted data, but then pass it something more akin to a form value with '='.
Try removing the "selected=" bit from your data line and just pass the stringified list.
If that doesn't work, check the trace and post it. If the string you are posting is just comma separated or something it needs to be an array in order for the POST to work correctly.
Apologies if I've misunderstood.

Post list of string null on web api controller

In my web api project, I got a controller named ContactController and a method named Synchro in it which waits for a list of string as below:
[HttpPost]
[Route("api/Contact/Synchro")]
public IHttpActionResult Synchro([FromBody]List<string> listNumTel)
{
List<Profil> listContact = new List<Profil>();
if (listNumTel.Count() > 0)
{
try
{
listContact = Librairie.Contacts.getContactSync(listNumTel);
return Ok(listContact);
}
catch(Exception e) {
return InternalServerError(e);
}
}
else
{
return BadRequest();
}
}
To test that method, I've created the ajax called below:
$("#btn_synchro").click(function () {
$.ajax({
url: '../api/Contact/Synchro',
type: 'POST',
data: {
"listNumTel": [
"+33640512999",
"+33640522997",
"+33640182998",
"+33640742996"]
},
dataType: 'json',
success: function (data) {
alert('Synchro réussi: ' + data);
},
error: function (request, error) {
alert("Erreur lors de la synchro");
}
})
});
When I test on debug mode, the call works fine but the method get a null list. I checked if the json is valid and it is. Does Somebody sees what could be wrong ? Thanks in advance !
Thanks for the answers, but I've just found out the solution. It was all about JSON sent. To send a list of string by an ajax call for example, the JSON should looks like below the variable listNumero
("#btn_synchro").click(function () {
var listNumero =
[ '+33640532999',
'+33640532997',
'+33640532998',
'+33640532996'];
$.ajax({
url: '../api/Contact/Synchro',
type: 'POST',
data: JSON.stringify(listNumero),
contentType: "application/json",
dataType: 'json',
success: function (data) {
alert('Synchro réussi: ' + data);
},
error: function (request, error) {
alert("Erreur lors de la synchro");
}
})
});
You can compare to my post, the JSON is different. Now my web api controller can get the values from the list.

Pass ViewModal from javascript file to code-behind

I have a Javascript file that calls a method in my code-behind. This seems to work if I create a parameterless default constructor, EXAMPLE 1, BUT I want to pass to the save method my ViewModel, EXAMPLE 2. When I do this I get a 500 error. After digging deeper I discovered more details about that network error.
Parameterless Default Constructor - this works but only if the other constructor is commented out.
EXAMPLE 1
[HttpPost]
public JsonResult SaveWorkRequestDetails()
{
return Json(new {});
}
If I have both of these in the code-behind file then I get this error: The current request for action 'SaveWorkRequestDetails' on controller type 'WorkRequestController' is ambiguous between the following action methods:
System.Web.Mvc.JsonResult SaveWorkRequestDetails() on type WorkRequest.Controllers.WorkRequestController
System.Web.Mvc.JsonResult SaveWorkRequestDetails(WorkRequest.ViewModel.WorkRequestViewModel) on type WorkRequest.Controllers.WorkRequestController
EXAMPLE 2
[HttpPost]
public JsonResult SaveWorkRequestDetails(WorkRequestViewModel viewModel)
{
// TODO: Save logic goes here
return Json(new { });
}
I need to pass the viewModel in order to save the user's selections. I am missing something and I am not sure what.
RegisterUIEventHandlers: function () {
$('#Save').click(function (e) {
// Check whether the form is valid. Note: Remove this check, if you are not using HTML5
if (document.forms[0].checkValidity()) {
e.preventDefault();
$.ajax({
type: "POST",
url: WorkRequest.SaveUrl,
data: ko.toJSON(WorkRequest.ViewModel),
contentType: 'application/json',
async: true,
beforeSend: function () {
// Display loading image
alert(ko.toJSON(WorkRequest.ViewModel));
},
success: function (result) {
// Handle the response here.
},
complete: function () {
// Hide loading image.
},
error: function (jqXHR, textStatus, errorThrown) {
// Handle error.
}
});
}
});
}
In the alert you see in beforeSend, in the AJAX POST within the javascript above, I see the selections the user makes. Everything works so I just want to pass this to the Controller's SaveWorkRequestDetails, how can I do this please. I was my understanding that the data parameter passed this on to the method specified in the url parameter.
The error message is clear. You have two action methods with the same name. So, call to the SaveWorkRequestDetails is ambigious as the error indicates.
You can overload functions in C# but it is not possible in ASP.NET MVC Framework.
It is not possible to have two SaveWorkRequestDetails() actions with different method signatures on the same controller in ASP.NET MVC.
Just remove the first SaveWorkRequestDetails(), and you will be fine.
I changed the dataType to json instead of application/json. This resolved the issue of the error stating there was not a parameterless default constructor. Now SaveWorkRequestDetails is being called.
RegisterUIEventHandlers: function () {
$('#Save').click(function (e) {
// Check whether the form is valid. Note: Remove this check, if you are not using HTML5
if (document.forms[0].checkValidity()) {
e.preventDefault();
$.ajax({
type: "POST",
url: WorkRequest.SaveUrl,
data: ko.toJSON(WorkRequest.ViewModel),
dataType: 'json',
async: true,
beforeSend: function () {
// Display loading image
alert(ko.toJSON(WorkRequest.ViewModel));
},
success: function (result) {
// Handle the response here.
},
complete: function () {
// Hide loading image.
},
error: function (jqXHR, textStatus, errorThrown) {
// Handle error.
}
});
}
});

ASP.NET MVC Show View after Ajax call to a Controller

I have a View with a submit form: when I click it a jquery/ajax function is called. This function has to encode the View Model, call a Controller action and show the View returned.
Now, this is my function:
<script type="text/javascript">
function Analyze() {
var urlact = '#Url.Action("Analysis")';
var model = '#Html.Raw(Json.Encode(Model))';
$.ajax({
data: model,
type: "POST",
url: urlact,
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
//WHAT HERE??
}
});
}
</script>
And the Analysis action is a kind of
public ViewResult Analysis(IEnumerable<Azienda> aziende) {
Debug.WriteLine(aziende.Count());
return View(aziende);
}
Returning a View!
How can I display that View on success:function(data)?
I tried changing dataType to html and calling on success alert(data) but I had problems with the encoded model, I tried commenting the contentType line but same model-encoding issue.
Does someone know how to do that?
A js/query/ajax workaround-trick is fine, too.
Thanks you all!
Use
return PartialView()
instead of
return View()
in your controller. Then in the success function in your ajax call, use the jQuery .html() function to update the element you wish to update in your html. See Query.html() and View() vs. PartialView()
Create a separate partial view with aziende as its model and return this in your Analysis action and then append the result to a div in your view:
//action returning a partial view
public ActionResult Analysis(IEnumerable<Azienda> aziende)
{
Debug.WriteLine(aziende.Count());
return PartialView("_partialView", aziende);
}
//then append the result to a div in your javascript
success: function (data) {
$("#some-div").html(data);
}

Retrieving search data from database using jQuery autocomplete?

I am using jQuery UI Autocomplete plugin for better data input in my ASP.NET web application.
http://jqueryui.com/demos/autocomplete/
However, I think I have somehow lost in this plugin.
I would like to ask what I should do in order to use this autocomplete function with the data retrieve from database?
I expect Ajax should be used for the real-time search,
but I have no idea how it can be done after looking at the demo in the website above.
Thanks so much.
Update:
Here is the code I have tried, doesn't work, but no error in firebug too.
$('#FirstName').autocomplete({
source: function (request, response) {
$.ajax({
url: "/Contact/FirstNameLookup?firstName=",
type: "POST",
data: {
"firstName": $('#FirstName').val()
},
success: function (data) {
response($.map(data, function (item) {
return {
label: item.FirstName,
value: item.FistName
}
}));
}
});
}
});
You need to create an action that does the lookup and returns the result as a JsonResult
e.g.
public ActionResult FirstNameLookup(string firstName)
{
var contacts = FindContacts(firstname);
return Json(contacts.ToArray(), JsonRequestBehavior.AllowGet);
}
I'm not sure if this will solve all your problems but here are a couple of edits you can make.
you don't need the "?firstname=" part of the url since you are using the data parameter for you ajax request.
rather than grabbing your search term with $('#FirstName').val(), try using the term property of the request object (request.term).
for example:
$('#FirstName').autocomplete({
source: function (request, response) {
$.ajax({
url: "/Contact/FirstNameLookup",
type: "POST",
data: {
"firstName": request.term
},
success: function (data) {
response($.map(data, function (item) {
return {
label: item.FirstName,
value: item.FistName
}
}));
}
});
}
});