My webapi method couldn't accept string parameter.
In post method in webapi controller , i could get only an optional string parameter, but when i test my method without parameter it get following error:
The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.String Get(Int32)' .
[HttpPost]
public IHttpActionResult List(string munZone="")
{
}
in route config:
routes.MapRoute(
name: "DefaultApi3",
url: "api/{controller}/{action}"
);
routes.MapRoute(
name: "DefaultApi2",
url: "api/{controller}/{action}/{id}",
defaults: new { id = UrlParameter.Optional }
);
I need to send nullable string parameter instead of int id parameter
I found it,if i send param as object of class, this problem will resolve.
public class T{
public string munZone
}
[HttpPost]
public IHttpActionResult List(T t)
{
}
Related
Here is what I have now: One route and all controllers so far confirm to it and work great. We want to keep those as is.
GlobalConfiguration.Configuration.Routes.MapHttpRoute(
name: "DitatApi",
routeTemplate: "api/{controller}/{action}"
Now we created new controller but need to route it differently. Below is a controller code and how those methods should be routed. How can I setup such route?
public class CarrierController : ApiController
{
[HttpGet]
public object Get(string id, int? key, string direction)
{
return null;
}
[HttpPost]
public object Update()
{
return null;
}
[HttpDelete]
public object Delete(int key)
{
return null;
}
[HttpGet]
public object GenerateRandomObject(int randomParam)
{
return null;
}
}
GET /api/carrier?id=<id>&key=<key>&direction=<direction>
POST /api/carrier
DELETE /api/carrier?key=<key>
GET /api/carrier/random?randomParam=<random>
WebApi v2 introduced the Route Attributes and those can be used along with your Controller class and can facilitate the routing configuration.
For example:
public class BookController : ApiController{
//where author is a letter(a-Z) with a minimum of 5 character and 10 max.
[Route("html/{id}/{newAuthor:alpha:length(5,10)}")]
public Book Get(int id, string newAuthor){
return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
}
[Route("json/{id}/{newAuthor:alpha:length(5,10)}/{title}")]
public Book Get(int id, string newAuthor, string title){
return new Book() { Title = "SQL Server 2012 id= " + id, Author = "Adrian & " + newAuthor };
}
...
However, please note that query parameters ?var1=1&var2=2 are not subject to evaluation to decide which API method will be used.
WebApi works based on reflection, so, this means that your curly braces {vars} must match the same name in your methods.
Therefore to match something like this api/Products/Product/test your template should look like this "api/{controller}/{action}/{id}" and your method needs to be declare like this:
[ActionName("Product")]
[HttpGet]
public object Product(string id){
return id;
}
Where the parameter string name was replaced by string id.
I'm trying to add attribute routing to a ApiController like so:
public class PhoneNumbersController : ApiController
{
// GET BY ID
public PhoneNumber GetById(int id)
{
return PhoneNumbersSelect(id)[0];
}
// GET BY ID TypeOFPhoneNumbers/Id
[Route("api/typeOfPhoneNumbers/{id}")]
public TypeOfPhoneNumber GetTypeOfPhoneNumberById(int id)
{
return TypeOfPhoneNumbersSelect(id)[0];
}
}
My config looks like this:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
I'm getting a 500 Error when trying to call api/phoneNumbers/1. If I comment out the GetTypeOfPhoneNumbersId() function the default controller GetById() works fine. What am I doing wrong? Am I not allowed to declare a unique route in the ApiController because of the way the config is set up?
Also, as I just found out, calling the api/typeOfPhoneNumbers/1 returns a 404 error, so that routing doesn't work at all.
Thanks for any help!
I believe you miss the controller name (phoneNumbers) in your route, this is a working code (I've tested it)
public class PhoneNumbersController : ApiController
{
// GET BY ID
[HttpGet]
public PhoneNumber GetById(int id)
{
return PhoneNumbersSelect(id)[0];
}
// GET BY ID TypeOFPhoneNumbers/Id
[HttpGet]
[Route("api/phoneNumbers/typeOfPhoneNumbers/{id:int}")]
public TypeOfPhoneNumber GetTypeOfPhoneNumberById(int id)
{
return TypeOfPhoneNumbersSelect(id)[0];
}
}
Could you try to access TypeOFPhoneNumbers's resource like that : ~api/typeOfPhoneNumbers?id=1
I am calling a Web API Post Action passing a JSON parameter.
My custom model is as follows:
[Serializable]
public class Model
{
public int? prop1 {get; set;}
public bool prop2 {get; set;}
}
Web API is:
public void Post(Model model)
{
if (model != null && model.prop1 ==5 )
{
// Do something
}
}
The JSON i pass from client is:
var value = {
prop1: 4,
prop2: true
};
And the AJAX call from client is:
.ajax('/api/MyController', {
type: "POST",
contentType: "application/json",
data: JSON.stringify(value),
success:function(data){
alert(Success);
}
});
However, the binding of the model properties never works in the WebAPI action. The "model" param comes back instantiated (it is not null), however all the properties inside are default values and not the values I pass from client. If I remove the [Serializable] attribute from the Model class, it works fine. I cannot remove this attribute since this object gets stored in SQL based session. What are the ways I can get this binding to work without removing the [Serializable] attribute
Remove [Serializable] from your Model and it should do it. Not sure why, but it's not working when the class is marked as Serializable.
In my WebApiConfig.cs file I have the following route defined: (it's the only route defined here)
config.Routes.MapHttpRoute(
name: "DefaultApi2",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new {id = RouteParameter.Optional}
);
The POST I'm making is to:
http://localhost:17138/api/Account/Login
My controller is this:
namespace WebAPI.Api
{
public class AccountController : ApiController
{
[HttpPost]
public HttpResponseMessage Login(string username,string password)
{...
The error I'm getting is:
{"Message":"NoHTTPresourcewasfoundthatmatchestherequestURI'http://localhost:17138/api/Account/Login'.","MessageDetail":"Noactionwasfoundonthecontroller'Account'thatmatchestherequest."}
and from Phil's program it looks like the route should work. Any thoughts?
I changed my parameters for my Login method to
public HttpResponseMessage Login(FormDataCollection formDataCollection)
and it worked. It seems I'm missing something about how POST parameters are handled because in the formDataCollection, both username and password are there. I'm not sure what that is not the same as
public HttpResponseMessage Login(string username,string password)
Consider a model class
public class MyModel
{
public string Id { get; set; }
/* some other properties */
}
And a controller
public class MyController
{
[HttpPut]
public ActionResult Update(string id, MyModel model)
{
/* process */
}
}
The routing is registered as follows:
protected override void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("MyController",
"api/my/{id}",
new { action = "Update", controller = "My"},
new { httpMethod = new HttpMethodConstraint(new[] { "PUT" }) });
}
When using a REST client and sending MyModel serialized as a JSON or XML request to this controller, a null "Id" property of "MyModel", overrides the "id" parameter of the action method, even if you post it to http://api.example.com/api/my/10.
How does one force ASP.NET MVC 3 to populate the "id" property from the URL (in this case "10") and ignore the "Id" property of the "MyModel"?
Note that I'm not using ASP.NET Web API.
Try using attribute [FromUri]. It's in "System.Web.Http". This attribute on action param id indicates it should be bonded using the url request.
using System.Web.Http;//at the top
public class MyController
{
[HttpPut]
public ActionResult Update([FromUri]string id, MyModel model)
{
/* process */
}
}
For MVC3 try to include web-api package(from nuget or manually) to use [FromUri] attribute. IF that is not possible then the only way I can think of getting it is from this.HttpContext.Request.QueryString["id"]
Instead of having id as a action method paramter declare it in action body. May have to change the url query api/my?id=1212. First try using api/my/{id} format.
var id = this.HttpContext.Request.QueryString["id"];