1

I am using ASP.NET WebApi 2.0 I have published it on localserver and am trying to consume the services

This is how my Api Controller looks

public class TestController : ApiController
{
    public List<string> names = new List<string>();
    public String Get()
    {
        return "Hello I am Service";
    }

    public IEnumerable<string> Post([FromBody]string custName)
    {
        try
        {

            names.Add(custName);
            return names;
        }
        catch(Exception ex)
        {
            return null;
        }           
    }
}

I am using jQuery AJAX to post the values & it looks as below

var customerName = $('#txtName').val();

$.ajax(
{
 url:"http://myip:8060/Api/Test",
 method:"POST",
 data:{'custName',customerName},
 success:function(data)
 {
  console.log(data);
 }
error:function(e)
{
 console.log(e);
}
})

Now if I alert customerName, I am getting the correct value, but when I am returning the Post action of the controller is returning null as below

[null]
[null,null] 

My question is why the values are getting null?

mason
  • 31,774
  • 10
  • 77
  • 121
Kgn-web
  • 7,047
  • 24
  • 95
  • 161

4 Answers4

1

The model binder of ASP.NET Web API can't translate a JSON to a string, you must use an object to do this think.

So you have 3 options to fix your problem

First, use query string

In your action change the attribute FromBody to FromUri, like that

public IEnumerable<string> Post([FromUri]string custName)
{
    try
    {
        names.Add(custName);
        return names;
    }
    catch (Exception ex)
    {
        return null;
    }
}

Then change your javascript code

$.post("/Api/Test/?custName=" + customerName, function(data) {
    console.log(data);
}).error(function(e) {
    console.log(e);
});

Second, use route attribute

Decorate your action with Route attribute like that

[Route("api/test/{custName}")]
public IEnumerable<string> Post([FromUri]string custName)
{
    try
    {
        names.Add(custName);
        return names;
    }
    catch (Exception ex)
    {
        return null;
    }
}

Then change your javascript code

$.post("/Api/Test/" + customerName, function(data) {
    console.log(data);
}).error(function(e) {
    console.log(e);
});    

Obs.: To use the Route attribute you must configure it in WebApiConfig, so you must have this line there:

config.MapHttpAttributeRoutes();

So your WebApiConfig should be like this

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();

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

Third, use a view model class

Create a class

public class ViewModel
{
    public string custName { get; set; }
}

Receive this model in your action, using FromBody attribute

public IEnumerable<string> Post([FromBody]ViewModel viewModel)
{
    try
    {
        names.Add(viewModel.custName);
        return names;
    }
    catch (Exception ex)
    {
        return null;
    }
}

Then change your javascript code

$.post("/Api/Test/", { custName: customerName }, function(data) {
    console.log(data);
}).error(function(e) {
    console.log(e);
});

Obs.: Your controller has a little bug

public class TestController : ApiController
{
    public List<string> names = new List<string>();

    public string Get()
    {
        return "Hello I am Service";
    }

    //Rest of code
}

Each controller in Web API and MVC is created everytime when a request is handled by the server, so your names field in TestController class will be a new List in every request, if you want to keep data in this list other requests, make this static

public static List<string> names = new List<string>();
Alberto Monteiro
  • 5,989
  • 2
  • 28
  • 40
  • @Alberto..what should I say mate to you..once again sincere thanks... High-5 – Kgn-web Jan 02 '16 at 17:17
  • @Alerto..only one thing to check with what does it make difference & how `[FromBody]` & `[FromUri]` – Kgn-web Jan 02 '16 at 17:19
  • 1
    @Chetan `FromUri` try to get data from Query String's URL like this `www.youtube.com/?w=videocode`. `FromBody` try to get data from the body of the HTTP Request that you received in server. – Alberto Monteiro Jan 02 '16 at 17:30
  • this is 1 question I asked some weeks back but didn't got the right ans, can you please have a look at it once http://stackoverflow.com/questions/34243111/what-is-the-cause-of-trust-level-issue-in-asp-net-mvc – Kgn-web Jan 04 '16 at 12:38
  • can you please look this, I am in bit of urgency for this requirment.http://stackoverflow.com/questions/34774473/is-there-any-way-to-write-stylesheet-specific-to-thermal-printer – Kgn-web Jan 13 '16 at 19:12
0

Try this in jQuery:

var customerName = $('#txtName').val();

$.ajax(
{
 url:"http://myip:8060/Api/Test",
 method:"POST",
 data:JSON.stringify({'custName':customerName}),
 success:function(data)
 {
  console.log(data);
 }
error:function(e)
{
 console.log(e);
}
})
zaitsman
  • 8,984
  • 6
  • 47
  • 79
0

Try this one:-

    var customerName = $('#txtName').val();

      $.ajax(
     {
      url:"http://myip:8060/Api/Test", 
      method:"POST",
      data: { custName: customerName },
      success:function(data)
      {
       console.log(data);
      }
      error:function(e)
      {
       console.log(e);
      }
    })
yash
  • 812
  • 3
  • 12
  • 37
  • if you mean to say that while passing custName I should remove quote, then I checked with it but doesn't make any difference.. `data: { custName: customerName }` or `data: { 'custName': customerName }` – Kgn-web Jan 02 '16 at 12:05
  • I have provided all the needed action & jQuery ajax call – Kgn-web Jan 02 '16 at 12:18
0

hmm the controller somehow gives an error when trying to do a post request. try this in your controller:

public List<string> Post()//[FromBody]string custName)
    {
        HttpContent requestContent = Request.Content;
        string custName = requestContent.ReadAsStringAsync().Result;

        try
        {

            names.Add(custName);
            return names;
        }
        catch (Exception ex)
        {
            List<string> errors = new List<string> {ex.Message};
            return errors;
        }



    }

the html i use is the following:

    <!DOCTYPE html>

<html>
<head>
    <title></title>
    <meta charset="utf-8"/>
</head>
<body>
First name: <input type="text" id="demo2" onkeyup="showitemresult()" ><br>
    result name: <input type="text" id="demo" ><br>
</body>
</html>
<script>
    function showitemresult() {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function () {
            if (xhttp.readyState == 4 && xhttp.status == 200) {
                document.getElementById("demo").value = xhttp.responseText;
            }
        };
        xhttp.open("POST", "http://localhost:52016/api/values", true);
        xhttp.send(document.getElementById("demo2").value);
    }
</script>

change http://localhost:52016/api/values to your address edit 2: i noted the js is not jquery. But i got this to work.

Roland
  • 71
  • 6
  • checked but instead of returning null it returns as `[" "]`, `[" "," "]` – Kgn-web Jan 02 '16 at 13:12
  • nopes, onkeyUp event I gets an error on the action **Unsupported media type(405)** – Kgn-web Jan 02 '16 at 13:46
  • hmm did you also copy the controller? I got the code working here. your address will look something like http://localhost:xxxxx/api/test – Roland Jan 02 '16 at 15:17