WebForms GET Json requests (JsonRequestBehavior.AllowGet) - javascript

I have an old WebForms project that needs revisiting and I want to add some new features.
I want to load the data using $.getJSON(), this is very simple in ASP.NET MVC because you can return the data like this,
return Json(data, JsonRequestBehavior.AllowGet);
The Get doesn't work in WebForms,
// Http GET request
$.getJSON('Attributes.aspx/GetAttributes', { 'ProductId': '3' }, function (d) { alert(d); });
The Post works.
// Http POST
$.post('Attributes.aspx/GetAttributes', { 'ProductId': '3' }, function (d) { alert(d); });
Here is the WebForms WebMethod,
[WebMethod]
public static string GetAttributes(string ProductId)
{
List<QuoteAttribute> list = DAL.GetAttributes(ProductId);
var json = JsonConvert.SerializeObject(list);
return json;
}
I want to return json using the GET method.
Is there an JsonRequestBehavior.AllowGet for WebForms?
Any help is appreciated.
Thanks

Need to add "[ScriptMethod(UseHttpGet = true)]" before the method.This will allow GET method.
eg.
[WebMethod]
[ScriptMethod(UseHttpGet = true)]
public static string GetAttributes(string ProductId)
{
List<QuoteAttribute> list = DAL.GetAttributes(ProductId);
var json = JsonConvert.SerializeObject(list);
return json;
}

Related

How to pass data from Spring controller to JQuery $.post() call

After posting data from the Jquery $.post() method, I am attempting to return some data which I want to use in the Jquery alert() from a Spring boot 1.5.1 controller method. Currently, the returned data is empty when used in the alert().
Jquery:
$('#element').click(function() {
var formData = $('#element').serialize();
var posting = $.post( '/update.json?id=${item.id}', formData );
posting.done(function( data ) {
alert(data);
});
return false;
});
Controller:
#RequestMapping("/update.json")
#ResponseBody
public void update(HttpServletRequest request,
Map model,
#RequestParam(value="id", required=true) Integer id) {
// to validation and binding...
model.put("result", "test");
}
Why is the result property not accessible in the Jquery data object in the callback?
Your Controller has a return type as void, that's normal. You can either use a response entity, if you want to set the status:
return new ResponseEntity<String>("test", HttpStatus.OK)
or you can return a plain string a well.

Return JavaScript object literal, not JSON string, from ASP.NET MVC endpoint

For various reasons, I have switched from ASP.NET MVC's built in JSON serializer (the one that returns a System.Web.Mvc.JsonResult object (see edit below)) to Newtonsoft. I didn't realize until after I began testing that the former returns a JavaScript object literal, while Newtonsoft returns a JSON formatted string.
I like not having to parse JSON strings on the client side — having it already as an object literal is very convenient — but I want to stick with Newtonsoft for other technical reasons.
For example, instead of seeing this result on my client...
"{"Errors":["Please enter a valid email address."],"HasErrors":true}"
...I'd like to see this result:
{"Errors":["Please enter a valid email address."],"HasErrors":true} // no quotes
Is there a way to make Newtonsoft return JS object literals instead of strings?
EDIT
The way my question was framed wasn't the best. There's nothing wrong with the JsonResult type. In fact, the solution still uses it. The only problem was the default Controller.Json methods, which can be overridden to use Newtonsoft (Json.NET) instead of the built-in serializer.
Just write a custom JsonResult that uses Newtonsoft serializer:
Something along the lines:
public abstract class BaseController : Controller
{
protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding)
{
return new JsonNetResult
{
ContentType = contentType,
ContentEncoding = contentEncoding,
Data = data
};
}
protected override JsonResult Json(object data, string contentType, System.Text.Encoding contentEncoding, JsonRequestBehavior behavior)
{
return new JsonNetResult
{
ContentType = contentType,
ContentEncoding = contentEncoding,
Data = data,
JsonRequestBehavior = behavior
};
}
}
JsonNetResult.cs:
using System;
using System.Web;
using System.Web.Mvc;
using Newtonsoft.Json;
public class JsonNetResult : JsonResult
{
public JsonSerializerSettings SerializerSettings { get; set; }
public Formatting Formatting { get; set; }
public JsonNetResult()
{
Formatting = Formatting.None;
SerializerSettings = new JsonSerializerSettings();
JsonRequestBehavior = JsonRequestBehavior.DenyGet;
}
public override void ExecuteResult(ControllerContext context)
{
if (context == null)
throw new ArgumentNullException("context");
if (JsonRequestBehavior == JsonRequestBehavior.DenyGet
&& String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("This request has been blocked because sensitive information could be disclosed to third party web sites when this is used in a GET request. To allow GET requests, set JsonRequestBehavior to AllowGet.");
}
HttpResponseBase response = context.HttpContext.Response;
response.ContentType = !string.IsNullOrEmpty(ContentType)
? ContentType
: "application/json";
if (ContentEncoding != null)
response.ContentEncoding = ContentEncoding;
if (Data != null)
{
var writer = new JsonTextWriter(response.Output) { Formatting = Formatting };
var serializer = JsonSerializer.Create(SerializerSettings);
serializer.Serialize(writer, Data);
writer.Flush();
}
}
}
Credit: https://gist.github.com/jpoehls/1424538
Answer is here: How to force ASP.NET Web API to always return JSON?
Excerpt:
Clear all formatters and add Json formatter back.
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
EDIT
I added it to Global.asax inside Application_Start().

asp.net mvc, returning multiple views as JSON

Is it possible to return 2 separate views to an ajax call in Asp.net?
for example, if foo1 and foo2 are 2 ActionResult methods each returning a view?
return Json(new { a = foo1(), b = foo2() });
currently attempting this, the end result is that javascript gets it back as a class object rather then the actual view, anybody know how to get the resulting rendered html instead?
EDIT: I guess what I'm actually going for, is there a way for me to return the rendered view in string format?
Yes their is a way of returning view in string format.
For this you need to do following things:
1.You need some method in which you can pass your viewname along with object model. For this please refer below code and add to your helper class.
public static class RenderViewLib
{
public static string RenderPartialView(this Controller controller, string viewName, object model)
{
if (string.IsNullOrEmpty(viewName))
viewName = controller.ControllerContext.RouteData.GetRequiredString("action");
controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
}
The above code will return your view in string format.
2.Now call above method from your json call like this:
[HttpPost]
public JsonResult GetData()
{
Mymodel model = new Mymodel();
JsonResult jr = null;
jr = Json(new
{
ViewHtml = this.RenderPartialView("_ViewName", model),
ViewHtml2 = this.RenderPartialView("_ViewName2", model),
IsSuccess = true
}, JsonRequestBehavior.AllowGet);
return jr;
}
and you will get your view as string format from your json call.
Hope this is what you are looking for.

How to populate javascript variable with JSON from ViewBag?

I have this Index action:
public ActionResult Index()
{
var repo = (YammerClient) TempData["Repo"];
var msgCol = repo.GetMessages();
ViewBag.User = repo.GetUserInfo();
return View(msgCol.messages);
}
GetMessages returns a list of POCO messages and GetUserInfo returns a POCO with the info of the user (id, name, etc).
I want to fill a javascript variable with the JSON representation of the user info.
So I would want to do something like this in the view:
...
<script>
var userInfo = "#ViewBag.User.ToJson()"
</script>
...
I know that doesn't work, but is there a way to do that? I want to avoid having to do an ajax request once the page is loaded just to get the user info.
In View you can do something like this
#{
var jss = new System.Web.Script.Serialization.JavaScriptSerializer();
var userInfoJson = jss.Serialize(ViewBag.User);
}
in javascript you can use it as
<script>
//use Json.parse to convert string to Json
var userInfo = JSON.parse('#Html.Raw(userInfoJson)');
</script>
Was using this solution for simple objects. But I had some problems getting an array to js objects so I'll just leave what I did here.
C#
#{
using Newtonsoft.Json;
ViewBag.AvailableToday = JsonConvert.SerializeObject(list);
}
js
var availableToday = JSON.parse('#Html.Raw(ViewBag.AvailableToday)');
Client-Side Code:
This is an ajax call to a .Net MVC Controller:
var clientStuff;
$.ajax({
type: 'GET',
url: '#Url.Action("GetStuff", "ControllerName")',
data: {},
dataType: "json",
cache: false,
async: false,
success: function (data) {
clientStuff = data;
},
error: function(errorMsg) {
alert(errorMsg);
}
});
Server-Side Code:
CONTROLLER:
public JsonResult GetStuff()
{
return Json(_manager.GetStuff(), JsonRequestBehavior.AllowGet);
}
MANAGER:
public IEnumerable<StuffViewModel> GetStuff()
{
return _unitofWork.GetStuff();
}
UNIT OF WORK:
public IEnumerable<StuffViewModel> GetStuff()
{
var ds = context.Database.SqlQuery<StuffViewModel>("[dbo].[GetStuff]");
return ds;
}
Unit of Work can be a query to a sproc (as I have done), a repository context, linq, etc.
I'm just calling a sproc here for simplicity, although it could be argued that the simplicity lies with Entity Framework and Linq.
You can change this line :
ViewBag.User = repo.GetUserInfo();
To
ViewBag.User = new HtmlString(repo.GetUserInfo());
You should add using Microsoft.AspNetCore.Html; or using System.Web; if HtmlString is not accessible.

How to return Json object to view in a Async method

I have ASP.NET MVC 2 web app. On page load I call a javascript method:
function getSomeData() {
$.post(GetTablesDataUrl, null,
function (data) {
alert(data);
});
}
here is then called a method in my HomeController.cs
public void GetTablesData()
{
WebClient webClinet = new WebClient();
webClinet.DownloadDataAsync( new Uri("http://somer_url"));
webClinet.DownloadDataCompleted += new DownloadDataCompletedEventHandler(webClinet_DownloadDataCompleted);
}
when download is completed, next method is executed
void webClinet_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
byte[] responseArray = e.Result;
string s = responseArray.ToString();
ReturnDataToPage(s); // return json object
}
inside is am method to return data back to my page like this
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult ReturnDataToPage(string s)
{
var data = s;
return Json(data);
}
but I always get an empty string. What am I doing wrong???
You have two possibilities:
Use a normal controller and because the AJAX call is already async you probably wouldn't need more:
public class TablesController : Controller
{
[HttpPost]
public ActionResult ReturnTables(string s)
{
using (var client = new WebClient())
{
string result = client.DownloadString("http://example.com");
// Assuming the remote address returns a JSON object
// if not parse the response and return Json
return Content(result, "application/json");
}
}
}
Use an async controller and IOCP (I/O Completion Ports):
public class TablesController : AsyncController
{
[HttpPost]
public void ReturnTablesAsync(string s)
{
AsyncManager.OutstandingOperations.Increment();
var client = new WebClient();
client.DownloadStringCompleted += (sender, e) =>
{
try
{
AsyncManager.Parameters["result"] = e.Result;
}
finally
{
AsyncManager.OutstandingOperations.Decrement();
}
};
client.DownloadStringAsync(new Uri("http://www.example.com"));
}
public ActionResult ReturnTablesCompleted(string result)
{
// Assuming the remote address returns a JSON object
// if not parse the response and return Json
return Content(result, "application/json");
}
}
In both cases you would consume those actions the same way:
// Not sure exactly what was the purpose of the "s" query string
// parameter as I am not using it in the action
var data = { s: 'some data' };
$.post('<%= Url.Action("ReturnTables", "Tables") %>', data, function(result) {
// Do something with the result
});
The difference between those two approaches is that the async version would use I/O Completion Ports and wouldn't block any worker threads during the retrieval of the remote resource.
The main issue with your approach is that you are calling the external site ("http://somer_url") asynchronously.
This means that the action called by 'someDataDataUrl' (Which, I assume, is not shown in your question) will return immediately, and this is probably before the asynch call returns with your actual data.
The secondary issue (If my understanding of your - possibly mistyped - question is correct) is that when the asynch call handler is invoked, it calls 'ReturnDataToPage' (Should this be 'ReturnTables'?), and then does nothing with the JsonResult that it gets.
You would be better off calling the external site Synchronously (although this introduces block issues, so timeouts need to be introduced) and the returning the result of this call correctly.
Doing this, however, would entail a bit of extra research (Not something that I've done from .NET, I'm afraid)

Categories

Resources