How to get single list item from response message in web api - c#

I am new to web api. I have a method, that returns 3 objects from response message. I want to get specific object from the response message,
public HttpResponseMessage GetAllStudents(HttpReqestMessage request)
{
HttpResponseMessage response = null;
return CreateHttpResponse(request, () =>
{
// some logics here
response = request.CreateResponse(HttpStatusCode = OK, new {success = true, StudentName, ListOfStudents, ListOfSubjects});
return response;
});
}
In this above code i want to get the ListOfStudents object alone from the response message. Please anyone help me to get this.

I think you have a malformatted json , you should create a property for each list, check the next example :
public HttpResponseMessage GetAllStudents(HttpReqestMessage request)
{
HttpResponseMessage response = null;
return CreateHttpResponse(request, () =>
{
// some logics here
response = request.CreateResponse(HttpStatusCode = OK, new {success = true, studentName = StudentName, listOfStudents = ListOfStudents, listOfSubjects = ListOfSubjects});
return response;
});
}
Example getting this with with jquery
$.get("GetAllStudents", function(data) {
if (data.success)
{
console.log(data.listOfStudents);
}
});

Related

CefSharp how to know when ajax is completed and get result?

Iam using CefSharp winform i try login to site ..
but this site using ajax which mean the site page not reload to get source
so how i can know if AJAX is completed ?
i need something like that's or any other Solution
var cvbar = chrom.EvaluateScriptAsync("Is AJAX completed ??")
var response = cvbar.Result;
if (response.Success == true && response.Result.ToString() != "")
{
// MessageBox.Show(response.Result.ToString());
}
var response1 = cvbar1.Result;
string HTML = await chrom.GetSourceAsync();
generate js script
async function eventClick() {
let target = (document.evaluate(".//html", document, null,
XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue);
let config = { attributes: true, childList: true, subtree: true, characterData: true + };
let observer;
function isItDone() {
return new Promise(resolve => {
// wait ajax response
setTimeout(() => { resolve(false); }, 30000);
// catch ajax response
observer = new MutationObserver(() => {
if (!compareObjects(oldElements, mutateElements)
resolve(true);
}
});
observer.observe(target, config);
});
}
// ajax request
document.evaluate(".//button", document.body, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.click();
let change = await isItDone();
console.log(change);
observer.disconnect();
observer = null; target = null; config = null;
return change;
}
exequte in cefsarp
JavascriptResponse responseClick = await browser.EvaluateScriptAsPromiseAsync("return eventClick();");

Returning success message from JSON post

I have the following to post JSON to a C# Web API:
submitForm(data: any): Observable<Response> {
return this.http.post(
'https://localhost:44396/api/PostNewComputer/AddItem/?=', data,
{ headers: new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' }) }).subscribe(data => { return "test"; });
}
And the API controller:
public class PostNewComputerController : ApiController
{
[HttpPost]
public IHttpActionResult AddItem(HttpRequestMessage request)
{
//var dynamicObject = Json.Decode(jsonString);
var jsonString = request.GetQueryNameValuePairs();
string message;
using (SqlConnection con = new SqlConnection("data source = MYSERVER; initial catalog = AssetDB; integrated security = SSPI; persist security info = True; Trusted_Connection = Yes"))
{
using (SqlCommand cmd = new SqlCommand("POST_NEW_COMPUTER", con) { CommandType = CommandType.StoredProcedure })
{
try
{
cmd.Parameters.Add(new SqlParameter("#JSON_TEXT", SqlDbType.NVarChar)).Value = jsonString;
con.Open();
cmd.ExecuteNonQuery();
con.Close();
message = "Item Successfully Added";
}
catch (Exception e)
{
//throw e;
message = e.Message;
}
}
return Ok(message);
}
}
}
I am trying to create a response message from the POST call that is then fed back to the webpage when the user submits the form to show that the post has worked.
However, this current setup doesn't work and I am struggling to solves this.
Is there a correct way to do this properly?
Use HttpResponseMessage to post back message as:
[HttpPost]
[ResponseType(typeof(string))]
public HttpResponseMessage AddItem(HttpRequestMessage request)
{
HttpResponseMessage response = null;
string message = string.Empty;
try
{
.....
message = "Item Successfully Added";
}
catch (Exception e)
{
.....
message = e.Message;
}
response = Request.CreateResponse<string>(HttpStatusCode.OK, message);
return response;
}
The problem is in your Angular service. Your API is correct
You're trying to subscribe to the response from your API before mapping it back to json(), you need to do the following, see below:
Firstly this is what should be in your component:
submitForm(data: any): Observable<Response> {
//this url can't be correct?
let url:string = 'https://localhost:44396/api/PostNewComputer/AddItem/?=';
return this.http.post(url, data, this._headers())
.map((res:Response) => res.json());
}
//Created a method to do the headers for you
private _headers():RequestOptionsArgs {
let headers:Headers = new headers();
headers.append('Content-Type', 'application/json');
let options:RequestOptionsArgs = new RequestOptions();
options.headers = headers;
return options;
}
You would then call your service from your component as follows:
public functionName():void {
this.service.submitForm(data)
.subscribe((res:any) => {
//this will contain your response
},
(error:any) => {
//this will contain your error
});
}
You need to ensure the model you're posting matches the model expected. With regards to the URL you are posting to, that seems incorrect, is it not https://localhost:44396/api/PostNewComputer/AddItem/?

Ajax calls are slower to controller in physically different file

While trying to speed up some ajax calls in one of our MVC pages, I encountered some strange behavior which I can't really explain. I have some ajax calls being made every N seconds for polling some statistics.
It seems like ajax calls being made to a controller in a physically different file are substantially slower than similar calls being made to a controller in the same physical file as where the view originates from.
See my simplified examples:
Situation 1: Only 1 file
FooController.cs
namespace FooBar.Areas.FooArea.Controllers
{
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class FooTestController: _BaseController
{
public JsonResult GetStats()
{
try
{
var req = new RestRequest() { Method = Method.GET };
req.AddHeader("Content-Type", "application/json");
req.AddHeader("Accept", "application/json");
req.AddParameter("apikey", /*APIKEY*/);
var client = new RestClient(/*STATSURL*/);
var response = client.Execute(req);
if (response.StatusCode == HttpStatusCode.OK)
return Json(new { success = true, content = response.Content });
else
return Json(new { success = false });
}
catch
{
return Json(new { success = false });
}
}
public JsonResult GetAgents()
{
var req = new RestRequest() { Method = Method.GET };
req.AddHeader("Content-Type", "application/json");
req.AddHeader("Accept", "application/json");
req.AddParameter("apikey", /*APIKEY*/);
try
{
var client = new RestClient(/*AGENTSURL*/);
var response = client.Execute(req);
if (response.StatusCode == HttpStatusCode.OK)
return Json(new { success = true, content = response.Content });
else
return Json(new { success = false });
}
catch
{
return Json(new { success = false });
}
}
}
public class FooController : _BaseController
{
// VIEW OF THE PAGE MAKING THE AJAX REQUESTS
public ActionResult Index()
{
Title = "Home";
return View();
}
}
}
Situation 2: 2 seperate files in same folder
FooController.cs
namespace FooBar.Areas.FooArea.Controllers
{
public class FooController: _BaseController
{
// VIEW OF THE PAGE MAKING THE AJAX REQUESTS
public ActionResult Index()
{
Title = "Home";
return View();
}
}
}
FooAjaxController.cs
namespace FooBar.Areas.FooArea.Controllers
{
[SessionState(System.Web.SessionState.SessionStateBehavior.ReadOnly)]
public class FooAjaxController: _BaseController
{
public JsonResult GetStats()
{
try
{
var req = new RestRequest() { Method = Method.GET };
req.AddHeader("Content-Type", "application/json");
req.AddHeader("Accept", "application/json");
req.AddParameter("apikey", /*APIKEY*/);
var client = new RestClient(/*STATSURL*/);
var response = client.Execute(req);
if (response.StatusCode == HttpStatusCode.OK)
return Json(new { success = true, content = response.Content });
else
return Json(new { success = false });
}
catch
{
return Json(new { success = false });
}
}
public JsonResult GetAgents()
{
var req = new RestRequest() { Method = Method.GET };
req.AddHeader("Content-Type", "application/json");
req.AddHeader("Accept", "application/json");
req.AddParameter("apikey", /*APIKEY*/);
try
{
var client = new RestClient(/*AGENTSURL*/);
var response = client.Execute(req);
if (response.StatusCode == HttpStatusCode.OK)
return Json(new { success = true, content = response.Content });
else
return Json(new { success = false });
}
catch
{
return Json(new { success = false });
}
}
}
}
In both situations, the ajax calls are made from jQuery as follows:
jQuery
$.ajax({
url: // URL TO ACTION DEPENDING ON SITUATION,
type: "POST",
dataType: "json",
cache: false,
success: function (result)
{
if (result.success)
{
var content = JSON.parse(result.content);
console.log(content);
}
}
});
Now, the response times from the ajax requests for both situations are as follows, with situation 1 being displayed on the left and situation 2 on the right:
So, as you can see the average time of a call made to GetStats() and GetAgents() in situation 1 is 52.8 ms and 53.8 ms respectively.
However, in situation 2, the average time of the calls is 486.8 ms and 529.9 ms.
My question now is: how can it be that ajax calls made to actions are on average almost 10 times slower when those actions reside in a controller in a physically different file, than when those actions reside in a controller which shares the same physical file as the file rendering the view in the first place?
Is it because the file containing the action to render the view is already loaded and kept in memory, while the seperate file, as in in situation 2, is opened and closed every time the action is called? Or is something more sinister going on?
You shared most of the code but not _BaseController.cs
On each request, MVC gets the controller using dependency injection.
[speculation] MVC may store the most recently-used controller, returning the same one several times. However if you are switching controllers, perhaps it creates a new one each time.
Perhaps there is some very slow code in the _BaseController default constructor - perhaps database queries. It sounds unlikely but has happened in my experience.
Taken together, these things would cause the slowdown you describe.

How to return a object in HttpResponseMessage in Web api mvc?

In one of my Get request, I want to return an HttpResponseMessage with some content. Currently I have it working as follows:
// GET api/Account/5
[HttpGet]
[ActionName("GetAccount")]
public HttpResponseMessage GetAccount(int id)
{
Account value;
try
{
var myque = from x in db.Accounts where x.idUser==id select x;
value= myque.FirstOrDefault();
}
catch (Exception)
{
return new HttpResponseMessage { Content = new StringContent("[{\"Success\":\"Fail\"},{\"Message\":\"Login Fail\"}]", System.Text.Encoding.UTF8, "application/json") };
}
return new HttpResponseMessage { Content = new StringContent("[{\"Success\":\"Success\"},{\"Message\":\"Login successfully\"}],{\"Data\":"+value+"}", System.Text.Encoding.UTF8, "application/json") };
}
I want to add value to HttpResponseMessage. Value will return a json normal.
[
{
"Success": "Success"
},
{
"Message": "successfully"
}
Value will display at here
]
Since you are using [ActionName("GetAccount")]... you should use IActionResult as the return type.
Otherwise if you want to use HttpResponseMessage, use -
[Route("api/GetAccount")]
Also, you can construct the output result like
return new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = data };
Use Jobject to return
return new JObject(<your dynamic object here>);

MVC Parameter Binding from JSON into multiple parameters

I'm receiving JSON data from this method:
function CallAPI(controllerName, functionName, sendData, callback) {
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function () {
if (ajax.readyState == 4) {
if (ajax.status == 200) {
var response = JSON.parse(ajax.responseText);
callback(response);
}
else {
callback();
}
}
}
ajax.open("POST", "http://" + window.location.host + "/API/" + controllerName + "/" + functionName, true);
ajax.setRequestHeader('Content-Type', 'application/json');
ajax.send(JSON.stringify(sendData));
}
function someRequest() {
var data = {};
data.userID = 1;
data.someValue = 20;
CallAPI("Home", "Add", data, function (response) {
if(response) {
alert(response.Message); //This property always exist
}
else {
alert("internet/connection error.");
}
});
}
And my Controller is:
[System.Web.Http.HttpPost]
public HttpResponseMessage Add(int userID, int someValue)
{
//Here!
return Request.CreateResponse(HttpStatusCode.OK, new GenericResponseAPI() { Status = false, Message = "Generic Message." });
}
I can create a model and MVC would bind it accordingly, but I have so many of these requests that I don't want to create various models (or a big one containing all of the properties), but instead have these simple functions with basic type parameters like this.
What do I need to do to be able to work with the controller function above, without changing the content-type of the incoming message?
Edit: I found a workaround with this:
[System.Web.Http.HttpPost]
public HttpResponseMessage Add(JObject jObject)
{
int userID = (int)jObject.getValue("userID").ToObject(typeof(Int32));
int someValue = (int)jObject.getValue("someValue").ToObject(typeof(Int32));
return Request.CreateResponse(HttpStatusCode.OK);
}
I imagine the reason is that your function signature is:
function CallAPI(controllerName, functionName, sendData, callback)
and you're calling
CallAPI("Home", "Add", function (response) { ... })
So you're never actually sending data in the format MVC is expecting.
I'd double check this by using something like Fiddler and by debugging your JavaScript code using your browsers dev-tools.

Categories