DNN Web API is not getting parameter - asp.net

I created a Web API in DNN with sample provided in
http://www.dnnsoftware.com/community-blog/cid/142400/getting-started-with-services-framework-webapi-edition
with this example i modified HelloWorld method for getting parameter, but not able to get parameter in action while passing through ajax . here is my code
public class RouteMapper : IServiceRouteMapper
{
public void RegisterRoutes(IMapRoute mapRouteManager)
{
mapRouteManager.MapHttpRoute(
moduleFolderName: "MyServices",
routeName: "Default",
url: "{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional },
namespaces: new[] { "MyServices" }
);
}
}
public class WelcomeController : DnnApiController
{
[AllowAnonymous]
[HttpGet]
public string HelloWorld(WelcomeParameter id)
{
return "test" + id.UserID + id.ClientID + id.LanguageID;
}
}
public class WelcomeParameter
{
public int UserID;
public int ClientID;
public int LanguageID;
}
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
method: "GET",
url: "desktopmodules/myservices/apI/Welcome/HelloWorld/",
data: JSON.stringify({"id":{ "UserID": 1, "ClientID": 1, "LanguageID": 1}}),
contentType: 'application/json; charset=utf-8',
dataType: 'json'
})
.done(function (msg) {
alert("Content: " + msg);
});
});
</script>
This action is not returning output as
test111
test111

i m getting error as 405 Method Not Allowed "The requested resource
does not support http method 'POST'."
You want to add action method with HTTP POST too.
public class WelcomeController : DnnApiController
{
[AllowAnonymous]
[HttpGet]
public string HelloWorld()
{
return "";
}
[AllowAnonymous]
[HttpPost]
public string HelloWorld(WelcomeParameter id)
{
return "test" + id.UserID + id.ClientID + id.LanguageID;
}
}

Related

WebApi HttpPut is working fine in localhost. In server it not working. It throws 403

Created a web api [HttpPut] method. When testing from local host, data is getting updated. When access the api(hosted in nginx - aws ec2) it throws 403 error. This api is developed in asp.net core web-api.
This api is called through JQuery ajax.
Controller:
[Authorize]
[Route("api/v1/[controller]")]
[ApiController]
public class EventSchedulerController : ControllerBase
{
[HttpPut]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
[Route("UpdateEvent")]
public async Task<IActionResult> UpdateEvent(EventSchedulerDTO evt)
{
string message = string.Empty;
if (string.IsNullOrEmpty(evt.Id))
{
return BadRequest();
}
try
{
var existingEventData = _db.EventSchedulers.FirstOrDefault(m => m.Id == evt.Id);
existingEventData.Title = evt.Title;
existingEventData.Description = evt.Description;
existingEventData.EventStartDateTime = evt.EventStartDateTime;
existingEventData.EventEndDateTime = evt.EventEndDateTime;
_db.EventSchedulers.Update(existingEventData);
await _db.SaveChangesAsync();
return Ok(new { Status = "Success", Message = "Data successfully updated" });
}
catch (Exception ex)
{
return StatusCode(StatusCodes.Status500InternalServerError, ex);
}
}
}
JQuery:
$("#btnSaveSchedule").click(function () {
var eventSchedulerData = {
"id": $(this).data("event-id"),
"title": $("#txtTitle").val(),
"description": $("#txtDescription").val(),
"eventStartDateTime": new Date($("#txtStartDateTime").val()).toISOString(),
"eventEndDateTime": new Date($("#txtEndDateTime").val()).toISOString(),
};
$.ajax({
url: '/api/v1/EventScheduler/UpdateEvent',
type: 'put',
data: JSON.stringify(eventSchedulerData),
dataType: 'json',
contentType: 'application/json',
success: function (data, textStatus, xhr) {
}
});
});
Remove [Authorize] from your controller or you need to add a token to your ajax request.
After this try the code:
$("#btnSaveSchedule").click(function () {
var eventSchedulerData = {
id: $(this).data("event-id"),
title: $("#txtTitle").val(),
description: $("#txtDescription").val(),
eventStartDateTime: new Date($("#txtStartDateTime").val()).toISOString(),
eventEndDateTime: new Date($("#txtEndDateTime").val()).toISOString(),
};
$.ajax({
url: '/api/v1/EventScheduler/UpdateEvent',
type: 'PUT',
data: eventSchedulerData,
success: function (data, textStatus, xhr) {
}
});
});

Why ajax send parameters to controller is null?

I sending a post request to controller by ajax:
This is my code in cshtml file:
<script>
$("#btnSeachAjax").click(function () {
var token = $('input[name="__RequestVerificationToken"]').val();
$.ajax({
url: '#Url.Action("Search")',
data: { id: "1",title:"ba"},
contentType: 'application/json',
type: 'POST',
headers: {
"RequestVerificationToken": token
},
success: function (data) {
$("#data").html(data);
}
,
error: function (req, status, error) {
alert(error);
}
});
return false;
});
</script>
This is my code in controller:
[HttpPost, ActionName("Search")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Search([FromBody] string id,string title)
{
var movie = await _context.Movies.FindAsync(id);
return View(movie);
}
Value of id , title in controller = null.
Why ajax send parameters to controller is null?
I using Asp.net mvc net core 3.1.
public async Task<IActionResult> Search([FromBody] string id,string title)
Value of id , title in controller = null.
Based on your action method and accepted parameters, you can try to modify the Ajax code as below.
$.ajax({
url: '#Url.Action("Search")'+'?title=ba',
data: JSON.stringify("1"),
contentType: 'application/json',
type: 'POST',
//...
Besides, you can create a viewmodel and modify your action accept a complex type parameter, like below.
public class MyData
{
public string Id { get; set; }
public string Title { get; set; }
}
Action method
public async Task<IActionResult> Search([FromBody] MyData myData)
{
//...
On JS client side
$.ajax({
url: '#Url.Action("Search")',
data: JSON.stringify({ id: "1", title: "ba" }),
contentType: 'application/json',
type: 'POST',
//...

Redirecting via RedirectToAction gives 404 status

In controller's action is redirected to another action of the same controller. Result: "HTTP Error 404.0 - Not Found". GetData is called via ajax-request in JQuery. On redirect is requested url http://localhost:61327/Home/Index/qwertyQWERTY%20HTTP/1.1. Request address http://localhost:61327/Home/Index/qwertyQWERTY works fine. Code of controller, ajax-request and RouteConfig.cs is shown below.
Routes
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{d}",
defaults: new { controller = "Home", action = "Index", d = UrlParameter.Optional }
);
routes.MapRoute(
name: "Default1",
url: "{controller}/{action}/{data}",
defaults: new { controller = "Home", action = "GetData", data = UrlParameter.Optional }
);
}
HomeController
public ActionResult Index(string d)
{
Repository repository = new Repository();
ViewBag.ViewbagValues = repository.GetAllCustomersAndOrders();
Response.Write("Ku-ku");
Response.Write(d);
return View(repository.GetAllCustomersAndOrders());
}
[HttpPost]
[ValidateInput(false)]
public ActionResult GetData(string data)
{
Response.Write(Request.InputStream);
Response.Write("qwerty");
return RedirectToAction("Index", "Home", new {d="qwertyQWERTY"});
}
Script
function SendDataToController(data) {
$.ajax({
url: "Home/GetData",
type: "POST",
datatype: "text",
contentType: "application/text; charset=utf-8",
data: data,
success: function (result) {
alert("Data was send to the controller");
window.location = result.URL;
},
error: function (err) {
alert("Error: data was not send to the controller");
}
});
alert(data);
In addition to Stephen Muecke's note - this will work with your javascript:
[HttpPost]
[ValidateInput(false)]
public ActionResult GetData(string data)
{
var data = new { URL = Url.Action("Index", "Home", new {d="qwertyQWERTY"}) };
return Json(data, JsonRequestBehavior.AllowGet);
}

How to receive JSON as an MVC 5 action method parameter

I have been trying the whole afternoon crawling through the web trying to receive a JSON object in the action controller.
What is the correct and or easier way to go about doing it?
I have tried the following:
1:
//Post/ Roles/AddUser
[HttpPost]
public ActionResult AddUser(String model)
{
if(model != null)
{
return Json("Success");
}else
{
return Json("An Error Has occoured");
}
}
Which gave me a null value on my input.
2:
//Post/ Roles/AddUser
[HttpPost]
public ActionResult AddUser(IDictionary<string, object> model)
{
if(model != null)
{
return Json("Success");
}else
{
return Json("An Error Has occoured");
}
}
which gives me a 500 error on the jquery side which is trying to post to it? (meaning that it didn't bind correctly).
here is my jQuery code:
<script>
function submitForm() {
var usersRoles = new Array;
jQuery("#dualSelectRoles2 option").each(function () {
usersRoles.push(jQuery(this).val());
});
console.log(usersRoles);
jQuery.ajax({
type: "POST",
url: "#Url.Action("AddUser")",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(usersRoles),
success: function (data) { alert(data); },
failure: function (errMsg) {
alert(errMsg);
}
});
}
All I want to do is receive my JSON object in my mvc action?
Unfortunately, Dictionary has problems with Model Binding in MVC. Read the full story here. Instead, create a custom model binder to get the Dictionary as a parameter for the controller action.
To solve your requirement, here is the working solution -
First create your ViewModels in following way. PersonModel can have list of RoleModels.
public class PersonModel
{
public List<RoleModel> Roles { get; set; }
public string Name { get; set; }
}
public class RoleModel
{
public string RoleName { get; set;}
public string Description { get; set;}
}
Then have a index action which will be serving basic index view -
public ActionResult Index()
{
return View();
}
Index view will be having following JQuery AJAX POST operation -
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(function () {
$('#click1').click(function (e) {
var jsonObject = {
"Name" : "Rami",
"Roles": [{ "RoleName": "Admin", "Description" : "Admin Role"}, { "RoleName": "User", "Description" : "User Role"}]
};
$.ajax({
url: "#Url.Action("AddUser")",
type: "POST",
data: JSON.stringify(jsonObject),
contentType: "application/json; charset=utf-8",
dataType: "json",
error: function (response) {
alert(response.responseText);
},
success: function (response) {
alert(response);
}
});
});
});
</script>
<input type="button" value="click1" id="click1" />
Index action posts to AddUser action -
[HttpPost]
public ActionResult AddUser(PersonModel model)
{
if (model != null)
{
return Json("Success");
}
else
{
return Json("An Error Has occoured");
}
}
So now when the post happens you can get all the posted data in the model parameter of action.
Update:
For asp.net core, to get JSON data as your action parameter you should add the [FromBody] attribute before your param name in your controller action. Note: if you're using ASP.NET Core 2.1, you can also use the [ApiController] attribute to automatically infer the [FromBody] binding source for your complex action method parameters. (Doc)
There are a couple issues here. First, you need to make sure to bind your JSON object back to the model in the controller. This is done by changing
data: JSON.stringify(usersRoles),
to
data: { model: JSON.stringify(usersRoles) },
Secondly, you aren't binding types correctly with your jquery call. If you remove
contentType: "application/json; charset=utf-8",
it will inherently bind back to a string.
All together, use the first ActionResult method and the following jquery ajax call:
jQuery.ajax({
type: "POST",
url: "#Url.Action("AddUser")",
dataType: "json",
data: { model: JSON.stringify(usersRoles) },
success: function (data) { alert(data); },
failure: function (errMsg) {
alert(errMsg);
}
});
You are sending a array of string
var usersRoles = [];
jQuery("#dualSelectRoles2 option").each(function () {
usersRoles.push(jQuery(this).val());
});
So change model type accordingly
public ActionResult AddUser(List<string> model)
{
}
fwiw, this didn't work for me until I had this in the ajax call:
contentType: "application/json; charset=utf-8",
using Asp.Net MVC 4.

Getting ContentType in ASP.NET MVC 3

i have the following code in c#. I'm using ASP.NET MVC 3.
public override void ExecuteResult(ControllerContext context)
{
// If ContentType is not expected to be application/json, then return XML
if ((context.HttpContext.Request.ContentType ?? String.Empty).Contains("application/json"))
{
new JsonResult { Data = this.Data }
.ExecuteResult(context);
}
else
{
using (MemoryStream stream = new MemoryStream(500))
{
using (var xmlWriter = XmlTextWriter.Create(
stream,
new XmlWriterSettings()
{
OmitXmlDeclaration = true,
Encoding = UTF8,
Indent = true
}))
{
new XmlSerializer(typeof(T), IncludedTypes)
.Serialize(xmlWriter, this.Data);
}
// NOTE: We need to cache XmlSerializer for specific type. Probably use the
// GenerateSerializer to generate compiled custom made serializer for specific
// types and then cache the reference
new ContentResult
{
ContentType = "text/xml",
Content = UTF8.GetString(stream.ToArray()),
ContentEncoding = UTF8
}
.ExecuteResult(context);
}
}
}
I'm trying to return a json or a xml result depending the request. The problem is that i get context.HttpContext.Request.ContentType = "" when i run it.
Is there a way to make the application know that the request is "application/json"?
I'm returning this result object in a controller method called GetGoogleMapsMarkers:
$(document).ready(function () {
$.ajax({
type: "POST",
url: "http://localhost:1939/API/Google/GetGoogleMapsMarkers",
datatype: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
alert(data);
}
}
});
Help me please.
Thanks.
Unable to reproduce. Here's what I tried:
Result:
public class TestResult : ActionResult
{
public override void ExecuteResult(ControllerContext context)
{
var ct = context.HttpContext.Request.ContentType;
context.HttpContext.Response.Write(ct);
}
}
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult Foo()
{
return new TestResult();
}
}
View:
<script type="text/javascript">
$.ajax({
url: '#Url.Action("foo")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
success: function (result) {
alert(result);
}
});
</script>
The AJAX call resulted in the correct request content type to be fetched.
i added
data: { },
to the ajax call and it worked.... it's weird but it made it work...

Resources