I am using the IHttpActionResult Type for the API Call which is Get call and i want to send the Response Header in a same call above is my code
[HttpGet]
public IHttpActionResult GetSyncData()
{
syncDataRepository.Location = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.Location);
syncDataRepository.UserLocation = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.UserLocation);
syncDataRepository.UserAuthentication = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.UserAuthentication);
syncDataRepository.UserDetails = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.UserDetails);
syncDataRepository.TourOrganization = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.TourOrganization);
syncDataRepository.TourBatch = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.TourBatch);
syncDataRepository.TourSuperBatch = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.TourSuperBatch);
syncDataRepository.TourPlanItemChat = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.TourPlanItemChat);
syncDataRepository.TourBatchPlan = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.TourBatchPlan);
syncDataRepository.MyRole = JsonConvert.SerializeObject(Roles.GetRolesForUser(HttpContext.Current.User.Identity.Name));
syncDataRepository.DeletedBatchPlan = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.DeletedBatchPlan);
syncDataRepository.Mode = JsonConvert.SerializeObject(SyncDataOfMobileDatatSet.Mode);
string jsonData = JsonConvert.SerializeObject(syncDataRepository);
return Json(syncDataRepository);
}
i tried with HttpContext.Response but i am getting it as null. so is there any other way please help me.
Thank You.
You can set a response header by implementing the IHttpActionResult and setting the header in the ExecuteAsync method like so :
public class DateHeaderActionResult<TContent> : IHttpActionResult
{
private DateTime _date;
private TContent _content;
private HttpRequestMessage _request;
public DateHeaderActionResult(DateTime date, TContent content, HttpRequestMessage request)
{
_date = date;
_content = content;
_request = request;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = _request.CreateResponse(HttpStatusCode.OK);
response.Headers.Add("MyDate", _date.ToString("yyyyMMddThhmmss"));
response.Content = new ObjectContent<TContent>(_content, new JsonMediaTypeFormatter());
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return Task.FromResult(response);
}
}
And then in your controller instead of returning
return Json(syncDataRepository);
You would return
return new DateHeaderActionResult<SyncDataRepository>(DateTime.Now, syncDataRepository, Request);
That's assuming the syncDataRepository class name is SyncDataRepository
Related
I am trying to send Get request using RestSharp but getting this message in response:Bad Request/
{"Message":"P1001: No Ids were specified"}. Could someone help please to figure out that? Seems like it's not adding Parameter list to the Request Body...
Here is my code:
public partial class DTO
{
public List<string> evidenceIds { get; set; }
}
public RestRequest GetPlayRequest(Method requestType, string token)
{
DTO MyObject = new DTO();
MyObject.evidenceIds = new List<string>();
MyObject.evidenceIds.Add("6F00CAE1-F16E-47F6-AF3F-D10305DD7859");
string jsonString = JsonConvert.SerializeObject(MyObject);
var restRequest = new RestRequest(requestType);
restRequest.RequestFormat = DataFormat.Json;
restRequest.AddParameter("text/json", jsonString, ParameterType.RequestBody);
restRequest.AddHeader("Organization", "Bofa");
restRequest.AddHeader("Username", "Admin");
restRequest.AddParameter("Authorization", "Bearer " + token, ParameterType.HttpHeader);
return restRequest;
}
The request with all params
The Content response after sending the request
I can suggest the following:
public RestRequest GetPlayRequest(Method method, string token)
{
var obj = new DTO { evidenceIds = new string[]
{"6F00CAE1-F16E-47F6-AF3F-D10305DD7859" }
};
return new RestRequest(method)
.AddJsonBody(obj)
.AddHeader("Organization", "Bofa")
.AddHeader("Username", "Admin");
.AddHeader("Authorization", $"Bearer {token}");
}
How can I return HTTP Content-Type "application/json" header? Can not find a sample in net...
[FunctionName("Function1")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
Dictionary<string, string> dd = Parser(requestBody);
string json = JsonConvert.SerializeObject(dd);
if (json == null)
{
return new BadRequestObjectResult("Please pass request body");
}
return (ActionResult)new OkObjectResult(json);
}
1 - By specifying it in your request "Accept : application/json". Azure functions will natively return the type requested in the Accept header. Your code should already be correctly honouring that request.
2 - By returning a JsonResult
The following code will ignore the Accept header and return "application/json" in every case - your serialization is redundant.
[FunctionName("Function1")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
Dictionary<string, string> dd = Parser(requestBody);
if (dd == null) return new BadRequestObjectResult("Please pass request body");
return (ActionResult) new JsonResult(dd);
//return (ActionResult) new OkObjectResult(dd);
}
You could do this by accessing the Response object via the request's HttpContext:
[FunctionName("Function1")]
public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log)
{
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
Dictionary<string, string> dd = Parser(requestBody);
string json = JsonConvert.SerializeObject(dd);
if (json == null)
{
return new BadRequestObjectResult("Please pass request body");
}
//add this line...
req.HttpContext.Response.Headers.Add("Content-Type", "application/json");
return (ActionResult)new OkObjectResult(json);
}
I believe you are looking for the CreateResponse class:
var jObject = JObject.Parse(resp);
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(jObject.ToString(), Encoding.UTF8, "application/json");
return response;
My Action method is returning HttpResponseMessage but, I want to get rid off Microsoft.AspNetCore.Mvc.WebApiCompatShim NuGet Package (which is basically provided to bridge the gap while porting Asp.Net Web API code into .Net Core) and use IActionResult/ActionResult instead of HttpResponseMessage.
My Action method looks like this:
[HttpGet]
[Route("GetTemplate")]
public async Task<HttpResponseMessage> GetTemplate(string id) {
var userAgent = this.Request.Headers.UserAgent;
bool IsWindows = true;
if(userAgent.ToString().ToLower().Contains("apple")) {
IsWindows = false; //false
}
var template = await _templateService.GetTemplateContent(id);
HttpResponseMessage responseMsg = new HttpResponseMessage();
if(IsWindows) {
responseMsg.Content = new StringContent(JsonConvert.SerializeObject(template));
responseMsg.RequestMessage = Request;
responseMsg.StatusCode = HttpStatusCode.OK;
responseMsg.Content.Headers.ContentType =
new MediaTypeHeaderValue("application/json");
} else {
responseMsg.Content = new ByteArrayContent(template.ContentBytes);
responseMsg.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment") { FileNameStar = template.Name };
responseMsg.Content.Headers.Add("x-filename", template.Name);
responseMsg.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
responseMsg.Content.Headers.ContentLength = template.ContentBytes.Length;
responseMsg.RequestMessage = Request;
responseMsg.StatusCode = HttpStatusCode.OK;
}
return (responseMsg);
}
Since you aren’t doing anything fancy there, you can translate your return object directly into corresponding action results here. In your case, you want a JsonResult and a FileResult with a custom response header:
[HttpGet]
[Route("GetTemplate")]
public async Task<HttpResponseMessage> GetTemplate(string id)
{
var userAgent = this.Request.Headers.UserAgent;
bool IsWindows = !userAgent.ToString().ToLower().Contains("apple");
var template = await _templateService.GetTemplateContent(id);
if (IsWindows)
{
return Json(template);
}
else
{
Response.Headers.Add("x-filename", template.Name);
return File(template.ContentBytes, "application/octet-stream", template.Name);
}
}
There are a lot similar utility methods on the Controller and ControllerBase type that help you create a variety of different response messages. For most use cases, there should be a built-in way to produce the response.
1stly change the signature of your action to this:
public async Task<IActionResult> GetTemplate
You will then return your data in the response something like this return Ok(data). You do not have to serialize your data, you can send a POCO class. This would represent .StatusCode = HttpStatusCode.OK
If you want to add extra headers to your response, you will do so using the Response field from ControllerBase. Eg. Response.Headers.Add for adding key value pairs to your Response header.
I want to write custom batch handler in my webapi.
Requirement for this : I am not able to identify weather the incoming request is part of batch or independent.
By writing custom batch handler i will be able to add value in header of each request, which i can use later to identify.
First we need to write custom batch hahttps://stackoverflow.blog/2011/07/01/its-ok-to-ask-and-answer-your-own-questions/ndler
For this we need to override HttpMessageHandler. Below is code
public class BatchHandler : HttpMessageHandler
{
HttpMessageInvoker _server;
public BatchHandler(HttpConfiguration config)
{
// BatchServer is a class which overrides
_server = new HttpMessageInvoker(new BatchServer(config));
}
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
// Return 400 for the wrong MIME type
// As batch request will always be of MIME type
if ("multipart/mixed" !=
request.Content.Headers.ContentType.MediaType)
{
return request.CreateResponse(HttpStatusCode.BadRequest);
}
// Start a multipart response
var outerContent = new MultipartContent("batch");
var outerResp = request.CreateResponse();
outerResp.Content = outerContent;
// Read the multipart request
var multipart = await request.Content.ReadAsMultipartAsync();
foreach (var httpContent in multipart.Contents)
{
HttpResponseMessage innerResp = null;
try
{
// Decode the request object
var innerReq = await
httpContent.ReadAsHttpRequestMessageAsync();
innerReq.Headers.Add("IsBatch", "true");
// Send the request through the pipeline
innerResp = await _server.SendAsync(
innerReq,
cancellationToken
);
}
catch (Exception ex)
{
// If exceptions are thrown, send back generic 400
innerResp = new HttpResponseMessage(
HttpStatusCode.BadRequest
);
}
// Wrap the response in a message content and put it
// into the multipart response
outerContent.Add(new HttpMessageContent(innerResp));
}
return outerResp;
}
}
in above code their is this line
// BatchServer is a class which overrides HttpServer
_server = new HttpMessageInvoker(new BatchServer(config));
if we don't do this we gets an error
The 'DelegatingHandler' list is invalid because the property
'InnerHandler' of 'xxhandler' is not null.\r\nParameter
name: handlers
Below is the BatchServer class which overrides HttpServer
public class BatchServer : HttpServer
{
private readonly HttpConfiguration _config;
public BatchServer(HttpConfiguration configuration)
: base(configuration)
{
_config = configuration;
}
protected override void Initialize()
{
var firstInPipeline = _config.MessageHandlers.FirstOrDefault();
if (firstInPipeline != null && firstInPipeline.InnerHandler != null)
{
InnerHandler = firstInPipeline;
}
else
{
base.Initialize();
}
}
}
Now we want to hit batch request on BatchHandler
For this we need configure route to BatchHandler
Add below code to your AppStart
var batchHandler = new BatchHandler(config);
config.Routes.MapHttpRoute("batch", "api/batch", null, null, batchHandler);
I am using Web API 2. I have the following in my controller (and more):
[Route("about")]
public string GetAbout()
{
IPrincipal principal = RequestContext.Principal;
IPrincipal user = User;
return string.Format("principal: {0}, user: {1}", principal == null || principal.Identity == null ? null : principal.Identity.Name,
user == null ? null : user.Identity.Name);
}
[Route("license/exchange")]
//public string PostUser([FromBody]string value)
public XmlDocument PostLicenseExchange(XmlDocument xml)
{
Trap.trap();
int x = 3;
return xml;
}
In my browser, If I put in the URI http://localhost:13770/about, I get the data back.
But I I try a POST to http://localhost:13770/license/exchange, I get:
System.Net.WebException occurred
Message=The remote server returned an error: (401) Unauthorized.
Source=System
StackTrace:
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at EnforcedVacationCommon.LicenseServer.ServerComm.GetResponseCallback(IAsyncResult asynchronousResult) in c:\src\EnforcedVacation\EnforcedVacationCommon\LicenseServer\ServerComm.cs:line 137
InnerException:
I am calling using:
Start() {
// start the request
Uri httpSite = new Uri(URI_LICENSE_SERVER);
WebRequest wreq = WebRequest.Create(httpSite);
wreq.Method = "POST";
wreq.ContentType = "text/xml";
RequestState requestState = new RequestState(asyncCallback, xmlDoc.ToString(SaveOptions.DisableFormatting), msgGuid, wreq);
wreq.BeginGetRequestStream(GetRequestStreamCallback, requestState);
}
private static void GetRequestStreamCallback(IAsyncResult asynchronousResult)
{
RequestState requestState = (RequestState)asynchronousResult.AsyncState;
using (Stream postStream = requestState.Request.EndGetRequestStream(asynchronousResult))
{
byte[] byteArray = Encoding.UTF8.GetBytes(requestState.XmlRequest);
postStream.Write(byteArray, 0, byteArray.Length);
postStream.Close();
}
requestState.Request.BeginGetResponse(GetResponseCallback, requestState);
}
private static void GetResponseCallback(IAsyncResult asynchronousResult)
{
RequestState requestState = (RequestState)asynchronousResult.AsyncState;
// exception on this call
using (HttpWebResponse response = (HttpWebResponse) requestState.Request.EndGetResponse(asynchronousResult))
What am I doing wrong?
You need to specify that this is a Http Post method with an attribute on the action result as such.
[HttpPost]
[Route("license/exchange")]
//public string PostUser([FromBody]string value)
public XmlDocument PostLicenseExchange(XmlDocument xml)
{
Trap.trap();
int x = 3;
return xml;
}
You can see the documentation by clicking here.