Render Partial View using Jquery Ajax with variable data - asp.net-mvc-3

I have already read this post, but I am not sure know to make it work taking data from the user. Here is the ajax jquery I am using. I know (or at least think) that this cant render a partial. But it works all the way until the render fails. I thought it may be helpful to have.
$.ajax(
{
type: 'POST',
contentType: 'application/json; charset=utf-8',
data: "{'test':" + "'" + dateText + "'}",
dataType: 'json',
url: 'Site/Grab/',
success: function (result) {
alert('Success');
},
error: function (error) {
alert('Fail');
}
});
Here is my controller
[HttpPost]
public ActionResult Grab(string test)
{
DateTime lineDate= Convert.ToDateTime(test);
List<Info> myInfo= GameCache.Data(lineDate);
return PartialView("_PartialView", myInfo);
}

Okay, couple of things to try:
1) dataType is the expected result of the ajax call. In your case, your sending JSON, but receiving HTML. The content-type parameter specifies the request, which you have (and what you have is correct). So the data type should be:
dataType: 'html',
2) You need to serialize the JSON. Try grabbing the lightweight JSON library and stringify'ing:
var test = { test: 'testvalue' };
$.ajax {
...
data: JSON.stringify(test),
...
});
Much easier than trying to coerce a JSON string with quoatations. Create a regular JS variable, then stringify it.
The rest of your code looks fine.
If it's a problem with the HTML/markup of the partial view itself, run in debug mode and Visual Studio should stop on the line in the markup that is causing the problem.
Bonus Hint: ASP.NET MVC 3 includes built-in JSON model binding. So you can create a basic POCO that matches the fields of your JSON object, then accept it as a strongly-typed object in the action method:
[HttpPost]
public ActionResult Grab(MyJsonObject obj)
{
DateTime lineDate= Convert.ToDateTime(obj.test);
List<Info> myInfo= GameCache.Data(lineDate);
return PartialView("_PartialView", myInfo);
}
Since your only sending one parameter, it's overkill - but if you have more than 2 then it's worthwhile using a JSON POCO.

Change your controller code to:
public ActionResult Grab(string test) {
DateTime lineDate= Convert.ToDateTime(test);
List<Info> myInfo= GameCache.Data(lineDate);
return Json(new { data = this.RenderPartialViewToString("_PartialView", myInfo) });
}

Related

Requesting Data from API Controller using GET with data as complex object

I have, until today always used POST to get response from API Controllers in .NETCore/MVC applications, but have been struggling with performance and have noted that POST cannot be cached...
So, I am trying to change things to use a GET request.
I do not like this, because I would prefer the data sent as a form, not in the URL... but if it must, it must
Anyway, I am having trouble getting .NET to serialize data posted using an object in the AJAX post (using jQuery or otherwise, I don't care)
My controller looks like this:
[HttpGet]
[Route("ProductStockHistory")]
public async Task< ChartResponse> ProductStockHistory([FromQuery] ChartQuery value)
{
//// do stuff
}
You can see I want to send a ChartQuery object, this looks like this:
public class ChartQuery
{
public string dateFrom { get; set; }
public string dateTo { get; set; }
public string groupBy { get; set; } = "month";
// more values...
}
Using a POST, I would do this: (with the [HttpGet] attribute changed to [HttpPost] and [FromQuery] changed to [FromBody])
$.ajax({
type: "POST",
url: "/Chart/" + chartAction,
contentType: "application/json",
dataType: "json",
data: JSON.stringify({
dateFrom : dateFromValue,
dateTo : dateToValue,
groupBy : groupByValue,
// more values...
}),
success: function (data) {
// do stuff
}
});
This works fine... but as per my opening statement, I cannot cache a POST request/response.
You can probably tell I am trying to get data for a chart, so it is not changing, therefore a cached response is adequate for me.
I have tried many variations of the AJAX code and the most logical to me looks like this:
$.ajax({
type: "GET",
url: "/Chart/" + chartAction,
contentType: "application/json",
dataType: "json",
data: { value: JSON.stringify({
dateFrom : dateFromValue,
dateTo : dateToValue,
groupBy : groupByValue,
// more values...
})},
processData: true,
success: function (data) {
// do stuff
}
});
This is generating a URL like: /Chart/ProductStockHistory?value=%7B"dateFrom "%3AdateFromValue%2C"dateTo"%3AdateToValue%7D, which looks about right, but .NET is not serializing the value, I'm getting a null/default object as value in my controller.
It's entirely possible that I am approaching it wrong, but how can I get a cached response when using a complex object as a value in a controller?
EDIT: note, I realise I could change the controller to receive individual values of the ChartQuery object, but that is not what I am trying to achieve
You dont need to call JSON.stringify on your ajax request. Something like this should work:
data:{
dateFrom : dateFromValue,
dateTo : dateToValue,
groupBy : groupByValue,
}
This should produce a request url like this:
/Chart/ProductStockHistory?dateFrom=dateFromValue&dateTo=dateToValue&groupBy=groupByValue
.net core binds those values then correctly to your ChartQuery model.

Sending data to MVC Controller with AJAX

I am trying to send data with AJAX to MVC Controller method, but I don't know what am I doing wrong.
Here is the AJAX call
$.ajax({
type: 'POST',
url: invokingControllerActionUrl,
data: "it is just a simple string",
success: function (data) {
window.location.href = link;
}
});
And here is the controller method. It is invoked, but the parameter is always null.
public IActionResult OnPostTest([FromBody] string stringValue)
{
// stringValue is always null :(
}
Change you ajax call to this
$.ajax({
type: 'POST',
url: invokingControllerActionUrl, // Confirm the Path in this variable Otherwise use #Url.Action("OnPostTest", "InvokingController")
data: {stringValue: "it is just a simple string"},
success: function (data) {
window.location.href = link;
}
});
And remove the [FromBody]. ALso its better to define type post. Not necessary though
[HttpPost]
public IActionResult OnPostTest( string stringValue)
{
// stringValue is always null :(
}
Depending on what Content-Type you are sending from JS, you might need to encode your string properly, as a form-value
...
data: 'stringValue="it is just a simple string"',
...
or e.g. JSON:
...
data: '{stringValue: "it is just a simple string"}',
...
See also this discussion
I haven't found an easy way to pass a string of unformatted data via parameter, unfortunately. According to this answer, you can do the following:
public IActionResult OnPostTest()
{
Stream req = Request.Body;
req.Seek(0, System.IO.SeekOrigin.Begin);
string stringValue = new StreamReader(req).ReadToEnd();
...
// process your stringValue here
...
}

how to get the result from controller in ajax json

Isend the some aruguments to controller using ajax but it does not return the value.
My concept : selected #html.dropdownlist value i send to the controller , using this value thats perfrom the get the valus for bind the property to another dropdownlist using mvc3
IGot this answer : verfif given link
verfif given link
you are passing type option in ajax twice and the url is not formatted properly
function onChange(bookid) {
$.ajax({
type: "GET",
url: '#Url.Action("books","subject")',
data : { bookid: bookid},
dataType: "json",
success: function (result) {
alert('success');
//do whatever you want
},
error: function(result){
}
});
};
You are passing dataType as json. So, if you want to hit the success result for $.ajax, you need to return Json from your action result instead of returning as View.
When you return as View it gives error always.
public ActionResult books(string bookid)
{
var books= service.books(projectId);
// books are stored in list format
return Json(books);
}
Hope it helps you.

MVC3 Get Ajax Posted Values

in postback requests when i need posted values i do like this
[HttpPost]
public ActionResult Index()
{
//i need to get values in here not in action method argument
//i know this works but not like this --> ActionResult Index(string Name)
string Name = Request.Form["Name"];
}
but in ajax requests this does not work,,and i cant find where mvc store ajax posted values
Any Suggestions?
I'm a little late to the party, but I will offer an alternative that will allow you to access Request.Form with an Ajax post/form. This was tested in MVC 4 and jQuery 1.9.1.
If the controller's Request.Form is not populating for your Ajax post, it is likely because you are manually serializing and sending the data to the controller with a contentType of application/json (a common scenario).
Here is an jQuery.ajax example that will NOT populate Request.Form on the controller.
// JSON serialized form data.
var data = {"id" : "1234", "name" : "Dave"};
$.ajax({
type: "POST",
url: serviceUrl,
contentType: "application/json",
dataType: "json",
data: JSON.stringify(data || {}),
success: function () { }
});
Changing the contentType will cause the controller to process the post like a form submission.
// Form encoded data. See jQuery.serialize().
var data = "id=1234&name=Dave";
$.ajax({
type: "POST",
url: serviceUrl,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
dataType: "json",
data: data,
success: function () { }
});
You can also leave contentType undefined as application/x-www-form-urlencoded; charset=UTF-8 it is the jQuery default.
I would note that I only used $.ajax to better illustrate what is going on. You could also use $.post, though you will still need to send form encoded data
The ajax posted values won't appear in the request from collection however you can use the ValueProvider infrastructure in MVC to get the your Ajax posted value:
[HttpPost]
public ActionResult Index()
{
Name = ValueProvider.GetValue("Name").AttemptedValue;
}
Or the Request.InputStream contains all the posted data what you can read and deserailize as you want:
[HttpPost]
public ActionResult Index()
{
var serializer = new JavaScriptSerializer();
using (var streamReader = new StreamReader(Request.InputStream))
{
var data = (Dictionary<string,object>)serializer
.DeserializeObject(streamReader.ReadToEnd());
//assuming your posted data looks like this: '{"Name": "test"}'
string name = data["Name"].ToString();
}
}
But I highly recommend that you should not fight against the MVC infrastructure and recive the data as your action paratemer:
[HttpPost]
public ActionResult Index(string name)
{
}

No 'MediaTypeFormatter' is available to read an object of type 'String'

I'm using the ASP.NET Web API. I have an action in my controller which works fine if there's no parameter. If there is a parameter, like:
public string UploadFile(string actionType)
then my action isn't called and I get the following message, viewed in Fiddler:
No 'MediaTypeFormatter' is available to read an object of type 'String' with the media type 'multipart/form-data'
The route in my global.asx is as follows:
"api/{controller}/{action}/{actionType}"
I'm using Jquery Post to call the action:
function upload() {
var actiontype = $("input:radio[name=actiontype]").val();
var formData = new FormData($('form')[0]);
$.ajax({
url: 'api/uploads/uploadfile/' + actiontype,
type: 'POST',
success: function (data) {
$("#mydiv").append(data);
},
error: function (data) {
$("#mydiv").append(data);
},
data: formData,
cache: false,
contentType: false,
processData: false
});
};
Here's my action method:
public string UploadFile(string actionType)
{
if (Request.Content.IsMimeMultipartContent())
{
//Save file
MultipartFormDataStreamProvider provider = new MultipartFormDataStreamProvider(HttpContext.Current.Server.MapPath("~/Files"));
Request.Content.ReadAsMultipartAsync(provider);
}
return string.Format("Action {0} Complete!", actionType);
}
Is this a known problem, with a workaround? How can I have a simple action with parameter?
Assuming you're using the default routes, it looks like you're posting to an incorrect path. This is a common confusion that MVC developers seem to encounter (i know i did). MVC uses a default path like: /Controller/Action.
In web API's default routing setup, however, the action name is skipped (/api/Controller) then the method is found through the intersection of the HTTP verb name (post), the method name (Post___) and parameter if necessary.
Assuming you have an API controller named Uploads, you should have an action named PostUploadFile.
$.ajax({
url: 'api/uploads/',
type: 'POST',
Some things to notice...
I started the name of your action with the text "Post..." this matters, the remainder of the name does not
Your post url was shorted to the name of the controller.
I went more in depth explaining the mapping here.
EDIT
Apparently your experiencing an odity of WebAPI. The way around this is to stuff your "actionType" parameter into a simple object, so model binding can take over.
Rick Strahl explains this and some other binding oddities here. There is also another SO question addressing similar issues.

Resources