locked
send complex and simple parameter to web api using ajax RRS feed

  • Question

  • User-1548796982 posted

    hi

    i write web api.

    web api controller:

    [HttpPost]
        public IHttpActionResult PostNewTask(string xx,string yy,CommonTask Task)
        {
    ...
    }

    and ajax:

    var task = new Object();
    
    task.Description = 'kjk';
    task.ID = null;
    
    
    var req = $.ajax({
        url: 'http://localhost:3641/api/TaskApi',
        contentType: "application/json",
        data: {"xx":'admin',"yy":'123',"task": JSON.stringify(task) },
        type: 'Post',
        success: function (data) {
            alert('success');
        }
    });
    
    req.fail(function (jqXHR, textStatus) {
        alert("Request failed: " + jqXHR.responseText);
    });

    and WebApiConfig:

    config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

    when run ajax, return error: No action was found on the controller 'TaskApi' that matches the request

    Saturday, March 2, 2019 7:42 PM

Answers

  • User475983607 posted

    tadbirgaran

    I want to use the web api in the mobile app and other web sites.

    Is there any solution?

    By design, Web API does not support multiple POST parameters.  An MVC controller will work though.

    namespace ApiDemo.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                ViewBag.Title = "Home Page";
    
                return View();
    
            }
    
            [HttpPost]
            public ActionResult PostNewTask(string xx, string yy, CommonTask CommonTask)
            {
                CommonTask.Id = 1;
                return Json(new { x = xx, y = yy, Description = CommonTask.Description, Id = CommonTask.Id  });
            }
        }
    }
    <div>
        <input id="Button1" type="button" value="button" />
    </div>
    
    @section scripts {
        <script>
            $(function () {
    
                $('#Button1').click(function (e) {
                    e.preventDefault();
    
                    var task = {
                        xx: 'admin',
                        yy: '123',
                        CommonTask: {
                            Id: null,
                            Description:'kjk'
                        }
                    };
    
                    $.ajax({
                        type: 'POST',
                        url: '/home/PostNewTask/',
                        //url: '/api/taskapi',
                        contentType: 'application/json; charset=utf-8',
                        dataType: 'json',
                        data: JSON.stringify(task),
                        success: function (response) {
                            console.log(response);
                        },
                        error: function (jqXHR, textStatus, errorThrown) {
                            console.log(jqXHR);
                            console.log(textStatus);
                            console.log(errorThrown);
                        }
                    });
                });   
                
            });
        </script>
    }

    Again, please use the browser's dev tools to debug your code. It shows a 405 (Not Allowed) error because Web API uses the parameters to find the best matching Action.  

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

    IMHO, the excuse that you have too may models indicates a design bug.  Rethink the action interfaces.  

    tadbirgaran

    The 'xx' and 'yy' parameters are the username and password of the user. The first step in action is to check if the user has that username and password, the intended operation is performed.

    It is possible to pass the username and password in the request header but you really should rethink this design as it has a rather large security vulnerability.  I recommend using standard login practices; using an authentication cookie or token.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, March 3, 2019 3:31 PM

All replies

  • User475983607 posted

    The URL does not match the action.  The action signature is invalid.   The data parameters are incorrect.

    hi

    i write web api.

    web api controller:

    [HttpPost]
        public IHttpActionResult PostNewTask(string xx,string yy,CommonTask Task)
        {
    ...
    }

    and ajax:

    var task = new Object();
    
    task.Description = 'kjk';
    task.ID = null;
    
    
    var req = $.ajax({
        url: 'http://localhost:3641/api/TaskApi',
        contentType: "application/json",
        data: {"xx":'admin',"yy":'123',"task": JSON.stringify(task) },
        type: 'Post',
        success: function (data) {
            alert('success');
        }
    });
    
    req.fail(function (jqXHR, textStatus) {
        alert("Request failed: " + jqXHR.responseText);
    });

    and WebApiConfig:

    config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

    when run ajax, return error: No action was found on the controller 'TaskApi' that matches the request

    Saturday, March 2, 2019 9:47 PM
  • User-1548796982 posted

    PostNewTask is action name.

    my controller:

    public class TaskApiController : ApiController
        {
    
            [HttpPost]
            public IHttpActionResult PostNewTask(string xx,string yy,CommonTask Task)
            {
                    ...
    
            }
    }

    Sunday, March 3, 2019 3:56 AM
  • User-1548796982 posted

    Is the definition and initialize of the parameters in Action and Ajax correct?

    While I define a parameter (CommonTask Task) for action and set it to an AJAX with "data:  JSON.stringify(task)"  it works correctly.

    Sunday, March 3, 2019 4:03 AM
  • User-2054057000 posted

    Change the URL to:

    url: 'http://localhost:3641/api/PostNewTask',

    Sunday, March 3, 2019 6:07 AM
  • User-1548796982 posted

    not working...

    Sunday, March 3, 2019 6:37 AM
  • User475983607 posted

    not working...

    Please do not response with "not working...".  This is a professional support forum, tells us exactly what is not working, share all the relavant code and explain the expected results and actual results.  Use the debugging tools to validate your written logic.

    Below is an working example.

    Model

    public class CommonTaskViewModel
    {
        public string xx { get; set; }
        public string yy { get; set; }
        public CommonTask CommonTask { get; set; }
    }
    
    public class CommonTask
    {
        public int? Id { get; set; }
        public string Description { get; set; }
    }

    API Action

    public class TaskApiController : ApiController
    {
        // POST: api/TaskApi
        public CommonTaskViewModel PostNewTask([FromBody]CommonTaskViewModel task)
        {
            task.CommonTask.Id = 1;
            return task;
        }
    }

    View

    <div>
        <input id="Button1" type="button" value="button" />
    </div>
    
    @section scripts {
        <script>
            $(function () {
    
                $('#Button1').click(function (e) {
                    e.preventDefault();
    
                    var task = {
                        xx: 'admin',
                        yy: '123',
                        CommonTask: {
                            Id: null,
                            Description:'kjk'
                        }
                    };
    
                    $.ajax({
                        type: 'POST',
                        url: '/api/taskapi',
                        contentType: 'application/json; charset=utf-8',
                        dataType: 'json',
                        data: JSON.stringify(task),
                        success: function (response) {
                            console.log(response);
                        },
                        error: function (jqXHR, textStatus, errorThrown) {
                            console.log(jqXHR);
                            console.log(textStatus);
                            console.log(errorThrown);
                        }
                    });
                });   
                
            });
    
    
        </script>
    }

    Sunday, March 3, 2019 1:45 PM
  • User-1548796982 posted

    Please do not response with "not working...".  This is a professional support forum, tells us exactly what is not working, share all the relavant code and explain the expected results and actual results.  Use the debugging tools to validate your written logic.

    Ok. Sure

    public class CommonTaskViewModel
    {
        public string xx { get; set; }
        public string yy { get; set; }
        public CommonTask CommonTask { get; set; }
    }


    I can not define the new model.

    Because the number of models in my project is high and I can not define a model view for each one of them.


    The 'xx' and 'yy' parameters are the username and password of the user.
    The first step in action is to check if the user has that username and password, the intended operation is performed.

    I want to use the web api in the mobile app and other web sites.

    Is there any solution?

    Sunday, March 3, 2019 2:48 PM
  • User475983607 posted

    tadbirgaran

    I want to use the web api in the mobile app and other web sites.

    Is there any solution?

    By design, Web API does not support multiple POST parameters.  An MVC controller will work though.

    namespace ApiDemo.Controllers
    {
        public class HomeController : Controller
        {
            public ActionResult Index()
            {
                ViewBag.Title = "Home Page";
    
                return View();
    
            }
    
            [HttpPost]
            public ActionResult PostNewTask(string xx, string yy, CommonTask CommonTask)
            {
                CommonTask.Id = 1;
                return Json(new { x = xx, y = yy, Description = CommonTask.Description, Id = CommonTask.Id  });
            }
        }
    }
    <div>
        <input id="Button1" type="button" value="button" />
    </div>
    
    @section scripts {
        <script>
            $(function () {
    
                $('#Button1').click(function (e) {
                    e.preventDefault();
    
                    var task = {
                        xx: 'admin',
                        yy: '123',
                        CommonTask: {
                            Id: null,
                            Description:'kjk'
                        }
                    };
    
                    $.ajax({
                        type: 'POST',
                        url: '/home/PostNewTask/',
                        //url: '/api/taskapi',
                        contentType: 'application/json; charset=utf-8',
                        dataType: 'json',
                        data: JSON.stringify(task),
                        success: function (response) {
                            console.log(response);
                        },
                        error: function (jqXHR, textStatus, errorThrown) {
                            console.log(jqXHR);
                            console.log(textStatus);
                            console.log(errorThrown);
                        }
                    });
                });   
                
            });
        </script>
    }

    Again, please use the browser's dev tools to debug your code. It shows a 405 (Not Allowed) error because Web API uses the parameters to find the best matching Action.  

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

    IMHO, the excuse that you have too may models indicates a design bug.  Rethink the action interfaces.  

    tadbirgaran

    The 'xx' and 'yy' parameters are the username and password of the user. The first step in action is to check if the user has that username and password, the intended operation is performed.

    It is possible to pass the username and password in the request header but you really should rethink this design as it has a rather large security vulnerability.  I recommend using standard login practices; using an authentication cookie or token.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, March 3, 2019 3:31 PM