ASP.Net MVC 3 WebFormsViewEngine HTML Helpers and JSON data - asp.net-mvc

I would like to know if is possible in ASP.Net MVC 3, using Web forms view engine and HTML Helpers, and the client side we are using Ext.Js to generate the grids.
The problem is when I return JSON(data) for the Ext.JS grid and the HTML Helper.
The HTML Helper is not able to render the JSON element.
It pops-up a window asking "What firefox should do with this file?".
I've tried to use:
return this.Json(new { objectJson = object}, "text/html", JsonRequestBehavior.AllowGet);
And it returned a new page with the HMTML Code, didn't bind to the HTML Helpers. I also tried without the JsonRequestBehavior.AllowGet and the result was:
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.
And even if I change the MIME type of the Header to application/json and make the method's return as JSONResult instead of ActionResult it still doesn't recognize the file.
return this.Json(new { IssueInventoryPartModel = issueInventoryPartmodel, success = true }, "application/json", JsonRequestBehavior.AllowGet);
Briefly the question is: The HTML Helper for Web Form View Engine binds with JSON?
Best regards,
Tito

I had this problem while sending html data via json, and solved it by adding contenttype to the jsonresult, in the server side action method (called via js in client side), there should be something like :
return Json(dataToReturn, "text/html")

it sounds like the content-type for the action result is not being set properly

how about including JsonRequestBehavior.AllowGet on the return of the JSON as in:
return Json(new
{
data = components,
success = true
}, JsonRequestBehavior.AllowGet);

Related

Use ValidateAntiForgeryToken with JQGrid in asp.net MVC?

In a hybrid asp.net web forms/mvc 5.2.6 application, using JQuery.jqGrid v4.4.4, I'm struggling to discover a way to use the ValidateAntiForgeryToken attribute on the Controller method that jqGrid posts to when fetching its data.
The grid is read-only. The "datatype" is "json" and the "mtype" is "POST". I've tried simply appending the value of the __RequestVerificationToken hidden input to the data that gets posted back to the Controller, but that does not work; the site simply throws a missing antiforgery token exception.
I notice that when one wants to make an $.ajax post of json data to a Controller method one can pass the __RequestVerificationToken in the "headers" parameter. While the jqGrid makes an $.ajax call behind the scenes, unfortunately it does not have a headers parameter.
I've found examples on SO where one can pass the token via the editData parameter (such as this: JQGrid able to pass ValidateAntiForgeryToken through the main CRUD controls?), but my grid is read-only, and in any case I want to enforce the token when the user enters search criteria and then clicks a button to fill the grid.
Is there any way to use the ValidateAntiForgeryToken when filling a jqgrid?
You can include postData parameter with __RequestVerificationToken property defined as the following function:
postData: {
__RequestVerificationToken: function () {
return jQuery("input[name=__RequestVerificationToken]").val();
}
}
It will add __RequestVerificationToken parameter to all request sent to the server during filling the grid.
Oleg's answer was the correct answer for me, but I also bumbled across this broader-brush solution from https://github.com/VahidN/jqGrid-Samples/blob/master/jqGrid04/jqGrid04/Views/Home/Index.cshtml, which adds the verification token to every ajax POST:
$(document).ajaxSend(function (elm, xhr, s) {
let securityToken = $('[name=__RequestVerificationToken]').val();
if (s.type === 'POST' && typeof securityToken != 'undefined') {
if (s.data.length > 0) {
s.data += "&__RequestVerificationToken=" + encodeURIComponent(securityToken);
}
else {
s.data = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
}
}
});

Returning result for .net Web Api from db call

I'm new to the .net Web API and am trying to figure out how I return a Get result from a call to my database. I know everything works in my regular MVC page. But Not sure how to return the result from the Web API controller. I thought it was as simple as returning Json with the result. Here is my code:
// GET api/<controller>
public IEnumerable<string> Get()
{
using (var _db = new JobsDatabaseEntities())
{
var user = Env.CurrentUser;
var posts =
_db.JobPostings.Where(
j =>
j.City.Equals(user.City, StringComparison.OrdinalIgnoreCase) &&
j.Industry.ID == user.Industry.ID);
var result = new List<BusJobPost>();
foreach (var post in posts)
{
var p = new BusJobPost(post);
result.Add(p);
}
return Json(result);
}
}
Please visit this resource: Action Results in Web API 2. Your case is described in fourth section Some other type (which is applicable to first version of Web API as well).
In Web API you don't return JSON result explicitly. It is actually done by process called Content Negotiation. You can read about it here [Content Negotiation in ASP.NET Web API] in detail.
Highlighting briefly just some of this:
You can set Accept header for you request as: Accept: application/json (for example, if you use jquery ajax function: dataType: 'json')
Or even if you don't use Accept header at all, if you send request with JSON data, you should also get response back in JSON format
So you should just return result variable from your controller action and satisfy some of conditions to get response serialized into JSON.

Redirecting from an API

I am trying to learn/expand my knowledge of .NET MVC/REST/API's and Web-sockets/SignalR. To do this I am implementing a chat app.
I have a typical MVC intro page that gets the users name and email address in a form and that data is submitted to a RESTFul API where the new user is added to the database.
<form class="form-horizontal" role="form" action="/api/GroopsAPIUsers" method="POST">
Inside of the controller for that page(?) I'm redirecting the user to a page where they can select which room they would like to enter.
public HttpResponseMessage Post( GroopsUser userValue)
{
userValue.ID = Guid.NewGuid();
bool results = groopsRepository.AddNewUser(userValue);
// return results;
var response = Request.CreateResponse(HttpStatusCode.Redirect);
//from http://stackoverflow.com/questions/11324711/redirect-from-asp-net-web-api-post-action
string fullyQualifiedUrl = Request.RequestUri.GetLeftPart(UriPartial.Authority);
response.Headers.Location = new Uri (fullyQualifiedUrl + "/home/rooms/?userID=" + userValue.ID);
return response;
}
But this doesn't feel right. It seems like the API should only be doing CRUD operations and shouldn't have anything to do with which page the user is redirected to.
Is this the wrong approach?
If so, can someone point me in the right direction?
(I'm not sure that I've used all of these terms correctly)
...gregory
I can see why you don't think it feels right. Usually, you would design your Web API in such a way, that it is platform agnostic, so the only thing it cares about is the incoming HTTP requests, and operations based on those. When you redirect a request to another URL, you are designing around the web browser, thus constraining yourself to that one platform. Sometimes that's what you need, sometimes it isn't.
(if it indeed is what you need, then you should probably stick to just regular Asp.NET MVC, and not Web Api)
Instead of what you have now, you could make your application more flexible by returning, for example, a 200 status code from your controller, after a successful operation. That way, it is up to the client-side application to decide what to do from there. (This is where you redirect, if your client-side application is browser-based.)
So how exactly do you achieve this with your browser application? You might already have guessed it, but the answer is Javascript. Instead of making a synchronous POST request to your API, via your form, you could make the request async, and then wait for the response from the server. Then you can take an appropriate action, based on what the response contains.
A quick example:
Controller
public HttpResponseMessage Post(GroopsUser userValue)
{
userValue.ID = Guid.NewGuid();
bool results = groopsRepository.AddNewUser(userValue);
var response = Request.CreateResponse<GroopsUser>(HttpStatusCode.OK, userValue);
return response;
}
Form
<form class="form-horizontal" id="group-form" onsubmit="return addToGroup()" role="form" action="/api/GroopsAPIUsers" method="POST">
Javascript (jQuery)
<script>
function addToGroup()
{
$.ajax({
type: "POST",
url: $('#group-form').attr('action'),
data: $('#group-form').serialize(),
dataType: "json",
success: function(data) {
window.location.replace('/home/rooms/?userID=' + data.ID);
},
error: function(){
alert('error handing here');
}
});
return false;
}
</script>
If anything is unclear, or if I'm mistaken about anything, please let me know!
It depends on what you are doing with said API. You can setup an API to perform purely CRUD operations or you can make your API a lot smarter and say have it serve up actual HTML to be rendered on the client (which is sort of what MVC does) or you can take it a step further and turn it into a Hypermedia service that will define the view as well as the state of your system. The front end is then tasked with simply rendering what is provided by your API.

return Json will redirects to another view when Url specified

When you do return Json(...) you are specifically telling MVC not to use a view, and to serve serialized JSON data. Your browser opens a download dialog because it doesn't know what to do with this data.
i got the above information from below link
How to return Json object from MVC controller to view
when i give this below code in some action result
return Json(new { Url = "sep/employee"}
whether it will redirect to specified action ? how it redirects to the URl ?
for this case why i cant use return RedirectToAction("sep/employee").
how return Json code redirects to action which specified in the Url.
ex:
public ActionResult Index()
{
................................
return Json(new { Url = "sep/employee"}
}
public ActionResult employee()
{
....................
}
what is the difference b/s redirectaction and return Json
You return the following line to an ajax success call
return Json(new { Url = "sep/employee"});
you then need to specify where to redirect to the new page
success: function(result) {
window.location.href=result.Url;
}
RedirectToAction simply returns 302 code to your browser with URL telling where the browser should redirect to. The browser immediately makes yet another call to the server to that URL obtained from redirection response.
RedirectToAction internals are:
Construct redirection url from parameters passed to RedirectToAction
Return new RedirectToRouteResult
In ExecuteResult of RedirectToRouteResult you can find the following line:
context.HttpContext.Response.Redirect(destinationUrl, endResponse: false);
which is merely returning 302 with redirection URL. More info - look at source code here.
Returning JSON data simply returns JSON serialized object to your browser. Is not meant to do any redirect. To consume such a result you will likely call the server using $.ajax:
$.ajax({
url: 'sep/employee',
type: 'POST'
success: function(result) {
// handle the result from the server, i.e. process returned JSON data
}
});
ExecuteResult of JsonResult just serializes passed CLR object to the response stream, which lands in your browser after response is fully received. Then you can handle such response in JavaScript code.
EDIT:
You of course can mimic 302 redirection by returning Json like
return Json(new { Url = "redirectionUrl"}
and at client side handle it like
$.ajax({
url: 'sep/employee',
type: 'POST'
success: function(result) {
// mimic the 302 redirection
windows.location.href = result.Url
}
});
although IMHO it should be avoided since you reinvent MVC infrastructure and enlarge your code base.
whether it will redirect to specified action ? how it redirects to the URl ?
I assume you mean to ask, "will it redirect to specified action? how will it redirect the the URI?"
To answer your question: How it redirects to the URL?
In your example it will redirect to the URL, if you made the HTTP request as AJAX and that you will explicitly handle the resulting HTTP response to actually redirect to the URL that you received. So your view should have something like this:
$.ajax({
url: '{your controller}/index',
type: 'GET'
success: function(url) {
// write code to redirect to the URL
// example:
// window.navigate(url)
}
});
If your view does not have anything that, then it will not redirect. You did not post your view, so I am assuming it just a normal page load.
Your next question, what is the difference b/s redirection and return Json?
If you really just want to redirect then do RedirectToAction from your controller, that is exactly what it is for. You can do the same effect using AJAX and JSON to be able to redirect, but AJAX and JSON serves a much wider purpose than just redirecting and in most cases (unless you have very good reasons) you probably will not want replace RedirectToAction with that approach.

MVC4 not binding a list of basic types

I cannot, for the life of me, get this data to bind. Here's my JavaScript:
var params = { 'InvItemIDs': ["188475", "188490"]};
$.post("api/Orders/OrderFromInventory?" + $.param(params))
and the Controller action:
public HttpResponseMessage OrderFromInventory(IList<int> InvItemIDs)
{
return new HttpResponseMessage();
}
I've built the query string so that it's sending:
?InvItemIDs=188475&InvItemIDs=188490
as well as
?InvItemIDs[]=188475&InvItemIDs[]=188490
and even
?InvItemIDs[0]=188475&InvItemIDs[1]=188490
and none of them are binding. InvItemIDs is always null. What am I doing wrong?
EDIT:
So it turns out all this is a bug (or something) in the new Web API controller code in MVC4. As soon as I moved the exact same code over to a standard controller it started working.
I'm still interested if anyone has any insight as to why the Web API would break this binding.
The reason it doesn't work is because you are using [HttpPost] where it will be expecting the data to be posted in "post body" instead of URL.
You can either
1, remove httpPost
2. put the list in the post content
You would need to set the "traditional: true" for the array to work. Here is a sample code that I've tested on my local project, give that a try
var InvItemIDs = ["188475", "188490"];
$.ajax({ type: "POST",
url: "Home/TestIndex",
datatype: "json",
traditional: true,
data:
{
'InvItemIDs': InvItemIDs
}
});
This Haacked blog post may help. Specifically, looking at his first example, what happens if you change IList to ICollection?
Something like this "should" work
[HttpGet]
public HttpResponseMessage OrderFromInventory(IList<int> InvItemIDs)
{
return new HttpResponseMessage();
}
with the querystring
?InvItemIDs=188475&InvItemIDs=188490

Resources