I couldn't call web api with params from android. I can do without params so problem probably how I send params or how I get them.
Following code gives this error :
No action was found on the controller 'Foo' that matches the request.
Android
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("token", session.getAccessToken()));
json = restClientService.getResponseAsJSON("http://192.168.2.242/WebApi/api/fbfeed/foo/", params);
--
private HttpResponse getWebServiceResponse(String URL,
ArrayList<NameValuePair> params) {
HttpResponse httpResponse = null;
try {
HttpParams httpParameters = new BasicHttpParams();
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpPost httpPost = new HttpPost(URL);
try {
httpPost.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
}
httpResponse = httpClient.execute(httpPost);
Config
config.Routes.MapHttpRoute(name: "UserCreateApi", routeTemplate: "api/{controller}/{action}", defaults: new { action = "Foo" });
Controller
[AcceptVerbs("GET", "POST")]
public IHttpActionResult Foo([FromBody]string token)
{
//some code
}
Is your controller inheriting from ApiController? Can you hit the url from a browser on your local machine?
Related
I'm trying to create a API broker program so that a frontend can call a api with any endpoint given, in the broker I decide which URL to be executed. I have the following problem:
In my front-end I am calling my API broker with the following url:
http://localhost:54857/getClients
When my API Broker receives this request it instantly returns a error, before this error occurs I want to redirect this to a controller action which does not match the name getClients.
Front-end code which requests the call to my API Broker:
[HttpGet]
public async Task<ActionResult> getCall()
{
string url = "http://localhost:54857/";
string operation = "getClients";
using (var client = new HttpClient())
{
//get logged in userID
HttpContext context = System.Web.HttpContext.Current;
string sessionID = context.Session["userID"].ToString();
//Create request and add headers
client.BaseAddress = new Uri(url);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
//Custom header
client.DefaultRequestHeaders.Add("loggedInUser", sessionID);
//Response
HttpResponseMessage response = await client.GetAsync(operation);
if (response.IsSuccessStatusCode)
{
string jsondata = await response.Content.ReadAsStringAsync();
return Content(jsondata, "application/json");
}
return Json(1, JsonRequestBehavior.AllowGet);
}
}
My routing in my API Broker:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller=Redirect}/{action=RedirectApi}/{id}");
}
API Broker controller:
[System.Web.Http.AcceptVerbs("GET")]
[System.Web.Http.HttpGet]
public Customer RedirectApi()
{
Customer t = dbProducts.Customers
.Where(h => h.customerID == 1)
.FirstOrDefault();
return t;
}
I also have a filter that works when the api method getClients is present:
public override void OnActionExecuting(HttpActionContext actionContext)
{
//Checks if header is method Get and has attribute
if ((actionContext.Request.Method.Method == "GET") && (actionContext.Request.Headers.GetValues("loggedinUser").First() != null))
{
}
base.OnActionExecuting(actionContext);
}
In the current situation(code above) I'm receiving a error and the code in my API broker is not even getting executed. What I'm trying to achieve is that I redirect any given request received in my API Broker to my API Broker Controller which executed the method RedirectApi().
Hope somebody can help!
Thanks in advance!
You could add this code after the other mapping code:
routes.MapRoute(
"404-PageNotFound",
"{*url}",
new { controller = "Redirect", action = "RedirectApi" }
);
When using convention based routing I am able to use a DelegatingHandler to create a response wrapper by overriding the SendAsync method.
DelegatingHandler[] handler = new DelegatingHandler[] {
new ResponseWrapper()
};
var routeHandler = HttpClientFactory.CreatePipeline(new HttpControllerDispatcher(config), handler);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}",
defaults: null,
constraints: null,
handler: routeHandler
);
However, this approach does not work for methods that rely upon attribute routing. In my case convention based routing will not work for all scenarios and the routeHandler does not apply to the attribute based routes.
How can I apply a response wrapper to all attribute based route responses?
I was able to add a global message handler that applies to all requests.
config.MessageHandlers.Add(new ResponseWrapper());
Since I am using swagger, I also had to ignore the swagger request URI. Here is the code for the ResponseWrapper class in the event it helps someone. I have not had a chance to go back through it so there are certain to be some improvements...
public class ResponseWrapper : DelegatingHandler
{
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var response = await base.SendAsync(request, cancellationToken);
if (request.RequestUri.ToString().Contains("swagger"))
{
return response;
}
return BuildApiResponse(request, response);
}
private static HttpResponseMessage BuildApiResponse(HttpRequestMessage request, HttpResponseMessage response)
{
object content = null;
string errorMessage = null;
response.TryGetContentValue(out content);
if (!response.IsSuccessStatusCode)
{
content = null;
var error = new HttpError(response.Content.ReadAsStringAsync().Result);
var data = (JObject)JsonConvert.DeserializeObject(error.Message);
errorMessage = data["message"].Value<string>();
if (!string.IsNullOrEmpty(error.ExceptionMessage) && string.IsNullOrEmpty(errorMessage))
{
errorMessage = error.ExceptionMessage;
}
}
var newResponse = request.CreateResponse(response.StatusCode, new ApiResponse(response.StatusCode, content, errorMessage));
foreach (var header in response.Headers)
{
newResponse.Headers.Add(header.Key, header.Value);
}
return newResponse;
}
}
We are currently having a view in the Oracle DB. We need to create a Web API that accepts the input parameters and queries the view in the Oracle DB and returns the response in the JSON format. I am new to ASP.NET and the web services. Below is the code for the service
namespace TGSSample.Controllers
{
public class TGSSampDataController : ApiController
{
public HttpResponseMessage Getdetails([FromUri] string id)
{
List<OracleParameter> prms = new List<OracleParameter>();
List<string> selectionStrings = new List<string>();
string connStr = ConfigurationManager.ConnectionStrings["TGSDataConnection"].ConnectionString;
using (OracleConnection dbconn = new OracleConnection(connStr))
{
DataSet userDataset = new DataSet();
var strQuery = "SELECT * from LIMS_SAMPLE_RESULTS_VW where JRS_NO =" + id;
var returnObject = new { data = new OracleDataTableJsonResponses(connStr, strQuery, prms.ToArray()) };
var response = Request.CreateResponse(HttpStatusCode.OK, returnObject, MediaTypeHeaderValue.Parse("application/json"));
ContentDispositionHeaderValue contentDisposition = null;
if (ContentDispositionHeaderValue.TryParse("inline; filename=ProvantisStudyData.json", out contentDisposition))
{
response.Content.Headers.ContentDisposition = contentDisposition;
}
return response;
}
}
I am trying to debug and in the URL I gave like http://localhost:6897/api/TGSSampData?id=379 but it throws error like enter image description here
I havent changed anything with the RouteConfig.cs or WebApiConfig.cs.
namespace TGSSample
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
); }}}
I am not sure why I am getting the error. I have changed anything or not renamed.Can anyone please help me with this
Parameter Binding in ASP.NET Web API
Using [FromUri]
To force Web API to read a complex type from the URI, add the
[FromUri] attribute to the parameter.
Remove the [FromUri] attribute and you can use the [HttpGet] attribute as well.
public class TGSSampDataController : ApiController {
//according to convention-based route mapping in webapiconfig
//api/{controller}/{id} should map the following to this action
//GET api/TGSSampData?id=379
//GET api/TGSSampData/379
[HttpGet]
public HttpResponseMessage Get(string id) { ... }
}
I have an angular/MVC app combo. A user goes in can modify a record clicks a a button calls a service that does a post to update a record in the DB. It hits the controller (I have breakpoint on the constructor) but, not the method and throws back a 405.
Button Click handler:
$scope.submit = function() {
console.log($scope.request);
requests.updateRequest($scope.request).then(onUpdate, onError);
}
Request resource:
var updateRequest = function (request) {
return $http.post("/api/request/update/", request).then(function (response) {
return response.data;
});
};
The routes are configured in a separate file:
config.Routes.MapHttpRoute("UpdateRequest", "api/request/update/", new { controller = "Requests", action = "UpdateRequest"});
The RequestController constructor gets hit but, I am unable to work out why the following endpoint is not hit.
Controller method:
[HttpPost]
public HttpResponseMessage UpdateRequest([FromBody] IRequest request)
{
try
{
var response = new HttpResponseMessage
{
StatusCode = HttpStatusCode.OK,
Content =
new ObjectContent(
typeof(int),
request.Id,
new JsonMediaTypeFormatter())
};
return response;
}
catch (Exception ex)
{
throw new HttpResponseException(HttpStatusCode.InternalServerError);
}
}
Any ideas?
Default parameter binding doesn't work with interfaces. Try changing:
[FromBody] IRequest request
to a concrete type e.g.
Request request
If you do want to use an interface in your webapi check out this blog post
I have the following code, but the request ends (Foo() / Bar()) always in No action was found on the controller 'Device' that matches the request.
I've a custom route in my WebApiConfig:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new {id = RouteParameter.Optional}
);
My ASP.NET WebAPI controller:
[HttpPost]
public void UpdateToken(string newToken)
{
_deviceHandler.UpdateToken(newToken);
}
To query my ASP.NET WebAPI I'm using RestSharp.
private static void Send(string resource, Method method, object payload)
{
var client = new RestClient(baseUrl);
var request = new RestRequest(resource, method);
request.XmlSerializer = new JsonSerializer();
request.RequestFormat = DataFormat.Json;
request.AddBody(payload);
var response = client.Execute(request);
// ... handling response (exceptions, errors, ...)
}
public void Foo()
{
var newToken = "1234567890";
Send("/api/device/updatetoken", RestSharp.Method.POST, newToken );
}
public void Bar()
{
var newToken = new { newToken = "1234567890" };
Send("/api/device/updatetoken", RestSharp.Method.POST, newToken );
}
The only way to avoid this error is creating a wrapper class with a property (get;set;) in it which has the name of the controller argument (newToken).
I have a lot of requests which sends one or two custom strings (undefined length) as post (get is limited in length). But to create for each scenario a wrapper implementation is real overhead! I'm looking for another way to go.
PS: I hope I haven't made any mistakes by simplifying the scenario =)
Primitives are by default bound from the URI. If you want a primitive to come from the body, you should use the [FromBody] attribute like this:
[HttpPost]
public void UpdateToken([FromBody] string newToken)
{
_deviceHandler.UpdateToken(newToken);
}
The string will then be deserialized using the appropriate formatter. If it's JSON, the request body should look like this:
"1234567890"