RestSharp AddJsonBody serialization camel case - asp.net-core

I'm using RestSharp v107.1.1 in a .net 5.0 core web app and when i add an object to my RestRequest with AddJsonBody it's serializing the property names in camel casing.
How do i make RestSharp not modify the property names when serializing!?
request.AddJsonBody(new { IHateCamelCase = "why you do this!" });
results in
CONTENT <root type="object"> <iHateCamelCase type="string">why you do this!</iHateCamelCase> </root>
when it should look like this
CONTENT <root type="object"> <IHateCamelCase type="string">why you do this!</iHateCamelCase> </root>
An example would be great!

You need to configure the serializer as you would do with anything else.
var options = new JsonSerializerOptions(JsonSerializerDefaults.General);
client.UseSystemTextJson(options);

Related

Get Swagger URL programmatically in ASP.NET Core

I'm using ASP.NET Core 5, and Swagger. I know how to use Swagger, and it works properly.
Swagger is served on foo:5001/swagger - but I need to determine that URL programmatically at runtime.
How can I do that?
I already tried:
Getting it by injecting IEnumerable<EndpointDataSource> into some helper/controller class, but that shows me all routes EXCEPT swagger's.
Getting it while setting up endpoint routing and inspecting IEndpointRouteBuilder, but once again it shows me all routes EXCEPT swagger's.
According to sources at https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerUI/SwaggerUIMiddleware.cs you can use an instance of class SwaggerUIOptions:
Register instance in DI container:
var options = new SwaggerUIOptions
{
RoutePrefix = "swagger"
};
options.SwaggerEndpoint("/swagger/v1/swagger.json", "waiting_list v1");
services.AddSingleton(options);
Use configured instance:
app.UseSwaggerUI(app.ApplicationServices.GetRequiredService<SwaggerUIOptions>());
Inject instance to any controller/class:
public WeatherForecastController(ILogger<WeatherForecastController> logger, SwaggerUIOptions swaggerOptions)
{
}
Property RoutePrefix contains swagger prefix (without leading '/')
This idea works only if options object passed to UseSwaggerUI method (available since version 6.0.0). If UseSwaggerUI invoked using callback (like a UseSwaggerUI(a => { a.RoutePrefix = string.Empty; })) it won't work.

NetCore 3.1 PostAsync CustomHeaders not working

I have several RESTful services that working with each other. In one scenario I want to post some data from one service to another service and I want to attach some information in Header of the request. I saw several cases to do this and in the end I came up with this workaround:
var httpClient = new HttpClient();
httpClient.Timeout = TimeSpan.FromMinutes(3);
var httpRequestMessage = new HttpRequestMessage {
Method = HttpMethod.Post,
RequestUri = new Uri(service2Address),
Content = new StringContent(JsonConvert.SerializeObject(obj))
};
httpRequestMessage.Headers.Add("myCustomHeaderKey", "myCustomHeaderValue");
var response = await httpClient.SendAsync(httpRequestMessage);
var responseString = await response.Content.ReadAsStringAsync();
With these lines of code, a Post request sent, but in service2 when I want to get the headers from request, there is no sign of myCustomHeaderKey in headers collection. I inspect Request.Headers in Visual Studio Watch and even try to get custom header with Request.Headers["myCustomHeaderKey"]. So what's wrong here?
EDIT 1
This implementation in based on this tutorial.
I have developed code like yours. Have created Two Asp.net core 3.1 project with standart template. One service is starting localhost:44320 and other localhost:44300
localhost:44320/PostService wrote the your codes.
Then get this url with browser. localhost:44320/weatherforecast/IncomeService function is like below
Finally i put breakpoint to where get request header. Result is like below
There is a not a problem. Maybe you use change request header middleware. Or if you are using something like nginx. this problem maybe nginx configuration.

HttpRequestMessage.Content is null in receiving Controller action

I've looked at some similar posts, but all had some relevant detail that does not apply in my case. I have an existing Shopper service with a Register method. It is built on .NET Framework 4.6.1 Web API. I have a number of working scenarios in which another .NET Framework 4.6.1 Web API service calls the Shopper service using HttpClient and HttpRequestMessage. I do this with GET, PUT, and POST methods and successfully pass data to the PUT and POST methods using
request.Content = new ObjectContent<MemberAddress>(memberAddress, new System.Net.Http.Formatting.JsonMediaTypeFormatter());
I'm now developing a new service, this one built on ASP.NET Core Web API. I'm attempting to call a POST action in the Shopper service. I'm getting my HttpClient from IHttpClientFactory.CreateClient. The HttpRequestMessage set up is, I think, the same as in my other calling services.
var request = new HttpRequestMessage(HttpMethod.Post, updateShopperUrl);
request.Content = new ObjectContent<MemberRegistration>(memberRegistration, new System.Net.Http.Formatting.JsonMediaTypeFormatter(), "application/json");
The call to the service looks like this:
var httpClient = _clientFactory.CreateClient();
var response = await httpClient.SendAsync(request);
I can inspect request.Content.Value before the call and it contains the object/data I expect. The controller action code on the other end looks like this:
[Route("{shopperId}/register")]
[Route("~/api/shopper/{shopperId}/register")]
[HttpPost]
public IHttpActionResult RegisterNewMember(string shopperId, [FromBody] MemberRegistration memberRegistration)
{
But the memberRegistration parameter is always null. The [FromBody] attribute is recent addition in an attempt to solve this problem, but it did not help. FromBody should be the default behavior for a complex object parameter anyway. I can POST to that endpoint with Postman and the memberRegistration data comes through.
Either I'm just missing something obvious or maybe there's something different happening in the ASP.NET Core calling side of the equation.
It appears you are trying to post JSON data
Try changing the approach a bit and see if it make a difference.
var json = JsonConvert.SerializeObject(memberRegistration);
var content = new StringContent(json, Encoding.UTF8,"application/json");
var httpClient = _clientFactory.CreateClient();
var response = await httpClient.PostAsync(updateShopperUrl, content);
The above manually serializes the object to JSON and Posts it to the web API.
It is possible there could have been an issue with the formatter used with the ObjectContent

How can I attach BinarySecurityToken in request header(.net core)

I want to create something like below
<soapenv:Header>
<wsse:Security>
<wsse:BinarySecurityToken EncodingType="XXXX" ValueType="XXX">Token
</wsse:BinarySecurityToken>
</wsse:Security>
</soapenv:Header>
I manage to acheive this by using the below code, which is working (well Kind of!)
using (new OperationContextScope(experianProxy.InnerChannel))
{
DataContractJsonSerializer serializer =new
DataContractJsonSerializer(typeof(BinarySecurityToken));
MessageHeader header = MessageHeader.CreateHeader("wsse:Security", "",
_token,serializer);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
var interactiveResponse = experianProxy.InteractiveAsync(new Root()).Result;
return interactiveResponse.OutputRoot.ToString();
}
and
[XmlRoot(ElementName = "wsse:BinarySecurityToken", Namespace = "")]
public sealed class BinarySecurityToken : IXmlSerializable
{...}
Now the request going out is,
<soapenv:Header>
<wsse:Security><wsse_x003A_BinarySecurityToken ValueType="xxxx"
EncodingType="wsse:Base64Binary"
>XXXXXXXXXXX</wsse_x003A_BinarySecurityToken>
</wsse:Security>
</soapenv:Header>
Converting cdata didn't help.
Can someone please point out what am I missing? Any help is much appreciated.
Thank you.
The scope of OperationContextScope is only valid within the using statement. after the instance of OperationContextScope is released, the OperationContext is restored and the message header is no longer valid. if you try to call the method in the using statement, you will find your custome header.
You can use the IClientMessageInspector interface if you want to permanently add message headers to requests.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/f1f29779-0121-4499-a2bc-63ffe8025b21/wcf-security-soap-header

Apache cxf jax-rs implementation with xml databind

I configured my rest service to implement content negotiation through Variant.
On jersey all works fine but on apache cxf something goes wrong.
No message body writer has been found for class ContentType: application/xml
It seems thath when I construct the response as xml type it cannnot find the correct body writer.
I configured jax-rs with jacksonJaxbJsonProvider and all works great with json databind.
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider" />
</jaxrs:providers>
cxf-rt-frontend-jaxrs version 3.0.3
jackson-databind: 2.4.2
Any idea?
Add a #XmlRootElement(name="order") generated xml cannot be <orderId>data<orderId>, it should have root element. Thus updated code would look like
#XmlRootElement(name="order")
#XmlType(propOrder = { "orderId"})
public class OrderForConfirmationEmail implements Serializable {
#XmlElement
public long getOrderId() {
long orderId = new Random().nextLong();
return orderId;
}
}
Generated xml is
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><order xmlns="http://com.kp.swasthik/so/schema">
<orderId>369317779145370211</orderId>
</order>
and json is
{"orderId":6812414735706519327}