locked
Web API GET new media type CSV - Reference issue RRS feed

  • Question

  • User-1668014665 posted

    I am following this code in docs

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/media-formatters

    My project MSVS 2017, Vb net, Net 4.61, latest DLL imports from nuget,

    GOAL:  to use the GET to return Symbol, Date, O,H,L,C,V data in either CSV or json format.

    Expectation when the CSV formatter is working for my GET 

    I believe the final result will be https://<xxxxx>/api/Data?Symbol=AAPL&type=csv to allow a CSV return format, of course with out the type=csv, then the default will be the standard json format. I assume the 'type' variable is part of the web api structure (??), not a controller GET variable. Correct me if I am wrong.

    My code

    The data model

       Public Class SDOHLCV
            Public nSymbol As String
            Public nDate As String
            Public nOpen As Double
            Public nHigh As Double
            Public nLow As Double
            Public nClose As Double
            Public nVolume As Double
        End Clas

    The converted to vb code from C# from this link, adjusted to the above data model

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/media-formatters

    Imports System
    Imports System.Collections.Generic
    Imports System.IO
    Imports System.Net.Http
    Imports System.Net.Http.Formatting
    Imports XXXXXXXXX.RTT_DataMod
    
    
    
    
    Namespace CSVFormatters
        Public Class SDOHLCVCsvFormatter
            Inherits BufferedMediaTypeFormatter
    
            Public Sub New()
                'SupportedMediaTypes.Clear()
    
                SupportedMediaTypes.Add(New Headers.MediaTypeHeaderValue("text/csv"))
    
                'SupportedEncodings.Add(Encoding.UTF8)
                'SupportedEncodings.Add(Encoding.Unicode)
    
    
            End Sub
    
    
            Public Overrides Function CanWriteType(ByVal type As System.Type) As Boolean
                If type = GetType(SDOHLCV) Then
                    Return True
                Else
                    Dim enumerableType As Type = GetType(IEnumerable(Of SDOHLCV))
                    Return enumerableType.IsAssignableFrom(type)
                End If
            End Function
    
            Public Overrides Function CanReadType(ByVal type As Type) As Boolean
                Return False
            End Function
    
    
            Class SurroundingClass
                Public Sub WriteToStream(ByVal type As Type, ByVal value As Object, ByVal writeStream As Stream)
    
                    Using writer = New StreamWriter(writeStream)
                        Dim OHLC = TryCast(value, IEnumerable(Of SDOHLCV))
    
                        If OHLC IsNot Nothing Then
    
                            For Each SDOHLCV In OHLC
                                WriteItem(SDOHLCV, writer)
                            Next
                        Else
                            Dim sOHLC = TryCast(value, SDOHLCV)
    
                            If sOHLC Is Nothing Then
                                Throw New InvalidOperationException("Cannot serialize type")
                            End If
    
                            WriteItem(sOHLC, writer)
                        End If
                    End Using
                End Sub
    
                Private Sub WriteItem(ByVal nd As SDOHLCV, ByVal writer As StreamWriter)
                    writer.WriteLine("{0},{1},{2},{3},{4},{5},{6}", Escape(nd.nSymbol), Escape(nd.nDate), Escape(nd.nOpen), Escape(nd.nHigh), Escape(nd.nLow), Escape(nd.nClose), Escape(nd.nVolume))
                End Sub
    
                Shared _specialChars As Char() = New Char() {","c, Chr(10), Chr(13), """"c}
    
                Public Shared Property SpecialChars As Char()
                    Get
                        Return _specialChars
                    End Get
                    Set(value As Char())
                        _specialChars = value
                    End Set
                End Property
    
                Private Function Escape(ByVal o As Object) As String
                    If o Is Nothing Then
                        Return ""
                    End If
    
                    Dim field As String = o.ToString()
    
                    If field.IndexOfAny(SpecialChars) <> -1 Then
                        Return String.Format("""{0}""", field.Replace("""", """"""))
                    Else
                        Return field
                    End If
                End Function
            End Class
    
        End Class
    End Namespace
    
    

    The registration of the formatter (not the same as code in link, so correct me if I am wrong)

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Web.Http
    Imports XXXXXX.CSVFormatters
    
    Public Module WebApiConfig
        Public Sub Register(ByVal config As HttpConfiguration)
            ' Web API configuration and services
            'config.Formatters.Clear()
    
            config.Formatters.Add(New SDOHLCVCsvFormatter())
    
            ' Web API routes
            config.MapHttpAttributeRoutes()
    
            config.Routes.MapHttpRoute(
                name:="DefaultApi",
                routeTemplate:="api/{controller}/{id}",
                defaults:=New With {.id = RouteParameter.Optional}
            )
        End Sub
    End Module

    THE ERROR

    In the Namespace CSVFormatters with this line

    SupportedMediaTypes.Add(New Headers.MediaTypeHeaderValue("text/csv"))

    I get an error when I build this to CHROME to use POSTMAN tool to check my controller GET call

    the error is

    Compiler Error Message: BC30652: Reference required to assembly 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' containing the type 'MediaTypeHeaderValue'. Add one to your project.

    I checked  my projects  system.net.http reference version and it is out of Microsoft.AspNet.WebApi.Core.5.2.7  , this is what MSVS loaded when I selected WebAPI (check box) while selecting the new ASP net project.

    So what is the fix?

    Does this help from Webconfig

      <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
          <dependentAssembly>
            <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
            <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="0.0.0.0-5.2.4.0" newVersion="5.2.4.0" />
          </dependentAssembly>
          <dependentAssembly>
            <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
            <bindingRedirect oldVersion="0.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
          </dependentAssembly>
        </assemblyBinding>
      </runtime>

    Thanks

    Friday, March 1, 2019 5:32 PM

All replies

  • User475983607 posted

    There is an issue with the namespace or .NET version.

    The fully qualified name is...

    System.Net.Http.Headers.MediaTypeHeaderValue("text/csv")

    My version is...

    #region Assembly System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
    // C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Net.Http.dll
    #endregion

    Check your project references.

    Friday, March 1, 2019 6:17 PM
  • User1120430333 posted

    Compiler Error Message: BC30652: Reference required to assembly 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' containing the type 'MediaTypeHeaderValue'. Add one to your project.


    I checked my projects system.net.http reference version and it is out of Microsoft.AspNet.WebApi.Core.5.2.7 , this is what MSVS loaded when I selected WebAPI (check box) while selecting the new ASP net project

    You're not doing a Core based project. You could go to Nuget and install System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a into the project and set reference to it, the one that's being called for and see what happens.

    Friday, March 1, 2019 6:34 PM
  • User-1668014665 posted
    Server Error in '/' Application.
    Compilation Error
    Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately. 
    
    Compiler Error Message: BC30652: Reference required to assembly 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' containing the type 'MediaTypeHeaderValue'. Add one to your project.
    
    Source Error:
    
    
    Line 17:             'SupportedMediaTypes.Clear()
    Line 18: 
    Line 19:             SupportedMediaTypes.Add(New System.Net.Http.Headers.MediaTypeHeaderValue("text/csv"))
    Line 20: 
    Line 21:             'SupportedEncodings.Add(Encoding.UTF8)
    
    
    Show Detailed Compiler Output:
    
    Show Complete Compilation Source:
    

    I did that , and it makes no difference!

    I did check my project references my System.Net.Http is as stated above is 5.2.7, thats how it was imported when i loaded up the web api!

    Friday, March 1, 2019 6:38 PM
  • User1120430333 posted

    GOAL: to use the GET to return Symbol, Date, O,H,L,C,V data in either CSV or json format.

    Wait a minute, the default exchange data type is Json for WebAPI. So why is it that you are trying to beat CVS out of it if it's an either/or criteria you have specified and you can easily co to Json?

    Friday, March 1, 2019 6:41 PM
  • User-1668014665 posted

    .."You're not doing a Core based project. You could go to Nuget and install System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a into the project and set reference to it, the one that's being called for and see what happens."..

    I just selected project ASP net , check box WEB API then thats what I stated with.

    How do I unload "Microsoft.AspNet.WebApi.Core.5.2.7"..

    And reload System.Net.Http, Version=4.0.0.0 

    Maybe I start a NEW project and NOT Select WebAPI,, and then install 4.000 separately to build my own webapi from the ground up??

    Friday, March 1, 2019 6:42 PM
  • User-1668014665 posted

    .."Wait a minute, the default exchange data type is Json for WebAPI. So why is it that you are trying to beat CVS out of it if it's an either/or criteria you have specified and you can easily co to Json?"...

    ??????

    CSV is very useful in my world. 

    I have seen many API offering the choice of data return type json, csv or XML

    Friday, March 1, 2019 6:43 PM
  • User1120430333 posted

    I did that , and it makes no difference!
    I did check my project references my System.Net.Http is as stated above is 5.2.7, thats how it was imported when i loaded up the web api

    So you removed the above reference out of the project and you set refernce in the project to the 4.0 version?

    Secondly, how do you know the 4.0 DLL has the publickey token that matches the one the compiler is barking about?

    Friday, March 1, 2019 6:50 PM
  • User1120430333 posted

    .."Wait a minute, the default exchange data type is Json for WebAPI. So why is it that you are trying to beat CVS out of it if it's an either/or criteria you have specified and you can easily co to Json?"...

    ??????

    CSV is very useful in my world. 

    I have seen many API offering the choice of data return type json, csv or XML

    There is nothing wrong with CVS. But I sure as hell wouldn't be racking my brain over it in trying to get WebAPI to work with it, and I would take the path of least resistance. :) 

    Friday, March 1, 2019 6:55 PM
  • User475983607 posted

    I did check my project references my System.Net.Http is as stated above is 5.2.7, thats how it was imported when i loaded up the web api!

    Ah, that's an ASP.NET Core assembly.  I thought you were building a .NET 4.6 application.

    https://www.nuget.org/packages/Microsoft.AspNet.WebApi.Core/

     

    Friday, March 1, 2019 7:12 PM
  • User-1668014665 posted

    All I want is an Web API that sits on my server, with an IP address so I can GET API URL CSV or json data of SDOHLCV for APPL stock price

    Not azure, Not core

    WHat is my best plan of attack?

    Maybe go back to 4.5 Net or somethng

    Friday, March 1, 2019 7:15 PM
  • User-1668014665 posted

    icm63

    .."Wait a minute, the default exchange data type is Json for WebAPI. So why is it that you are trying to beat CVS out of it if it's an either/or criteria you have specified and you can easily co to Json?"...

    ??????

    CSV is very useful in my world. 

    I have seen many API offering the choice of data return type json, csv or XML

    There is nothing wrong with CVS. But I sure as hell wouldn't be racking my brain over it in trying to get WebAPI to work with it, and I would take the path of least resistance. :) 

    I want a CSV file on the end of a URL no extra steps after API GET call

    Friday, March 1, 2019 7:17 PM
  • User475983607 posted

    All I want is an Web API that sits on my server, with an IP address so I can GET API URL CSV or json data of SDOHLCV for APPL stock price

    Not azure, Not core

    WHat is my best plan of attack?

    Maybe go back to 4.5 Net or somethng

    4.6 is fine.  Simply create a new Web API project and make sure you select ASP.NET Web Application (.NET Framework) not ASP.NET Core Web Application.

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api

    Friday, March 1, 2019 7:20 PM
  • User-1668014665 posted

    I did that, but my MSVS 2017 install inputs CORE, I just did a test project, Yip Net framwork ASP , then check box WEBAPI 

    And let it setup, and YES system.web.http is version 5.2.2 from CORE

    Go figure!

    Friday, March 1, 2019 7:31 PM
  • User475983607 posted

    I did that, but my MSVS 2017 install inputs CORE, I just did a test project, Yip Net framwork ASP , then check box WEBAPI 

    And let it setup, and YES system.web.http is version 5.2.2 from CORE

    Go figure!

    You must be selecting the wrong project template.  

    Friday, March 1, 2019 7:42 PM
  • User1120430333 posted

    All I want is an Web API that sits on my server, with an IP address so I can GET API URL CSV or json data of SDOHLCV for APPL stock price

    Not azure, Not core

    WHat is my best plan of attack?

    Maybe go back to 4.5 Net or somethng

    You're using the Core template.

    You should be clicking on the Web node to select the path to creating an ASP.NET WebAPI 2 project. You must be looking at a Core tutorial or something

    Friday, March 1, 2019 8:44 PM
  • User-1668014665 posted

    This is the example I am following

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api

    And if you download the code and look in the packages.config you see this

    <packages>
      <package id="Microsoft.AspNet.WebApi" version="5.2.3" targetFramework="net46" />
      <package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net46" />
      <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net46" />
      <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.3" targetFramework="net46" />
      <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.3" targetFramework="net46" />
      <package id="Microsoft.Net.Compilers" version="1.3.2" targetFramework="net46" developmentDependency="true" />
      <package id="Newtonsoft.Json" version="6.0.4" targetFramework="net46" />
    </packages>

    <package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net46" />

    It install CORE by default, thus system.web.http is verison 5.2.3 and can not be 4.0.0.0

    You can uninstall it as CORE is required "Microsoft.AspNet.WebApi.WebHost"..

    SO BACK TO MY original question

    Can this code be tweaked and updated for 5.2.3 or 5.2.7 system.web.http

    In the Namespace CSVFormatters with this line

    SupportedMediaTypes.Add(New Headers.MediaTypeHeaderValue("text/csv"))

    I get an error when I build this to CHROME to use POSTMAN tool to check my controller GET call

    the error is

    Compiler Error Message: BC30652: Reference required to assembly 'System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' containing the type 'MediaTypeHeaderValue'. Add one to your project.

    I checked  my projects  system.net.http reference version and it is out of Microsoft.AspNet.WebApi.Core.5.2.7  , this is what MSVS loaded when I selected WebAPI (check box) while selecting the new ASP net project.

    So what is the fix?

    Does this help from Webconfig

    Friday, March 1, 2019 10:09 PM
  • User475983607 posted

    Something is not right.   You have the correct assemblies.   The System.Net.Http assembly is loaded from the GAC (Global Assembly Cache).  Maybe your machine is missing the project's target framework?

    https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/how-to-determine-which-versions-are-installed

    Open the project properties by right clicking the project file and selecting properties.  I assume you have 4.6.1 installed?  Make sure the target is correct.

    My project MSVS 2017, Vb net, Net 4.61, latest DLL imports from nuget,

    There is no need to NuGet the latest packages.  Skip the update step for now.

    Friday, March 1, 2019 10:48 PM