0

I am trying to call my newly created Web API to post a message but it does not work. I have a view that receives the data from controller action method. I am very new in creating web api and calling it from Ajax method so I am looking for good detailed instructions. I would like to pass message typed in by user in text area and also the message ID that I have added as an data attribute on button.

I have created a form and added a text area with button for user to send message. In the API, I would like to add it to database. I can do the database part but I would like the form to be updated once ajax call is done.

View code

 <div class="bg-dark rounded padding-x4">
            @*This form will be used to send messages. Use Jquery to run Api to send messages*@
            <form>
                <textarea placeholder="Send a new message..." id="messageToBeSent" rows="6" cols="100"></textarea>
                <button data-message-id="@Model.Messages.MessageID" class="btn btn-primary" id="sendMessage">Send Message</button>
            </form>
        </div>

My Web Api structure

[HttpPost]
        public IHttpActionResult SendMessages(int MessageID,string MessageReply)
        {
            //Add a message to MessageReply table

            return Ok();
        }

Jquery code

 <script>
        $(document).ready(function () {
            $("#sendMessage").on("click", function (e) {
                e.preventDefault();
                var MessageReplyParam = $('#messageToBeSent').val();
                var button = $(this);
                $.ajax({
                    //url: "/api/messages/SendMessages?MessageID=" + button.attr("data-message-id"),
                    url: "/api/messages/SendMessages",
                    method: "POST",
                    data:{
                        MessageID:button.data("message-id"),
                        MessageReply:MessageReplyParam
                    },
                    success: function (data) {
                    }
                });      
             });
        });

    </script>

Currently, it is not hitting my API class and on Network tab in google chrome it says 404 Not found. What am I doing wrong?

1
  • Instead of hard coding, I often use the helper method and stick it in an attribute: <span data-url="@Url.Action("SendMessages", "messages", new {/*Route values here*/)"> more info: learn.microsoft.com/en-us/dotnet/api/… An example: stick this in the <form> element Commented May 15, 2019 at 18:20

1 Answer 1

1

Your controller action is expecting a POST request, but you're trying to send a "SendMessages" request, which is not a valid HTTP verb. Specify POST in the options:

$.ajax({
    url: "/api/messages/" + button.attr("data-message-id"),
    method: "POST",
    success: function (data) {

    }
});

You can also use .data() to better get your data-* attribute value:

$.ajax({
    url: "/api/messages/" + button.data("message-id"),
    method: "POST",
    success: function (data) {

    }
});

Also, is your URL correct in the first place? Shouldn't it include the action name? And are your routes set up to automatically populate MessageID, or do you need to set it manually?:

$.ajax({
    url: "/api/messages/SendMessage?MessageID" + button.data("message-id"),
    method: "POST",
    success: function (data) {

    }
});

If you want, you can also use a server-side helper to generate your URL. Since it's a POST request you can put the values in the request instead of on the URL. Something like this:

$.ajax({
    url: "/api/messages/SendMessage",
    method: "POST",
    data: {
        MessageID: button.data("message-id")
    },
    success: function (data) {

    }
});

That way you can easily add as many properties to that data object as you like.

Edit: It's possible that you may run into model binding issues here though, and it may depend on the version of Web API. (I'm honestly not certain.) But sometimes it sees that JavaScript object as one parameter with properties, not as separate parameters.

In that case, create a server-side model:

public class Message
{
    public int MessageID { get; set; }
    public string MessageReply { get; set; }
}

And use it on the action method:

public IHttpActionResult SendMessages([FromBody]Message message)

This should more effectively bind the incoming JSON to the method parameter.

Sign up to request clarification or add additional context in comments.

12 Comments

But I have multiple Post methods, can I tell which function to call and also how do I pass multiple parameters?
@LearnAspNet: I've updated the answer. The URL likely needs to include the action method name, depending on how you have your routes set up.
It works after changing the url as you mentioned. I will accept the answer. But can you tell me how can I pass multiple parameters and what is best way to setup a route for API. I only want to pass the url with controller name
@LearnAspNet: I've updated the answer. Since it's a POST request you can add complex objects into the request data. In this case it's just a single property, but it can be more and include nested properties on other objects.
it does not work, I have updated the code in question with like you mentioned and also my web API
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.