2

I have been introduced to an already existing C# ASP.Net Web API project a week ago. It returns all the data in JSON and Pascal Case, and this data is used by websites using React.Js which are case sensitive.

During the last week, after a commit that changed litteraly nothing on the API project (it only added translations for the Web Client project in the solution), suddenly the project started returning JSON in Camel case and not in Pascal Case anymore.

The problem is not like this post, I don't send to the API camel instead of pascal, the API sends camel instead of pascal.

I've been searching how to fix it but there are two specifities to the project that makes it difficult to find an answer :

  • The project uses ASP.Net and not ASP.Net Core, making posts like this or this not helpful
  • The project uses NancyFx 2.0.0, so it doesn't have any starting file (like the startup class in core projects, or .asax file) but uses a custom bootstrapper (see code down below)

Bootstrapper

public class AppBootstrapper : DefaultNancyBootstrapper
{
    protected override void ApplicationStartup(TinyIoCContainer container, IPipelines pipelines)
    {
        log4net.Config.XmlConfigurator.Configure();

        base.ApplicationStartup(container, pipelines);

        pipelines.BeforeRequest.AddItemToStartOfPipeline(ctx =>
        {
            if (ctx != null)
            {
                Log.Request(ctx.Request.GetHashCode(), ctx.Request.Method, ctx.Request.Path, ctx.Request.UserHostAddress, ctx.Request.Headers.UserAgent);
            }

            return null;
        });

        pipelines.AfterRequest.AddItemToEndOfPipeline(ctx =>
        {
            if (ctx != null)
            {
                Log.Response(ctx.Request.GetHashCode(), ctx.Response.StatusCode);
            }
        });
    }

    protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context)
    {
        pipelines.AfterRequest.AddItemToEndOfPipeline(ctx =>
        {
            ctx.Response.WithHeader("Access-Control-Allow-Origin", "*")
                .WithHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE,HEAD,OPTIONS")
                .WithHeader("Access-Control-Allow-Headers", "Accept, Origin, Content-type, Authorization");
        });

        // Gzip management, useless for this post
}

JsonSerializer

internal class JsonNetSerializer : ISerializer
{
    private readonly JsonSerializer _serializer;

    /// <summary>
    /// Initializes a new instance of the <see cref="JsonNetSerializer"/> class.
    /// </summary>
    public JsonNetSerializer()
    {
        _serializer = JsonSerializer.CreateDefault();
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="JsonNetSerializer"/> class,
    /// with the provided <paramref name="serializer"/>.
    /// </summary>
    /// <param name="serializer">Json converters used when serializing.</param>
    public JsonNetSerializer(JsonSerializer serializer)
    {
        _serializer = serializer;
    }

    /// <summary>
    /// Whether the serializer can serialize the content type
    /// </summary>
    /// <param name="mediaRange">Content type to serialise</param>
    /// <returns>True if supported, false otherwise</returns>
    public bool CanSerialize(MediaRange mediaRange)
    {
        return JsonHelpers.IsJsonType(mediaRange);
    }

    /// <summary>
    /// Gets the list of extensions that the serializer can handle.
    /// </summary>
    /// <value>An <see cref="IEnumerable{T}"/> of extensions if any are available, otherwise an empty enumerable.</value>
    public IEnumerable<string> Extensions
    {
        get { yield return "json"; }
    }

    /// <summary>
    /// Serialize the given model with the given contentType
    /// </summary>
    /// <param name="mediaRange">Content type to serialize into</param>
    /// <param name="model">Model to serialize</param>
    /// <param name="outputStream">Output stream to serialize to</param>
    /// <returns>Serialised object</returns>
    public void Serialize<TModel>(MediaRange mediaRange, TModel model, Stream outputStream)
    {
        using (var writer = new JsonTextWriter(new StreamWriter(new UnclosableStreamWrapper(outputStream))))
        {
            _serializer.Serialize(writer, model);
        }
    }
}

I have looked for solutions and so long I've found some sites talking about Owin, but it seems that I have to use a owin-based server (like Nowin) to host the ASP.Net application. The problem is that I have literally never used/heard about it and I lack of time to learn how to use it. On top of that I'm not sure at all that Nowin's Start<TContext>() function will be useful to modify the API's return formatting...

Every other solution I've found was leading to ASP.Net Core technology, but nothing for ASP.Net

0 Answers0