I upgraded a service to .NET Core 6. The old code allowed users to send "/" as the Accept header and the code returned the correct response type, xml or json, based on the request. Version 6 doesn't do that any more. The application teams do not want to change their code so I need to know how to allow "/" for Accept header and have the response returned as xml for xml requests and json for json requests.
My Startup.cs file:
using log4net;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System.IO;
using System.Linq;
using AgencyInterfaceSearchCore.Models;
using System.Collections.Generic;
using Newtonsoft.Json.Serialization;
using AgencyInterfaceSearchCore.Interface;
using AgencyInterfaceSearchCore.Repository;
using System.Text;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Hosting;
namespace AgencyInterfaceSearchCore
{
public class Startup
{
private static readonly ILog _log = LogManager.GetLogger(typeof(Startup));
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public static Dictionary<string, string> StatusMapping { get; set; }
public static Dictionary<string, string> EligibilityMapping { get; set; }
public static Dictionary<string, string> ProfileMapping { get; set; }
public static Dictionary<string, string> RedirectMapping { get; set; }
public void ConfigureServices(IServiceCollection services)
{
services.AddSwaggerGen(c =>
{
c.SwaggerDoc(name: "v2", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Agency Interface Search Web Service", Version = "v2" });
});
services.AddMvc(config =>
{
config.RespectBrowserAcceptHeader = true;
}).AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
});
services.AddControllers().AddXmlSerializerFormatters();
// Add Service/Repository
services.AddScoped<IHostBridgeService, HostBridgeService>();
services.Configure<CustomHostBridgeSection>((settings) =>
{
Configuration.GetSection("EligibilityMapping").Bind(settings);
});
StatusMapping = Configuration.GetSection("StatusMapping").GetChildren()
.ToDictionary(x => x.Key, x => x.Value);
EligibilityMapping = Configuration.GetSection("EligibilityMapping").GetChildren()
//.Select(item => new KeyValuePair<string, string>(item.Key, item.Value))
.ToDictionary(x => x.Key, x => x.Value);
ProfileMapping = Configuration.GetSection("ProfileMapping").GetChildren()
.ToDictionary(x => x.Key, x => x.Value);
RedirectMapping = Configuration.GetSection("RedirectMapping").GetChildren()
.ToDictionary(x => x.Key, x => x.Value);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.Use(async (context, next) =>
{
context.Request.EnableBuffering(); //enables repeated reading of request
var initialHeaders = context.Request.Headers;
using (var reader = new StreamReader(
context.Request.Body,
encoding: Encoding.UTF8,
detectEncodingFromByteOrderMarks: false,
bufferSize: 1024 * 100, //change 100 to accommodate the biggest request. In this case the size is 100Kb
leaveOpen: true))
{
string body = await reader.ReadToEndAsync();
_log.Info("Original Unescaped Request: " body);
string headerString = "\r\n";
foreach (var item in initialHeaders)
{
if (!string.IsNullOrEmpty(item.ToString()))
{
headerString = item.ToString() "\r\n";
}
}
_log.Info("Original Headers: " headerString);
context.Request.Body.Position = 0;
await next.Invoke();
}
});
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint(url: "/swagger/v2/swagger.json", name: "Acquire Customer Number Service API V2");
});
_log.Info("Swagger configured as JSON endpoint.");
_log.Info("App Configured");
}
}
}
The request object:
using System.Runtime.Serialization;
namespace AgencyInterfaceSearchCore.Models
{
[DataContract]
public class AgencyInterfaceSearchRequest
{
[DataMember]
public string AgencyCode { get; set; }
[DataMember]
public string RedirectionCode { get; set; }
[DataMember]
public string CallingApplicationName { get; set; }
[DataMember]
public string FutureUse { get; set; }
}
}
CodePudding user response:
"Accept" in your request header means which content-type you want in your response body,if you setted:"Accept":"*/*"
,it means all content-type are Ok.
If you want to set the content-type of your response body same as which of your
request body,just try as below in your controller:
var ContentType = HttpContext.Request.Headers["Content-Type"];
HttpContext.Response.ContentType = ContentType;