I have an xml document that I want to return via a web api call.
I want to allow the user the option of the response via content negotiation.
[HttpGet]
public HttpResponseMessage Get()
{
var doc = new XmlDocument();
doc.LoadXml("<MyExport SomeProperty='Some Value'></MyExport>");
return Request.CreateResponse(HttpStatusCode.OK, doc);
}
When I request this an Accept header of application/json I get:
{
"MyExport": {
"#SomeProperty": "Some Value"
}
}
Is it correct that # is included in the property name?
If so why?
Related
So I have to make a method in asp.net for an API that accepts 2 files via PUT (1 json and 1 xml for processing data, not saving- because I have to, OK? :) ), sending the request via fiddler..
Right now I'm sending the request like this on fiddler (PUT METHOD):
Content-Type: multipart/form-data
Authorization: XXXXX
Host: XXXX
Request body:
<#INCLUDE *C:\Users\ZZZZ.json*#>
<#INCLUDE *C:\Users\XXXX.xml*#>
Here's what I've tried inside the controller so far:
[HttpPut, Route("api/Student/{studentId}/Classes/{classId}")]
public async Task<string> Put(int studentId, int classId)
{
var file = HttpContext.Current.Request.Files.Count > 0 ?
HttpContext.Current.Request.Files[0] : null;
Stream fileContent = await this.Request.Content.ReadAsStreamAsync();
MediaTypeHeaderValue contentTypeHeader = this.Request.Content.Headers.ContentType;
if (fileContent != null)
return "ok";
return "not ok";
}
So far the file is not being uploaded nor appears within the request (everything's null). I've also tried the "Request" variable and HttpContext.
Tried the exact same thing but with a POST Method (including the boundaries) and the same happens.
What would you do in order to make this work? I really have to send a json object and another in xml, I really can't change languages or send everything in json ('cause that I could make it work)...
PS: The files don't have a defined structure, it has to be dynamic
PS2 : How would you then attempt to read those files without actually saving them?
You don't have to use a stream to read the file content. You can just try using the HttpPostedFile.
[HttpPut, Route("api/student/{studentId}/classes/{classId}")]
public async Task<string> Put(int studentId, int classId)
{
if (HttpContext.Current.Request.Files.Count == 0)
throw new HttpResponseException(new HttpResponseMessage()
{
ReasonPhrase = "Files are required",
StatusCode = HttpStatusCode.BadRequest
});
foreach (string file in HttpContext.Current.Request.Files)
{
var postedFile = HttpContext.Current.Request.Files[file];
if (!(postedFile.ContentType == "application/json" || postedFile.ContentType == "application/xml"))
{
throw new System.Web.Http.HttpResponseException(new HttpResponseMessage()
{
ReasonPhrase = "Wrong content type",
StatusCode = HttpStatusCode.BadRequest
});
}
}
return "OK";
}
POSTMAN
My POSTMAN:
enter image description here
Fiddler
I have a Web API controller action where I want to set response headers and also return the content in the requested format specified by the Accept header.
Unfortunately if I'm using a typed action or IHttpActionResult for the action's return type, I can't set the headers, but the content negotiation works.
I'd have to return HttpResponseMessage to be able to specify headers in the action, but then I need to specify the formatter for the ObjectContent. Although I'm only supporting XML or JSON types, I still don't want to burn in ugly conditionals to check what the return type should be.
Is there a way to do this nicely, without filters, attributes and custom generic return types?
public HttpResponseMessage Post([FromBody]QueryModel model)
{
var data = _svc.Query(model);
var resp = new HttpResponseMessage(HttpStatusCode.OK);
// set headers
resp.Content = new ObjectContent(typeof(ResponseModel), data, /* CAN YOU NOT GUESS */);
return resp;
}
The solution was actually easy, the Request object has a CreateResponse() method to craft a HttpResponseMessage.
public HttpResponseMessage Post([FromBody]QueryModel model)
{
var data = _svc.Query(model);
var resp = Request.CreateResponse(HttpStatusCode.OK, data);
resp.Content.Headers.Add("X-Moo", "Boo");
return resp;
}
I faced problem like this.
I have method in controller, that receive data in body of POST request.
Here is method.
// POST: api/StartWorkingDays
[ResponseType(typeof(StartWorkingDay))]
public IHttpActionResult PostStartWorkingDay(StartWorkingDay startWorkingDay)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
db.StartWorkingDays.Add(startWorkingDay);
db.SaveChanges();
return Json(new { Result = "Success", Message = "Saved Successfully"});
//return CreatedAtRoute("DefaultApi", new { id = startWorkingDay.Id }, startWorkingDay);
}
How I can see body of request that I receive?
Thank's for help.
[HttpPost]
public HttpResponseMessage PostStartWorkingDay([FromBody] StartWorkingDay startWorkingDay)
{
//here above startWorkingDay is body your mobile developer will send
//you and data can be viewed while debugging ,
//tell mobile developer to set content-type header should be JSON.
return Request.CreateResponse(HttpStatusCode.Created, "Success");
}
Why your return type is Json ? you should use HttpResponse . I believe you are using Web api 2 . With Attribute routing and if you want to send response in json format then remove Xml formatter from WebApiConfig.cs file inside App_Start folder
I have a Web API solution which is configured to respond results always in JSON format as below
config.Formatters.JsonFormatter.SerializerSettings.Formatting =
Newtonsoft.Json.Formatting.Indented;
But now I have a requirement to respond only one of the API calls with XML Response . But if I add the XML formatter to the system
config.Formatters.XmlFormatter.UseXmlSerializer = true;
then all the API calls get affected.
I have a XML string hardcoded which I want to give as reponse .
How can I solve this problem ?
You have to use the Сonfiguration.Formatters.XmlFormatter at api level. Try below code
public IHttpActionResult ApiMethod()
{
...
return Content(HttpStatusCode.OK, Model, Configuration.Formatters.XmlFormatter);
}
Write the below code in your action:
Class1 c1 = new Class1();//Your Model class
var content = new ObjectContent<Class1>(c1,
GlobalConfiguration.Configuration.Formatters.XmlFormatter);
return new HttpResponseMessage()
{
Content = content
};
I have written a method to post messages to an uri.
public string RestClientPost(string uri, string message = null)
{
var client = new RestClient(uri);
var request = new RestRequest(Method.POST);
request.AddHeader("Accept", "text/xml");
if (!string.IsNullOrEmpty(message))
request.AddParameter(message, ParameterType.RequestBody);
var result = "";
var response = client.Execute(request);
if (response.StatusCode == HttpStatusCode.OK)
{
result = response.Content;
Console.WriteLine(result);
}
else
{
result = response.StatusCode.ToString();
}
return result;
}
and below code is used above method to post.
public void test123()
{
string uri = "myuri"; //private uri, cannot expose.
var file= System.IO.File.ReadAllText(Path.Combine(Settings.EnvValPath, "RestClientXML", "test.XML"));
var content = new RestClientServices().RestClientPost(uri, file);
}
however, it returns "Unsupported Media type".
my test.XML's content is
<customer>
<customerName>test</customerName >
<customerStatus>OK</customerStatus >
</customer>
And using Advanced Rest Client Plugin for Google Chrome, I'm able to post it and return with string that I wanted. Is there something wrong?? I set "content-type" to "text/xml" in Advanced Rest Client.
The return message is id of the customer. e.g: 2132
im using postman,
if you can call any xml web services with this tools , then you can click on code and select restsharp and copy paste it to your code
This happened because the header "Accept" is to specify a type of return object. In this case a value of a variable content, not the type of content to send. Specify a type of content to send with: "Content-Type: application/xml".
If a return type of POST request is a media file, you can use 'image/png' or 'image/jpeg'. You can use multiple accept header values like: "application/xml, application/xhtml+xml, and image/png".
For example, you can use Fiddler to debug HTTP(s) traffic - it's a good tool for web developers.