title: ASP.Net Core - Customer Formatter takes precedence
body: <p>I followed the example <a href="https://docs.microsoft.com/en-us/aspnet/core/web-api/advanced/custom-formatters?view=aspnetcore-2.2" rel="nofollow noreferrer">here</a> and written my customer formatter below. It works fine, however the issue is it always runs first and doesn't take into account it should only run when Accept Header is text/csv.</p>
  
  <pre><code>public class CSVFormatter : TextOutputFormatter
  {
      private string FileName { get; set; }
  
      public CSVFormatter()
      {
          SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/csv"));
  
          SupportedEncodings.Add(Encoding.UTF8);
          SupportedEncodings.Add(Encoding.Unicode);
      }
  
      protected override bool CanWriteType(Type type)
      {
          return IsTypeOfIEnumerable(type);
      }
  
      private bool IsTypeOfIEnumerable(Type type)
      {
          foreach (Type interfaceType in type.GetInterfaces())
          {
              if (interfaceType == typeof(IEnumerable))
                  return true;
          }
  
          return false;
      }
  
      public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context, Encoding selectedEncoding)
      {
          IServiceProvider serviceProvider = context.HttpContext.RequestServices;
  
          var response = context.HttpContext.Response;
          var buffer = new StringBuilder();
          var value = context.Object;
          var type = context.ObjectType;
  
          WriteData(type, value, buffer, response);
  
          return response.WriteAsync(buffer.ToString());
      }
  
      private void WriteData(Type type, object value, StringBuilder buffer, HttpResponse response)
      {
          //NOTE: We have check the type inside CanWriteType method. If request comes this far, the type is IEnumerable. We are safe.
  
          Type itemType = type.GetGenericArguments()[0];
  
          //Write out columns
          buffer.AppendLine(string.Join&lt;string&gt;(",", itemType.GetProperties().Select(x =&gt; x.Name.ToLower())));
  
          foreach (var obj in (IEnumerable&lt;object&gt;)value)
          {
              var vals = obj.GetType().GetProperties().Select(pi =&gt; new { Value = pi.GetValue(obj, null) });
              string valueLine = string.Empty;
  
              foreach (var val in vals)
              {
                  var columnValue = val.Value;
                  valueLine = string.Concat(valueLine, columnValue, ",");
              }
  
              valueLine = valueLine.Substring(0, valueLine.Length - 1);
  
              buffer.AppendLine(valueLine);
          }
      }
  }
  </code></pre>
  
  <p>I added it to Starup.cs like this:</p>
  
  <pre><code> services.AddMvc(options =&gt;
              {
                  options.RespectBrowserAcceptHeader = true;
                  options.OutputFormatters.Insert(0, new CSVFormatter());
              })
  </code></pre>
  
  <p>Pre Asp.net core, in .Net I only ran my Custom Formatter when I needed it by specifying a certain query string "<strong>format=csv</strong>" for.e.g.</p>
  
  <p>So couple of questions:</p>
  
  <ul>
  <li>How can I force it to only run when I want.</li>
  <li>Also can I pass a file name in Query string or header and read it in the custom formatter and add it like this.</li>
  </ul>
  
  <p><em><code>headers.Add("Content-Disposition", string.Format("attachment; filename={0}", FileName));</code></em></p>