Not receiving JSONP callback - asp.net-mvc

I am following the sample code/tutorial for ASP.NET MVC and JSONP blog post: http://blogorama.nerdworks.in/entry-EnablingJSONPcallsonASPNETMVC.aspx
I have taken the code sample and have modified it for my own consumption.
When I hit the page, it fires off my controller's action but the $.getJSON(call, function (rsp).. is not firing at all.
Controller action
[JsonpFilter]
public JsonpResult GetMyObjects(int id)
{
List<MyObject> list = MyDAO.GetMyObjects(id);
return new JsonpResult
{
Data = list,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
HTML Page
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
var url = "http://localhost/MySite.ContentDelivery/MyController/GetMyObjects/?";
function getObjects() {
//
// build the URL
//
debugger;
var call = url + "id=48&jsoncallback=?";
//
// make the ajax call
//
$.getJSON(call, function (rsp) {
debugger;
alert(rsp);
if (rsp.stat != "ok") {
//
// something went wrong!
//
$("#myDiv").append(
"<label style=\"background-color:red;color:white;padding: 25px;\">Whoops! It didn't work!" +
" This is embarrassing! Here's what the system had to " +
" say about this - " + rsp.message + "</label>");
}
else {
//
// build the html
//
var html = "";
$.each(rsp.list.myObject, function () {
var obj = this;
html += "<span" + obj.Name + "</span> <br />";
});
//
// append this to the div
//
$("#myDiv").append(html);
}
});
}
//
// get the offers
//
$(document).ready(function() {
alert('go..');
$(getOobjects);
});
</script>
<div id="myDiv"></div>
</body>
</html>
tl;dr why is my getJson() not firing while my getObjects() fires and executes the MVC controller action.

Replace:
var call = url + "id=48&jsoncallback=?";
with:
var call = url + "id=48&callback=?";
The custom JsonpResult you are using relies on a query string parameter called callback and not jsoncallback:
Callback = context.HttpContext.Request.QueryString["callback"];
Also you have decorated your controller action with a [JsonpFilter] attribute and returning a JsonpResult. As explained in the article you must have read you should choose one:
[JsonpFilter]
public ActionResult GetMyObjects(int id)
{
List<MyObject> list = MyDAO.GetMyObjects(id);
return Json(list, JsonRequestBehavior.AllowGet);
}
or the other:
public ActionResult GetMyObjects(int id)
{
List<MyObject> list = MyDAO.GetMyObjects(id);
return new JsonpResult
{
Data = list,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
but do not mix the two.

Related

Active Directory how to get user from distinguishedName

I need some help on retrieving a user with distinguishedName in asp.net mvc project. I have a search function that has 2 properties to load, "displayName" and "distinguishedName". Once I find, I return a view with a list containing these two parameters for each user found. Then I want to be able to click on a user and immediately show their information. So how do I load the information about the user once I only have these two parameters passed through?
Here is the function that initially searches:
public List<string> SearchUserByName(string name){
try{
DirectoryEntry ldapConnection = createDirectoryEntry();
DirectorySearcher search = new DirectorySearcher(ldapConnection);
search.PropertiesToLoad.Add("displayName");
search.PropertiesToLoad.Add("distinguishedName");
resultCollection = search.FindAll();
if (resultCollection.Count == 0)
{
return null;
}
else
{
foreach(SearchResult sResult in resultCollection)
{
if (sResult.Properties["distinguishedName"][0].Equals(null) ||
sResult.Properties["displayName"][0].Equals(null))
continue;
displayName.Add(sResult.Properties["distinguishedName"][0].ToString());
displayName.Add(sResult.Properties["displayName"][0].ToString());
}
}
ldapConnection.Close();
ldapConnection.Dispose();
search.Dispose();
return displayName;
}
catch (Exception e)
{
Console.WriteLine("Exception caught:\n\n" + e.ToString());
}
return null;
}
Now my view:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Résultat de recherche d'utilisateurs</title>
</head>
<body>
<h2> Résultat de recherche d'utilisateurs</h2>
#{
var incLoop = 0;
var incArr = 0;
var list = (List<string>)ViewData["Names"];
var size = list.Count();
string[] objSID = new string[size];
foreach (var link in list)
{
if (incLoop % 2 == 0)
{
objSID[incArr] = link;
incArr++;
}
else
{
#link<br/>
}
incLoop++;
}
}
</body>
</html>
If you click on #link in the tag, you get the information, which is shown in the next view. I've also split my list to not show the distinguishedName in the search result view.
What I have done for now, is researching the Active Directory when you click on the link, but it seems like bad practice (searching twice for one result). Any ideas?
Thank you, hope it's clear

Knockout js, mvc 5 project - bind client ViewModel to the controller action

Could you please help me with this. I'm successfully getting data from the server ViewModel. However when I try to save client ViewModel from the view to the Controller Save action. I'm getting empty ViewModel. In the sample what I'm using was used JavaScriptSerializer. However this is not recommended to use in ASP.NET Core MVC project since there are Newtonsoft extension. Could you please help me to adopt below code to work?
#{
ViewBag.Title = "Details";
}
#{
var data = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model));
}
#section scripts
{
<script src="~/lib/knockout/dist/knockout.js"></script>
<script src="~/lib/knockout-mapping/knockout.mapping.js"></script>
<script src="~/js/realtyvm.js"></script>
<script type="text/javascript">
$(function () {
var realtyViewModel = new RealtyViewModel(#Html.Raw(data));
ko.applyBindings(realtyViewModel);
});
</script>
}
/* Realty Client ViewModel */
(function () {
RealtyViewModel = function (data) {
var self = this;
ko.mapping.fromJS(data, {}, self);
self.save = function () {
$.ajax({
url: "/App/Save/",
type: "POST",
data: ko.toJSON(self),
contentType: "application/json",
success: function (data) {
if (data.realtyViewModel != null)
ko.mapping.fromJS(data.realtyViewModel, {}, self);
}
});
}
}
})();
This how looks controller actions:
public ActionResult Create()
{
RealtyViewModel realtyViewModel = new RealtyViewModel();
return View(realtyViewModel);
}
public JsonResult Save(RealtyViewModel realtyViewModel)
{
Realty realty = new Realty();
realty.Title = realtyViewModel.Title;
realty.Description = realtyViewModel.Description;
realty.RealtyType = realtyViewModel.RealtyType;
_repository.InsertRealty(realty);
_repository.Save();
realtyViewModel.MessageToClient = string.Format("{0} realty has been added to the database.", realty.Title);
return Json(new { realtyViewModel });
}
Update, I opened XHR request, here is details:
Request payload
{Id: 0, Title: "Te", Description: "te", RealtyType: "te", MessageToClient: null}
Description:"te" Id:0 MessageToClient:null RealtyType:"te" Title:"Te"
Response:
{"realtyViewModel":{"id":0,"title":null,"description":null,"realtyType":null,"messageToClient":" realty has been added to the database."}}
I've resolved this issue by specifying from where coming data, by adding [FromBody] to post action.
public JsonResult Save([FromBody]RealtyViewModel realtyViewModel)
{
Realty realty = new Realty();
realty.Title = realtyViewModel.Title;
realty.Description = realtyViewModel.Description;
realty.RealtyType = realtyViewModel.RealtyType;
_repository.InsertRealty(realty);
_repository.Save();
return Json(new { realtyViewModel });
}

View not refreshing after AJAX post

I have a view (Index.cshtml) with a grid (Infragistics JQuery grid) with an imagelink. If a user clicks on this link the following jquery function will be called:
function ConfirmSettingEnddateRemarkToYesterday(remarkID) {
//Some code...
//Call to action.
$.post("Home/SetEnddateRemarkToYesterday", { remarkID: remarkID }, function (result) {
//alert('Succes: ' + remarkID);
//window.location.reload();
//$('#remarksgrid').html(result);
});
}
Commented out you can see an alert for myself and 2 attempts to refresh the view. The location.reload() works, but is basically too much work for the browser. The .html(result) posts the entire index.cshtml + Layout.cshtml double in the remarksgrid div. So that is not correct.
This is the action it calls (SetEnddateRemarkToYesterday):
public ActionResult SetEnddateRemarkToYesterday(int remarkID) {
//Some logic to persist the change to DB.
return RedirectToAction("Index");
}
This is the action it redirects to:
[HttpGet]
public ActionResult Index() {
//Some code to retrieve updated remarks.
//Remarks is pseudo for List<Of Remark>
return View(Remarks);
}
If I don't do window.location.reload after the succesfull AJAX post the view will never reload. I'm new to MVC, but i'm sure there's a better way to do this. I'm not understanding something fundamental here. Perhaps a nudge in the right direction? Thank you in advance.
As you requesting AJAX call, you should redirect using its response
Modify your controller to return JSONResult with landing url:
public ActionResult SetEnddateRemarkToYesterday(int remarkID) {
//Some logic to persist the change to DB.
var redirectUrl = new UrlHelper(Request.RequestContext).Action("Index", "Controller");
return Json(new { Url = redirectUrl });
}
JS Call:
$.post("Home/SetEnddateRemarkToYesterday", { remarkID: remarkID }, function (result) {
window.location.href = result.Url
});
After Ajax post you need to call to specific Url..
like this..
window.location.href = Url
When using jQuery.post the new page is returned via the .done method
jQuery
jQuery.post("Controller/Action", { d1: "test", d2: "test" })
.done(function (data) {
jQuery('#reload').html(data);
});
HTML
<body id="reload">
For me this works. First, I created id="reload" in my form and then using the solution provided by Colin and using Ajax sent data to controller and refreshed my form.
That looks my controller:
[Authorize(Roles = "User")]
[HttpGet]
public IActionResult Action()
{
var model = _service.Get()...;
return View(model);
}
[Authorize(Roles = "User")]
[HttpPost]
public IActionResult Action(object someData)
{
var model = _service.Get()...;
return View(model);
}
View:
<form id="reload" asp-action="Action" asp-controller="Controller" method="post">
.
.
.
</form>
Javascript function and inside this function I added this block:
$.ajax({
url: "/Controller/Action",
type: 'POST',
data: {
__RequestVerificationToken: token, // if you are using identity User
someData: someData
},
success: function (data) {
console.log("Success")
console.log(data);
var parser = new DOMParser();
var htmlDoc = parser.parseFromString(data, 'text/html'); // parse result (type string format HTML)
console.log(htmlDoc);
var form = htmlDoc.getElementById('reload'); // get my form to refresh
console.log(form);
jQuery('#reload').html(form); // refresh form
},
error: function (error) {
console.log("error is " + error);
}
});

How to save current URL to a cookie, and restore with javascript onclick

Can anyone help me to create a cookie to save the users current URL with location.href when they click a button, in effect a "save progress" button. Then have another load button to take the user to what had been saved in this cookie,
<!DOCTYPE html>
<html>
<head>
<script>
function newDoc()
{
window.location.assign(location.href)
}
</script>
</head>
<body>
<input type="button" value="Load Progress" onclick="newDoc()">
</body>
</html>
is this possible?
Many thanks.
You can create cookie using javascript.
You can use following function to make it easy.
You can read, right, delete cookies by using following functions.
/***create cookie using createCookie later you can read it eg. var url = readCookie("currenturl");***/
function newDoc(){ createCookie("currenturl", document.URL, 1);
}
function createCookie(name,value,days) { if (days) { var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toGMTString();
}
else var expires = "";
document.cookie = name+"="+value+expires+"; path=/";
}
function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function eraseCookie(name) { createCookie(name,"",-1);
}

JQuery AJAX HandleErrorAtribute PartialView

I have a function that submits a form to a MVC controller as follows -
function submitForm() {
$.ajax
({
type: 'POST',
url: '/Users/Index',
data: $('#searchForm').serialize(),
beforeSend: function() {
$('.usersearchresult').fadeOut('fast', function () { $('.loadinggif').show(); });
},
success: function (response) {
$('.loadinggif').hide();
$('.usersearchresult').hide().html(response).fadeIn('normal');
},
error: function (response) {
alert(response);
$('.loadinggif').hide();
$('.usersearchresult').hide().html(response).fadeIn('normal');
}
});
return false;
}
I wanted a central location to catch errors so I have extended HandleErrorAttribute -
public class ClientExceptionAttribute : HandleErrorAttribute
{
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public override void OnException(ExceptionContext context)
{
Log.Error(context.Exception);
context.ExceptionHandled = true;
// Verify if AJAX request
if (context.HttpContext.Request.IsAjaxRequest())
{
// Use partial view in case of AJAX request
var result = new PartialViewResult();
result.ViewName = "~/views/shared/error.ascx";
context.Result = result;
}
}
}
The error view is very simple -
#model String
#{
Layout = null;
}
<div class="exception">
<img src="../Content/Graphics/warning.png" />
<br />
<div class="message">#(String.IsNullOrEmpty(Model) ? "User Entry Api is currently unavailable" : Model) </div>
</div>
The problem is that AJAX on error never renders the partial view (error.cshtml) - it just gives me a blank screen.
So I have two questions -
How do I make AJAX render the partial error view
How can I pass a model to a partial view in the ClientExceptionAttribute
Thank you!
result.ViewName = "~/views/shared/error.ascx"; should be result.ViewName = "Error";
If anyone knows the answer to question number two I'd appreciate it.

Resources