I'm new to Web API, and I'm stuck at getting multiple values for Get(). What I'm trying to do is to pass in many values through the query string. Instead of having a Get(string .., string .., so on), I decided to go MVC style and do something like Get(RequestModel m). This returns a NullRef exception. e.g.:
For my 'web request', I've created a class:
RequestModel
{
public string Req1 {get;set;}
public string Req2 {get;set;}
public string Req3 {get;set;}
}
My Get function in the controller:
public ValuesController : ApiController
{
public Get(RequestModel m)
{
return m.Req1;
}
}
My url is:
http://localhost/api/values?Req1=test
Is this possible? If not, what's the best way to do this? The only thing i can think of as an alternative is ParseQueryString().
You would need to explicitly set [FromUri] attribute like below:
public Get([FromUri] RequestModel m)
Related
I have a webapi controller and following is a post method.
public HttpResponseMessage Register(string email, string password)
{
}
How do I test from the browser?
When I test it from the browser with the following , it is not hitting the controller.
http://localhost:50435/api/SignUp/?email=sini#gmail.com&password=sini#1234
It is giving me the below error.
Can't bind multiple parameters ('id' and 'password') to the request's
content.
Can you please help me???
You get an error, because you cannot pass multiple parameter to WebApi in this way.
First option:
You can create a class and pass data through from body in this way:
public class Foo
{
public string email {get;set;}
public string password {get;set;}
}
public HttpResponseMessage Register([FromBody] Foo foo)
{
//do something
return Ok();
}
Second Option:
public HttpResponseMessage Register([FromBody]dynamic value)
{
string email= value.email.ToString();
string password = value.password.ToString();
}
And pass json data in this way:
{
"email":"abc#test.com",
"password":"123#123"
}
Update:
If you wan to get data from URL, then you can use Attribute Routing.
[Route("api/{controller}/{email}/{password}")]
public HttpResponseMessage Register(string email, string password)
{
//do something
return Ok();
}
Note:
URL should be : http://localhost:50435/api/SignUp/sini#gmail.com/sini#1234
Don't forget to enable attribute routing in WebApiConfig
If you use this way, you will have security issue.
I want to log the each action method parameter name and its
corresponding values in the database as key value pair. As part of
this, I am using OnActionExecuting ActionFilterAttribute, since it
will be the right place (OnActionExecuting method will get invoke for
all controller action methods call) to get Action Executing context.
I am getting the value for .Net types (string, int, bool). But I am
unable to get the value of the User defined types (custom types).
(ex: Login model). My model might have some other nested user
defined types as well.
I was trying to get the values of the user defined types but I am
getting the only class name as string. I hope we can do in
reflection.
Could you please anyone assist to resolve the issue. since I am new
to reflection. It will helpful to me. Thanks in Advance.
I need to get the name and value of these types in OnActionExecuting.
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
ActionParameter = new SerializableDictionary<string,string>();
if(filterContext.ActionParameter != null)
{
foreach(var paramter in filterContext.ActionParameter)
{
//able to get returnUrl value
//unable to get model values
ActionParameter.Add(paramter.Key, paramter.Value);
}
}
}
public ActionResult Login(LoginModel model, string returnUrl)
{
return View(model);
}
User defined type
public class LoginModel
{
public string UserName {get;set;}
public string Password {get;set;}
//User defined type
public UserRequestBase Request {get;set;}
}
//User defined type
public class UserRequestBase
{
public string ApplicationName {get;set;}
}
I am able to get the value of the returnUrl (login method param) in OnActionExecuting but not for model (login method param). I am able to see the values, but don't know how to access it, I used typeof even though I am unable to get it, but I need generic because i have 20 methods in controller so I could not only for LoginModel.
This answer isn't exactly what you want - based on your question - but I think it will work better for what want to accomplish. Quick aside...
Playing around with reflection and nested classes in this instance, lead to some SO (a propos?) errors for me...
So, a better path, maybe? Rather than trying to get/cast the property names, values (types?) from 'context.ActionParameters,` I found it was much easier to let a Json serialization do the work for me. You can then persist the Json object, then deserialize... pretty easy.
Anyway, here's the code:
using Newtonsoft.Json; // <-- or some other serialization entity
//...
public class LogActions : ActionFilterAttribute, IActionFilter
{
// Using the example -- LoginModel, UserRequestBase objects and Login controller...
void IActionFilter.OnActionExecuting(ActionExecutingContext context)
{
var param = (Dictionary<String, Object>)context.ActionParameters;
foreach (var item in param.Values)
{
string itemName = item.GetType().Name.ToString();
string itemToJson = JsonConvert.SerializeObject(item);
// Save JsonObject along with whatever other values you need (route, etc)
}
}
}
Then when you retrieve the Json object from the database you just have to deserialize / cast it.
LoginModel model = (LoginModel)JsonConvert.DeserializeObject(itemToJson, typeof(LoginModel));
From example:
public class LoginModel
{
public string UserName {get;set;}
public string Password {get;set;}
//User defined type
public UserRequestBase Request {get;set;}
}
//User defined type
public class UserRequestBase
{
public string ApplicationName {get;set;}
}
Controller used in example:
public ActionResult Login(LoginModel model, string returnUrl)
{
return View(model);
}
Hope this helps. If there are further issues with this please let me know and I will try to help.
I have a webAPI controller which is like
Public class TestController:APIController
{
[Route(“Api/Test/{testId}/SubTest”)]
Public void Post(int subTestid)
{
}
}
Our requirement is to get the value of testId from the url inside the post method.
Could anyone suggest the best way to achieve this.
Looking at this link: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2
The string "customers/{customerId}/orders" is the URI template for the
route. Web API tries to match the request URI to the template. In this
example, "customers" and "orders" are literal segments, and
"{customerId}" is a variable parameter.
public class OrdersController : ApiController
{
[Route("customers/{customerId}/orders")]
[HttpGet]
public IEnumerable<Order> FindOrdersByCustomer(int customerId) { ... }
}
It seems that you need to change subTestid to testId so it will be a match.
Basically I'm trying to create a method in my webapi controller:
The method looks like this(the method body is relevant):
[HttpPost]
public HttpResponseMessage CpaLead([FromBody]CpaLeadVM model)
{
Here's the class declaration of the object being passed:
public class CpaLeadVM
{
public string UserIp = "";
public string UserCountry = "";
public double Earn = 0.0;
public string SurveyType = "";
}
The thing is; when I send a post request to the method, the model is always null.
The post request has the following data:
UserIp=hello
Earn=44.4
UserCountry=denmark
SurveyType=free
Shouldn't it be able to bind to the model or am I missing something here?
The problem is the "properties" you are trying to bind to are fields and not actual properties. The model binders and formatters in Web Api doesn't look at fields. If you change your model to:
public class CpaLeadVM
{
public CpaLeadVm()
{
UserIp = "";
UserCountry = "";
Earn = 0.0;
SurveyType = "";
}
public string UserIp {get;set;}
public string UserCountry {get;set;}
public double Earn {get;set;}
public string SurveyType {get;set;}
}
Your binding will work. As a side note, the [FromBody] attribute on your action is redundant since non-primitive values are bound from the request body by default.
As you may know, you can only get a single value from the body, which must be sent as "=value". See this article for more info
http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/
I'm not sure, but I think you could create your own model binder, which parses the body into your class. Another approach is to use JSON. Read more about that here
ASP.NET MVC 4 Post FromBody Not Binding From JSON
I have the following Web API (GET):
public class UsersController : ApiController
{
public IEnumerable<Users> Get(string firstName, string LastName, DateTime birthDate)
{
// Code
}
}
It's a GET, so I can call it like this:
http://localhost/api/users?firstName=john&LastName=smith&birthDate=1979/01/01
and receive an xml result of user(s).
Is it possible to encapsulate parameters to one class like this:
public class MyApiParameters
{
public string FirstName {get; set;}
public string LastName {get; set;}
public DateTime BirthDate {get; set;}
}
And then have:
public IEnumerable<Users> Get(MyApiParameters parameters)
I've tried it and anytime I try to get result from http://localhost/api/users?firstName=john&LastName=smith&birthDate=1979/01/01, the parameter is null.
By default complex types are read from body, that's why you are getting null.
Change your action signature to
public IEnumerable<Users> Get([FromUri]MyApiParameters parameters)
if you want the model binder to pull the model from the querystring.
You can read more about how Web API does parameter binding in the excellent article by Mike Stall from MSFT - http://blogs.msdn.com/b/jmstall/archive/2012/04/16/how-webapi-does-parameter-binding.aspx