I'm going to switch from my WCF Rest/Json Service to WebApi2 and I'm looking for a way to map this method:
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Json, UriTemplate = "Users?mail={mail}&pw={pw}")]
UserData getUserByEmailAndPw(String mail);
I want to query a user by email and password so I can't use the default GET which is intended to use an ID. As far as I know you should do this via attributes in Rest...
Do I just have to register a route for this or is there a better way (maybe by convention) ?
[FromQuery] - Gets values from the query string. [FromRoute] - Gets values from route data. [FromForm] - Gets values from posted form fields. [FromBody] - Gets values from the request body.
Using [FromUri] To force Web API to read a complex type from the URI, add the [FromUri] attribute to the parameter. The following example defines a GeoPoint type, along with a controller method that gets the GeoPoint from the URI.
You always have to register a route in WebApi for your controller actions, this can be done with attribute routing or with conventions based routing.
Parameters passed in the query string for GET request don't really have to be specified explicitly in either of the routing configuration methods.
The parameters you specify on your controller action get mapped to parameters sent in the query string of a GET request.
If you are using the default WebApi conventions based setup where the routes are configured something like this:
var config = new HttpConfiguration();
// some other config setup for web api
...
...
// route config
config.Routes.MapHttpRoute(
name: "API Default",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Then a controller like this will work for you:
public class UsersController : ApiController {
// this maps to a get requests to:
// domain/api/users
// and domain/api/users?id=someid
// and domain/api/users?mail=somemail
// and domain/api/users?pw=somepw
// and domain/api/users?mail=somemail&pw=somepw
// and domain/api/users with any query string really
[HttpGet]
public IHttpActionResult Get(string mail, string pw) {
// should probably check mail and pw for empty strings and nulls
var users = SomeStaticExampleService.FindByMailAndPw(mail, pw);
return this.Json(users);
}
}
Alternatively you can use attribute routing and then call your controllers and action methods whatever you want. Configure your routes like this:
var config = new HttpConfiguration();
// some other config setup for web api
...
...
// route config
config.MapHttpAttributeRoutes();
Then you can create a controller like this:
public class FooController : ApiController {
// this maps to a get requests to:
// domain/users
// and domain/users?id=someid
// and domain/users?mail=somemail
// and domain/users?pw=somepw
// and domain/users with any query string really
[HttpGet]
[Route("users")]
public IHttpActionResult Bar(string mail, string pw) {
// should probably check mail and pw for empty strings and nulls
var users = SomeStaticExampleService.FindByMailAndPw(mail, pw);
return this.Json(users);
}
}
Bear in mind though that with Attribute Routing you have to be careful not to create clashing routes otherwise WebApi won't know which controller and action to route a request to when a route is mapped to multiple action methods.
I've used this.Json
in these examples to return a http response with json content to match your wcf ResponseFormat = WebMessageFormat.Json
. But you can of course just return a CLR type:
[HttpGet]
[Route("users")]
public IEnumerable<MyUser> Bar(string mail, string pw) {
// should probably check mail and pw for empty strings and nulls
var users = SomeStaticExampleService.FindByMailAndPw(mail, pw);
return users;
}
and let WebApi's content negotiation handle the response message content type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With