How to return partial view or Json result based on condition? - asp.net-mvc-4

I have following code in the controller, here I want to return Partial View or Json Result to jquery. My problem is when this controller is hit jquery blocks the UI with some progress bar and waiting for response until it return. But when ModelState is false it return partial view which bypass jquery unblock UI. So this makes UI block forever.
[HttpPost]
public ActionResult Edit(Form form)
{
...
if (!ModelState.IsValid)
{
return PartialView("EditPartial", model);
}
return Json(new
{
Success = true,
Id = ID
});
}
How can I solve this problem?

Your controller method is behaving properly. You just need to modify your ajax call:
$.ajax({
url: '<your url>',
dataType: 'json',
success: function(data, textStatus, jqXHR) {
// You have the json result.
},
error: function(jqXHR, textStatus, errorThrown) {
// You have the partial view
}
});
An empty response is also is considered to be a failed json parse. Your controller method should either return a response of null or {} instead.
See the below url for more details of dataType and error
http://api.jquery.com/jQuery.ajax/

Related

Send string from asp.net core controller to ajax in ajax call response

hi I'm trying to send a string from controller to ajax in ajax call response. but my ajax doesn't get the string in response , and i see the raw content in browser.Actually ,this is a simple example of my main project.
I'm using ASP.NET Core for server side programming.
here's my codes:
server side :
public IActionResult addlink(string link)
{
return Redirect("/home/showlink?key=" + link);
}
public IActionResult showlink(string key)
{
return Content("this is content from 2nd controller");
}
client side :
<form>
<input type="text" id="mainlink"/>
<button id="btn">submit</button>
</form>
<script>
$("#btn").click(function () {
$.ajax({
type: "POST",
url: "/home/addlink",
data: {
"link": $("#mainlink").val()
},
success: function (response) {
alert(response);
},
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
}
}
)
})
</script>
what i see in browser :
in main project i want to send a text from controller to ajax call succes ,just this, please help me :)
Try to return Ok ActionResult:
public IActionResult addlink(string link)
{
return Ok("/home/showlink?key=" + link);
}
If you add ajax to the submit button in the form, you should prevent the default behavior of form submission.
<script>
$("#btn").click(function (e) {
e.preventDefault();
$.ajax({
type: "POST",
url: "/home/addlink",
data: {
"link": $("#mainlink").val()
},
success: function (response) {
alert(response);
},
error: function (xhr, status, error) {
var err = eval("(" + xhr.responseText + ")");
alert(err.Message);
}
}
)
})
</script>

Calling MVC5 action using AXIOS and ValidateAntiForgeryToken

I am trying to call a controller method marked with [ValidateAntiForgeryToken] from my UI using Axios.
I have successfully called the same action by using Jquery ajax
Working AJAX Code.
First i get the token from my form
var addAntiForgeryToken = function (data) {
data.__RequestVerificationToken = $("[name='__RequestVerificationToken']").val();
return data;
};
amd then i call my method
$.ajax({
type: "POST",
url: "http://localhost:40428/controller/action",
data: addAntiForgeryToken({ }),
success: function (response) {
}
});
The above successfully calls the following method in my controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Test_Get()
{
ViewBag.Search = true;
return View("Index");
}
What i have already tried with axios is the following
axios({
method: 'post',
url: 'http://localhost:40428/Meeting_Notes/Test_Get',
data: addAntiForgeryToken({})
});
I have also tried setting the headers manually but I still cannot get it to work.
After searching around for a bit I found a simple solution. First create the controller and decorate it with HttpPost and ValidateAntiForgeryToken
[HttpPost]
[ValidateAntiForgeryToken]
public void Test_Axios(int id) { }
Then before calling the controller using axios add the following interceptor for the headers. This will define the header as default for all axios api calls
axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
then retreive the token
var token = document.querySelector('token, input').getAttribute('value');
then use the qs library to stringify the call with the token (Be careful! it's Qs and not qs!)
var request = Qs.stringify({ id: 22, __RequestVerificationToken: token });
if you don't wanna pass any parameters then you can just use the following
var request = Qs.stringify({ __RequestVerificationToken: token });
then just call the controller method
axios({
method: 'post',
url: "/controller/Test_Axios",
data: request
});
And you are done! You can now start calling mvc 5 controller, decorated with the [ValidateAntiForgeryToken] attribute.

Creating post web api 2 actions

I am currently attempting to do something that should be fairly straight forward, but to be honest is pretty far from it at the moment and its driving me a bit mad.
I've been consuming Get actions in my WebApi, however I'm trying to create Post actions in order to keep my mvc controllers clean however I can't for the life of me figure out why my get actions work as expected but my post action results in a 404
using Microsoft.AspNet.Authorization;
using Microsoft.AspNet.Mvc;
using TamWeb.Models.api;
namespace TamWeb.Controllers.api
{
[Authorize]
[Route("api/[controller]")]
public class AdminController : Controller
{
[HttpPost]
public bool UpdateDetails([FromBody]DetailsViewModel model)
{
return false;
}
}
}
using System;
namespace TamWeb.Models.api
{
public class DetailsViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
The api controller is as simple as it gets and as per several other api questions instead of using string parameters I've created a model object and to follow other answers and what little out of date documentation I can find I consume the api as follows:
$(function() {
var firstname = $('#firstName').val();
var lastname = $('#lastName').val();
$.ajax({
url: "api/admin/UpdateDetails",
type: "POST",
data: JSON.stringify([firstname, lastname]),
success: function(data) {
console.log(data);
},
error: function() { console.log("error") }
});
});
As far as I can tell everything "should" work, however fiddler keeps telling me the url doesn't exist so now I'm at a loss as to whats wrong.
hopefully my answer can help you to deal with your question.
1.first issue you have to use "ApiController" instead "Controller"
2. [Authorize] <-- you have to get token key and then using it to get data from webapi
as following code, I will share you me simple code without Authorize,I wish it can solve your problems
client code
$("#read1").click(function () {
$.support.cors = true;
$.ajax({
crossDomain: true,
url: 'http://localhost:43520/api/Banners/',
datatype: "json",
contenttype: "application/json; charset=utf-8",
data: { id: 123 },
type: 'post',
error: function (xhr, status, errorThrow) {
alert(xhr.status);
},
success: function (data) {
alert(JSON.stringify(data));
}
});
});
server code
// GET: api/Banners/5
[ResponseType(typeof(Banners))]
public IHttpActionResult GetBanners(int id)
{
Banners banners = db.Banners.Find(id);
if (banners == null)
{
return NotFound();
}
return Ok(banners);
}

Why page url changes after PUT method in Web API?

I am using Web API in a MVC Website. This is my Update action in the API controller:
public HttpResponseMessage PutProduct(int Id, ProductModel model)
{
HttpResponseMessage response = null;
if (ModelState.IsValid)
{
model.ProductId = Id;
if (model.Update())
response = Request.CreateResponse(HttpStatusCode.Created);
}
return response;
}
I call it using JQ AJAX from a partial view which is loaded in the Index.cshtml page. The code works fine and the index page does not get called again, instead, the new list is populated in the partial view itself. I am not calling Index page again. But after the response, the page url changes to show like this:
http://localhost:54820/Products/Index?ProdName=Chicken+Soup&Category=Chinese&Price=20
This is my AJAX:
function updateprod(product) {
$.ajax({
url: uri + '/' + product.ProductId,
type: 'put',
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(product),
statusCode: {
201: function (data) { //accepted
loadlist();
}
}
})
.fail(function (xhr, textStatus, err) {
alert(err);
});
}
I want the URL to be like this, like what it was initially:
http://localhost:54820/Products/Index
Can anyone help ?
You should look at the response headers.
It seems that your response has a location header used by the user-agent to redirect to URL indicated in the response.
Besides that you should use 201 status-code for created resources, for update is better to use 200 (OK), how you can read in the w3c docs.
Hope it helps.

asp.net webapi validation

I have an API Controller and call action from JS:
$('#create-se').on('click', function () {
var data = {};
$.ajax({
url: 'api/registration',
type: 'POST',
data: data,
dataType: 'json',
contentType: 'application/json',
success: function () {
}
});
});
public bool Post(UserRegistrationViewModel model)
{
if (!ModelState.IsValid) { return false; }
return true;
}
Model has few required properties and few StringLength. When I send data from js to controller ModelState.IsValid always returns true. I can't figure out how to solve it. Even if posted model is null, Model.IsValid is true anyway
http://codebetter.com/johnvpetersen/2012/04/02/making-your-asp-net-web-apis-secure/
This website has a better way of doing validation and using headers to send the token across and if it invalid it will return validation failed.