By Hanady


2016-06-06 21:15:15 8 Comments

I created a .Net web service:

public class UsersController : ApiController
{
    [System.Web.Http.HttpPost]
    public void Post(string value)
    {
        SqlConnection connection = new SqlConnection("Data Source=198.71.226.6;Integrated Security=False;User ID=AtallahMaroniteDB;[email protected]$$123;Database=AtallahPlesk_;Connect Timeout=15;Encrypt=False;Packet Size=4096");


        String query = "INSERT INTO Members(LastName, FirstName, Gender, MobileNumber, EmailAddress, Job, Address) VALUES " +
            "(@LastName, @FirstName, @Gender, @MobileNumber, @EmailAddress, @Job, @Address)";
        SqlCommand command = new SqlCommand(query, connection);
        try
        {
            JavaScriptSerializer json_serializer = new JavaScriptSerializer();
            PersonModel person = json_serializer.Deserialize<PersonModel>(value);

            command.Parameters.Add("@LastName", person.LastName);
            command.Parameters.Add("@FirstName", person.FirstName);
            command.Parameters.Add("@Gender", person.Gender);
            command.Parameters.Add("@MobileNumber", person.MobileNumber);
            command.Parameters.Add("@EmailAddress", person.EmailAddress);
            command.Parameters.Add("@Job", person.Job);
            command.Parameters.Add("@Address", person.Address);

            connection.Open();
            command.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.InnerException.ToString());
        }
    }
}

And the following is my routing config:

RouteTable.Routes.MapHttpRoute(
     name: "MyApi",
     routeTemplate: "api/{controller}/{action}/{value}"
 );

When I am calling this web service from an Android or iOS application, I am getting the following error:

No HTTP resource was found that matches the request URI 'http://www.mytestdomain.com/api/users/post'

Below is the android code:

JSONObject dato = POST(person); // This method converts the Person object to JSONObject

String text = null;
try {
    HttpPost post = new HttpPost("http://www.mytestdomain.com/api/users/post");
    StringEntity entity = new StringEntity(dato.toString());
    entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
    post.setEntity(entity);
    HttpResponse response = httpClient.execute(post);
    HttpEntity entityResponse = response.getEntity();
    text = getASCIIContentFromEntity(entityResponse);                   
} catch ( IOException ioe ) {
    ioe.printStackTrace();
}

Please note that when I call this web service from postman, it's posting the data successfully.

Please let me know if you need any further details.

1 comments

@Nkosi 2016-06-07 11:22:12

You need to update your route template to make sure that you get a valid match for your request.

Here is what a valid template would look like for your API. Note this is specific to the UsersController as the defaults: has been set to controller = "Users" which will map to the UsersController

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Attribute routing.
        config.MapHttpAttributeRoutes();

        // Convention-based routing.

        config.Routes.MapHttpRoute(
            name: "MyApi",
            routeTemplate: "api/users/{action}",
            defaults: new { controller = "Users" }
        );

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

From your code example you are sending the model as json and then trying to manually parse it on the server. You can let the framework parse the model with its model binders based on the Content-Type of the request. This will allow you to update your action to accept the actual object model instead of a string.

public class UsersController : ApiController {

    //eg: POST api/users/post
    [HttpPost]
    public IHttpActionResult Post(PersonModel person) {
        if (person == null) return BadRequest();
        try
        {        
            SqlConnection connection = new SqlConnection("Data Source=198.71.226.6;Integrated Security=False;User ID=AtallahMaroniteDB;[email protected]$$123;Database=AtallahPlesk_;Connect Timeout=15;Encrypt=False;Packet Size=4096");

            String query = "INSERT INTO Members(LastName, FirstName, Gender, MobileNumber, EmailAddress, Job, Address) VALUES " +
            "(@LastName, @FirstName, @Gender, @MobileNumber, @EmailAddress, @Job, @Address)";
            SqlCommand command = new SqlCommand(query, connection);
            command.Parameters.Add("@LastName", person.LastName);
            command.Parameters.Add("@FirstName", person.FirstName);
            command.Parameters.Add("@Gender", person.Gender);
            command.Parameters.Add("@MobileNumber", person.MobileNumber);
            command.Parameters.Add("@EmailAddress", person.EmailAddress);
            command.Parameters.Add("@Job", person.Job);
            command.Parameters.Add("@Address", person.Address);

            connection.Open();
            command.ExecuteNonQuery();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.InnerException.ToString());
            return InternalServerError();
        }
        return Ok();
    }
}

You also need to make sure the request sent is correct so you can get a match

Here is a raw example request snippet

POST  /api/users/post HTTP/1.1
Host: http://www.mytestdomain.com
Content-Type: application/json
... 
Content-Length: 163

{"LastName":"Doe","FirstName":"Jane","Gender":"Female","MobileNumber":"+1234567890","EmailAddress":"[email protected]","Job":"Developer","Address":"My address"}

Try inspecting the requests sent from the mobile to make sure its being sent correctly. Something like Fiddler.

@Hanady 2016-06-07 12:58:26

When I call http://www.mytestdomain.com/api/users/post/someValue, I am getting the following error: {"Message":"The requested resource does not support http method 'GET'."}. Also I added the Optional attribute but it didn't work. The value is sent in an HttPPost request from the mobile app. What should I modify in order to allow this?

@Nkosi 2016-06-07 13:01:19

The message explains itself. You tagged the action with HttpPost which means it will only accept POST requests. If you try a GET then it will fail by design. Show how you send the post from the mobile.

@Hanady 2016-06-07 13:05:02

I just added the android code. Please note that from Postman the request is being successfully executed. Only from Android and iOS it is failing

@Nkosi 2016-06-07 13:09:18

Ok your last update helps explain a lot. I'll review and update my answer. At first glance the value is sent in the body of the request and not the URI

@Hanady 2016-06-07 13:11:31

Right, but when I add the [FromBody] annotation, the value arrives null to the web service. Please take this into consideration.

Related Questions

Sponsored Content

10 Answered Questions

[SOLVED] How to make HTTP POST web request

18 Answered Questions

1 Answered Questions

3 Answered Questions

[SOLVED] No HTTP resource was found that matches the request URI

11 Answered Questions

[SOLVED] Make an HTTP request with android

1 Answered Questions

No HTTP resource was found that matches the request URI in webapi

0 Answered Questions

OData no http resource was found that matches the request uri

1 Answered Questions

[SOLVED] No HTTP resource was found that matches the request URI

Sponsored Content