dcsimg
Results 1 to 28 of 28

Thread: trying to call a service manually

  1. #1

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    trying to call a service manually

    Hi.
    I am able to call a service manually by doing:
    Code:
         Try
            
    
                Dim request1 = DirectCast(WebRequest.Create("https://xxx.xxx/WSVistaWebClient/OData.svc/Cinemas"), HttpWebRequest)
          
    
              '''  request.Credentials = New System.Net.NetworkCredential("vie", "g3")  '' this service do not use credentials 
    
                'request.Credentials = CredentialCache.DefaultCredentials
                Dim response As WebResponse = request.GetResponse()
    
                Dim dataStream As Stream = response.GetResponseStream()
    
                Dim reader As New StreamReader(dataStream)
                ' Read the content.  
                Dim responseFromServer As String = reader.ReadToEnd()
                ' Display the content.  
                Console.WriteLine(responseFromServer)
                ' Clean up the streams and the response.  
                reader.Close()
                response.Close()
    
            Catch ex As Exception
    
            End Try
    However since this is a REST call I'm try other way that does not work at all.
    Can you please correct on what I'm doing wrong?

    Code:
    '1st try
     Try
                Dim host As WebServiceHost = New WebServiceHost(GetType(ServiceReference2.Cinema), New Uri("https://xxx.xxx/WSVistaWebClient/OData.svc/Cinemas"))
                Dim ep As ServiceEndpoint = host.AddServiceEndpoint(GetType(ServiceReference2.Cinema), New WebHttpBinding(), "")
                host.Open()
            Catch ex As Exception
    '''' "The contract type WindowsApplication1.ServiceReference2.Cinema is not attributed with ServiceContractAttribute.  In order to define a valid contract, the specified '''   type (either contract interface or service class) must be attributed with ServiceContractAttribute."
    
            End Try
    2nd try:

    Code:
        Dim Binding As BasicHttpBinding = New BasicHttpBinding()
            Dim address As EndpointAddress = New EndpointAddress("https://xxx.xxx/WSVistaWebClient/OData.svc/Cinemas")
    
    
            Dim factory1 As EndpointAddress = New EndpointAddress("https://xxx.xxx/WSVistaWebClient/OData.svc/Cinemas")
    
            Try
                Dim client As ServiceReference2.Cinema = ChannelFactory(Of ServiceReference2.Cinema).CreateChannel(Binding, address)
            Catch ex As Exception
    '''"The type argument passed to the generic ChannelFactory class must be an interface type."
            End Try
    Any help?
    Slow as hell.

  2. #2

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    I mean.
    Sure interface types but how can I get that?
    The service itself does not have anything.
    Or I must simulate p.e. an ServiceReference2.Cinema.City as ServiceReference2.Cinema.Icity ??
    Slow as hell.

  3. #3
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,580

    Re: trying to call a service manually

    The two "new" things you have tried aren't for calling web services. They are for hosting web services. That is when you are the web service and you want other people to call you.

    They are part of WCF, which is a whole topic in and of itself that requires a good bit of book learning. Like most of Microsoft's frameworks, it's very heavily XML-based and most humans have to pay for tools to use it. You can probably write something that uses WCF to call web services, but:
    • Most .NET developers just import a package like RestSharp.
    • Everyone else uses HttpWebRequest or something like HttpClient or WebClient.


    REST is just HTTP. You don't need to be fancy to use it.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  4. #4

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    Hi.
    I was quite familiar with WCF (wrote some articles here on how to use it and bypass CORS and had a web site using full WCF with interfaces) but you are right that I was creating the WCF service myself and now I need to call it. The problem is that some WCF services that they send me, cannot be added as a service reference because they need username and password.
    When I try to add them as a service reference they fail. They do work as HttpWebREquests so if that is the way to go then OK.
    Btw, is there any way to add them as service reference and somehow stick the password and username in there? Something like https://username:password@xxx.xxx/WS...ta.svc/Cinemas ?
    Something like that? Haven't tried .
    Last edited by sapator; Jan 23rd, 2018 at 10:57 AM.
    Slow as hell.

  5. #5

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    Or maybe setting something on app.config like Transport security so I can add the damn thing and then use credentials.
    Buhhh.
    And why I remember that when I imported my WCF I was poped up to ender my credentials? Or mayby I don't recall correctly as that service was made a couple of years ago...Hmmm.
    Slow as hell.

  6. #6
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,580

    Re: trying to call a service manually

    You'll need to find some kind of WCF mentor to walk you through configuring it. Maybe ask on StackOverflow.

    That you need to read a manual to interact with a REST service is precisely why I haven't bothered to even look at WCF.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  7. #7

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    If I have to do so then I would prefer to talk to the company that created the service.
    I didn't want to do so because it's a big multinational company and their support is very very slow but I guess that is the way to go.
    Thanks.
    Slow as hell.

  8. #8
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    31,885

    Re: trying to call a service manually

    Are you *SURE* they gave you a WCF endpoint? You said that "They do work as HttpWebREquests"... which leads me to believe it's not a Web Service you can reference, but rather a Web API endpoint that you consume by invoking it through an HTTP request and sending/receiving the data through JSON objects.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  9. #9
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,580

    Re: trying to call a service manually

    Why do you think you need to use WCF?

    If you have working code, why are you trying to use something that doesn't work?
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  10. #10

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    A Service with .svc extension could be a Web API?
    Anyhow it is a WCF service.

    Name:  Clipboard01.jpg
Views: 141
Size:  43.9 KB

    I "need" to use WCF because if you import the service you get all of it's methods ready to go. you do not have to webRequest each method every time you need it.
    I also do not like WCF complexity, especially setting the configuration files is a nightmare that I had to deal with when I created WCF services but I get all the method in a robust namespace.
    Slow as hell.

  11. #11
    Fanatic Member PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Newport, UK
    Posts
    875

    Re: trying to call a service manually

    Quote Originally Posted by sapator View Post
    A Service with .svc extension could be a Web API?
    Anyhow it is a WCF service.

    Name:  Clipboard01.jpg
Views: 141
Size:  43.9 KB

    I "need" to use WCF because if you import the service you get all of it's methods ready to go. you do not have to webRequest each method every time you need it.
    I also do not like WCF complexity, especially setting the configuration files is a nightmare that I had to deal with when I created WCF services but I get all the method in a robust namespace.
    If you know it is a WCF service then why are you wanting to call it manually? If you add it as a service reference then you get a strongly typed wrapper around the service and it should also sort out the configuration files for you as well.

    If you only want to manage the configuration in code then https://docs.microsoft.com/en-us/dot...rvices-in-code is worth a read.

  12. #12

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    This one is password free.
    They have locked the other services with passwords and I cannot find a way to add a service reference with a password. Also it does not prompt for credentials when I add the service reference.
    I could only set credentials in webrequest . I also try to use https://usernameassword@xxx.xxx/WS...ta.svc/Cinemas trick with no avail.
    Slow as hell.

  13. #13
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    31,885

    Re: trying to call a service manually

    So I entered this into google:
    calling a password protected WCF service

    and got this:
    First create a WCF service library in Visual Studio.
    Then create a WCF service application in Visual Studio.
    Then we need to configure the web.config for the service binding, security mode and username/password authentication. ...
    Now our service is ready.
    Which came from this:
    http://www.c-sharpcorner.com/UploadF...n-wcf-service/

    Complete Google result:
    https://www.google.com/search?q=call...ed+WCF+service

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  14. #14

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    Hi.
    The sole issue is that all these examples require (even if they do not specify it) to add a service reference.
    After you add a service reference you can pass the credentials and configure the application or web.config files
    what you posted show how to add credential on the server side. As this is not my service, the whole first security section is irrelevant.
    The client call (that i need to initial) is step 4 of the example, the 3-4 lines of code.

    Also the service when added is a real pain to set up with Transport.
    I have found a WCF service I created. Got the goosebumps remembering the pain it is to go through.
    Here is the transport binding (with certificate) that I used on the Server Side(1/3 of the whole configuration file).

    Code:
    <bindings>
          <basicHttpBinding>
            <binding name="defaultBasicHttpBinding" sendTimeout="00:25:00"
              maxReceivedMessageSize="3000000">
              <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
              <security mode="Transport">
                <message clientCredentialType="Certificate" />
              </security>
            </binding>
            <binding name="defaultBasicHttpBindingInfo" sendTimeout="00:25:00"
              maxReceivedMessageSize="3000000">
              <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
              <security mode="Transport">
                <transport clientCredentialType="Certificate" />
              </security>
            </binding>
            <binding name="TicketingService" sendTimeout="00:05:00" maxReceivedMessageSize="3000000">
              <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647"
                maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
            </binding>        
          </basicHttpBinding>
        </bindings>
    So what we are doing here is creating a certificate enabled Service.
    Now. In order for the CLIENT(aka poor me) to get this service, we need to first add a service reference . After that we get a certificate warning (if it's a temp certificate), or, I presume, a username password prompt, or nothing, just adds and set credentials in code. So if we do that , then, and only then we can say that we can follow the posted example, as this will initiate a new service reference (aka the name you have added the service) and we can just use it if we have a certificate or add credentials or anything else.
    Slow as hell.

  15. #15
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    31,885

    Re: trying to call a service manually

    My bad... on the first read, it sounded like you needed to modify the config file for your app, adding the security context for it. I see now that's for the server side. Might be worth taking a look at some of the links in the results though, because a few links later is this one:
    http://codebetter.com/petervanooijen...on-t-tell-you/
    Part way down on that page is this:
    The client
    To consume this service add a service reference in the client. The mexHttpBinding in the service configuration enables to read all metadata form the service without any credentials.

    Setting up a connection to the client requires some fiddling. Again not all of these settings are clear by default.

    var endPoint = new EndpointAddress(new Uri(Farm.FarmUrl), EndpointIdentity.CreateDnsIdentity("Farm"));

    var binding = new WSHttpBinding();

    binding.Security.Mode = SecurityMode.Message;

    binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;



    var result = new CustomerDeskOperationsClient(binding, endPoint);

    result.ClientCredentials.UserName.UserName = Farm.FarmUserName;

    result.ClientCredentials.UserName.Password = Farm.FarmPassword;

    First we need an endpoint. This is assembled from the url in the client’s configuration, here a constant Farm.FarmUrl. For the custom username authentication to work the endpoint also needs an EndpointIndentity. According to the sparse msdn documentation this is to prevent phishing. The fact that the identity was needed and the parameter had to be the certificate’s name was suggested by the WCF error messages.

    The security is set according to the security settings we have seen in the service. Both the username and password are set in UserName property of the ClientCredentails.
    Hmmmm.... Looks like you'll also need to know the serviceCertificate which you would need to get from the WCF owners... Of course, this assumes they have followed everything from the top down to the CLIENT section.
    If that's still not working... you might need to contact the endpoint owners and find out from them how you're supposed to connect. I've only used WCF internally, and that was 6 years ago... Most things lately are Web API-based and work differently in their security.

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  16. #16

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    I have contacted the company 2 days now and still I'm on their level 1 support.
    So we first get a level one support that needs to understand the requirements then we probably be forwarded to the main support tank that will evaluate the department to forward to and where. After that the department will evaluate if it can be resolved internal or need to go abroad . I know for a fact that the development department of them is hosted abroad, so this will go abroad, then the abroad support department will evaluate the request, will send it to their main support tank. The support tank will forward this to the general IT department, the department will evaluate the situation and send it to the specific development department, the development department will send it to the developers and get a solution.
    If they need more clues on the question or even worst if they need clues for the original question then , vrooooommmmm all the way up to the local and foreign departments to get to the support I'm currently talking to and then vrooooommmmm all the way down again. If this requires (the particular i suppose does not) an extra budget to fix, then in order to get a billing value they must contact their accounting department and it must go through levels to understand the requirement and set a price.Then aaallll the way up to their main accounting man for the Hellenic support marker, that we luckily can contact by phone to get a price. If we need to bargain the price then vrooooommmm all the way down to accounting managers IT managers etc etc.It's getting boring.

    So here is how our multinational company works in contrast of this chain above. I pick up the phone, dial directly to the department I need to and I get the answer.
    Slow as hell.

  17. #17

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    So No answer yet from their part.
    Anyhow I am able to call their methods with WebRequest.
    I had an issue because some methods require a POST and Json string. Funny enough not many solid examples out there and everything in C# , I had to convert myself.
    Posting this for reference. Note that you can use JavaScriptSerializer, I have a question here for inner Json strings and how to get them.
    first the example:
    Code:
     Dim requestJ = DirectCast(WebRequest.Create("https://xxx.xxx/WSVistaWebClient/RESTLoyalty.svc/member"), HttpWebRequest)
            requestJ.ContentType = "application/json"
            requestJ.Method = "POST"
            ''''Header if applicable
            '''''' requestJ.Headers.Add("token", "xc")           
         
            Try
    'Random session , Client
                Using streamWriter As New StreamWriter(requestJ.GetRequestStream())
                    Dim json As String = "{""userSessionId"":""c0e5c52508a44b1dabf41367e6b9a8b7""," +
                     """OptionalClientName"":""C1""}"
                    streamWriter.Write(json)
                    streamWriter.Flush()
                    streamWriter.Close()
                End Using
            Catch ex As Exception
    
            End Try
            Dim responseJ As WebResponse
            Dim responseFromServerJ As String
            Try
                responseJ = requestJ.GetResponse()
                Using readerJ As New StreamReader(responseJ.GetResponseStream())
                    responseFromServerJ = readerJ.ReadToEnd()
                End Using
            Catch ex As Exception
    
            End Try
    That seems to work.
    Now I have a question on JavaScriptSerialize

    Code:
     Dim Json As String = New JavaScriptSerializer().Serialize(New With {Key .userSessionId= "c0e5c52508a44b1dabf41367e6b9a8b7", Key .OptionalClientName= "C1"})
    That is ok for on level Json but what if we have multiple levels?
    Code:
     "LoyaltyMember": {
        "MemberId": "string",
        "FirstName": "string",
        "LastName": "string",
        "FullName": "string",
        "CardNumber": "string",
        "MobilePhone": "string",
        "HomePhone": "string",
        "Email": "string",
        "ClubID": "string",
        "BalanceList": [
          {
            "BalanceTypeID": "string",
            "Name": "string",
            "Message": "string",
    ]
    In here we have a LoyaltyMemeber and inside Firstname, lastname etc and also inside a BalanceList with a collection of data.
    Is there an easy way to pass this to a Json string with JavaScriptSerializer ?

    Should probably start a new thread but I just merged it with the WebRequest, so maybe we can have a full example here.

    Thanks.
    Slow as hell.

  18. #18
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,580

    Re: trying to call a service manually

    You shouldn't think of JSON as a String. It is an "object representation". So is XML, it's just wordier. It came from JavaScript, because in that language you can create entire class hierarchies out of JSON literals. So we like to work with JSON in two ways:
    1. "Get me the object this String represents."
    2. "Convert this object to its JSON representation."


    This is more of a hassle in .NET than it is in JavaScript because of "strong typing". Javascript is happy to let you create "an object" and add/remove properties on the fly. You never have to tell JavaScript up-front what something is. Some people don't like that, and for a long time developers didn't understand what kind of techniques could make that safe. So .NET is "strong typed", which means before you can use any object you have to tell the compiler exactly what properties and methods it has. That means we can't use JSON willy-nilly, we need to make objects so JSON libraries can convert them to JSON.

    So this line is actually doing that:
    Code:
     Dim Json As String = New JavaScriptSerializer().Serialize(New With {Key .userSessionId= "c0e5c52508a44b1dabf41367e6b9a8b7", Key .OptionalClientName= "C1"})
    The "New With" syntax is using a feature called "anonymous types" to look like it's conjuring an object out of thin air. It's not, though. The compiler reads your object syntax and generates a class behind-the-scenes for you.

    Objects in VB .NET translate to JSON in a very, very straightforward way. The anonymous type you wrote ends up looking like this:
    Code:
    Class Anonymous_1
        
        Public Property userSessionId As String
        Public Property OptionalClientName As String
    
    End Class
    So what your code snippet really does is:
    Code:
    Dim invisibleObject As New Anonymous_1()
    invisibleObject.userSessionId = "c0...b7"
    invisibleObject.OptionalClientName = "C1"
    New JavaScriptSerializer().Serialize(invisibleObject)
    A property in JSON can be a number, string, array, or object. In general, that's what .NET types can do as well. So when you see this in JSON:
    Code:
    { 
        "someProperty": {
            "innerProperty": 10
        }
    }
    That translates to "two VB classes, one of which has a property with the other type." It looks like this:
    Code:
    Class Example1
        Public Property someProperty As Example2
    End Class
    
    Class Example2
        Public Property innerProperty As Integer
    End Class
    And we can create the object with VB code that looks vaguely JSON-like:
    Code:
    Dim example As New Example1() With {
        .someProperty = New Example2() With {
            .innerProperty = 10
        }
    }
    The example JSON you posted isn't quite valid, but I assume you shortened it for simplicity. It would be a VB object hierarchy that looks something like this:
    Code:
    Public Class Root
        Public Property LoyaltyMember As LoyaltyMember
    End Class
    
    Public Class LoyaltyMember
        Public Property MemberId As String
        ...
        Public Property BalanceList() As Balance()
    End Class
    
    Public Class Balance
        Public Property BalanceTypeID As String
        Public Property Name As String
        Public Property Message As String
    End Class
    The JSON indicates the BalanceList property is an "array of objects". So that's what the BalanceList property I wrote is: an array of an object I named "Balance", with all the properties you showed me.

    I'm not familiar with JavaScriptSerializer. Professional .NET developers got used to the Newtonsoft JSON package because MS spent about 10 years ignoring JSON, and when they did implement parsers they had bugs. Now MS has admitted that yes, JSON is relevant, and made a good effort. But people are used to Newtonsoft.

    My guess is JavaScriptSerializer works very similar though. Give it an object, you get a JSON representation in a String. So if you build a proper 'Root' object from the class hierarchy I demonstrated, you ought to get the JSON you need.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  19. #19

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    I'm used to pass Json from html , markup but not from a form.
    I have used Newtonsoft to translate xml to Json and it works fine but I rarely pass Json from winforms to a webservice.
    Thanks for the example.
    What I need to do would probably be do build the Json on the fly.So I do not think I can create a class because I would need a couple of thousand classes to get all the combinations.
    It's either creating a string object like the first example or try to find if Newtonsoft .
    What I was thinking was to have the basic json object - string as text and in accordance to what the user need to use , I will remove part of it in text.
    The second option would be to fully create it as a class representation. Now I'm not sure how would I go, and not using class properties will actually remove them from the final class representation that will be passed to Newtonsoft . If the second thought is doable, maybe I will use that approach. The first thought is doable, for the second, hmm, i suppose something like this might work? https://www.newtonsoft.com/json/help...onManually.htm
    I will need to test it when I get past the web service calls and have some time in my hands.
    Slow as hell.

  20. #20

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    OK.
    So for now I am re-creating the json to vb classes and after I pass the values, i serialize the object to Json. It seems to accept null values so I don't have to remove the not needed properties.
    This was exactly what I was trying to avoid as service reference will give you an already made parent class with all the properties. Now I have to go in each and every one and translate it from json to classes. Will probably take me a month
    Slow as hell.

  21. #21
    Fanatic Member PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Newport, UK
    Posts
    875

    Re: trying to call a service manually

    Quote Originally Posted by sapator View Post
    OK.
    So for now I am re-creating the json to vb classes and after I pass the values, i serialize the object to Json. It seems to accept null values so I don't have to remove the not needed properties.
    This was exactly what I was trying to avoid as service reference will give you an already made parent class with all the properties. Now I have to go in each and every one and translate it from json to classes. Will probably take me a month
    Could you not add it as a service reference and use the classes it generates? There is a command line tool SvcUtil.exe that could also be used to generate the classes, basically it does the same as adding a service reference.

    Would that not work as a starting point?

  22. #22
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,580

    Re: trying to call a service manually

    Welcome to the downside of using statically-typed languages like VB .NET. If you want to use a type at all, it has to be defined up-front. If you were using a dynamically-typed language like JavaScript, Python, or Ruby, you could build your objects on the fly and avoid this tedium.

    That's why things like WCF exist: in a language like VB .NET, if your API is sprawling and defines more than a few types it can take a lot of effort to generate the JSON classes for interacting with it. WCF promises to be able to generate those. It's great, if the API implementor's done whatever they need to do to help your code work with it. But when it doesn't work, it doesn't work.

    C# has some handy features in VS 2017 where you can paste JSON into the window and it will automatically convert it to a class. This website seems to do the same thing for a host of languages. PlausiblyDamp's suggestion sounds plausible, too.

    You could use something like ExpandoObject with the Dynamic Language Runtime to maybe fill in the gaps. In a pinch, most libraries (Newtonsoft included) support a Dictionary(Of String, Object) in lieu of objects. Or you could use the samples you found to manually build up things Newtonsoft can interpret as JSON types. This approach is still fairly tedious, because algorithmically generating "the right types" still involves describing "right" to your program.

    I'd love to help you with WCF, but it's just not a popular enough technology for me to have ever given it a shot. In general, when I've had to use a complex API, I go find a NuGet package where someone else has already done the work of generating classes. If you're paying for access to whatever API this is, that company really should be helping you succeed.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  23. #23
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    31,885

    Re: trying to call a service manually

    Quote Originally Posted by PlausiblyDamp View Post
    Could you not add it as a service reference and use the classes it generates? There is a command line tool SvcUtil.exe that could also be used to generate the classes, basically it does the same as adding a service reference.

    Would that not work as a starting point?
    Normally, yes... that's what he's done in the past... but now the service is hiding behind a wall requiring login authentication which apparently is preventing the ability to do this. I suspect what has happened is the owners of the endpoint found their services being abused or the target of unauthorized use... and so they've done a conversion to a Web API of some kind requiring authentication... so of course that changes how those who legitimately call it work. And that's the point at which we are at... I though we covered this already...

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  24. #24
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,580

    Re: trying to call a service manually

    Yeah I think we're at a point where I understand why OP wants to use WCF, but none of us know why they can't get through the authentication barrier to use the WCF service. That's probably something the owner of the service can answer, and we don't really have a critical mass (or possibly any) WCF experts here. Maybe on StackOverflow?
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  25. #25
    Fanatic Member PlausiblyDamp's Avatar
    Join Date
    Dec 2016
    Location
    Newport, UK
    Posts
    875

    Re: trying to call a service manually

    Quote Originally Posted by techgnome View Post
    Normally, yes... that's what he's done in the past... but now the service is hiding behind a wall requiring login authentication which apparently is preventing the ability to do this. I suspect what has happened is the owners of the endpoint found their services being abused or the target of unauthorized use... and so they've done a conversion to a Web API of some kind requiring authentication... so of course that changes how those who legitimately call it work. And that's the point at which we are at... I though we covered this already...

    -tg
    I was thinking that if the endpoint was still allowing him to build the classes it was going to be easier than building them by hand. Then again if they have gone to a restful API they might have a swagger endpoint that could be helpful.

  26. #26

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    Hi.
    Yes the main idea was to use the WCF so I don't have to redo the whole thing.
    Fortunately they have all the Json in-out for the web services so I was using this tool https://jsonutils.com/ , that I saw that you also recommended, to get Json to Classes.
    Seems to work, although the tool will not create the classes as a Dictionary Of , will just go with array() . That is OK i guess, I can pass the arrayObjects{} .
    The issues here is that they probably have 100 service "Operations" as they call them, than needs to be translated.
    We might not like WCF but you saved a lot of trouble in a situation like this. Also if they make a change somewhere then we need to go and fix things manually, in contrast with WCF that you just did a refresh.
    Oh ,well...
    Last edited by sapator; Jan 29th, 2018 at 05:27 AM.
    Slow as hell.

  27. #27
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,580

    Re: trying to call a service manually

    JSON doesn't natively support Dictionary. In JavaScript, dictionaries and objects are the same thing. So it's expected that instead of a Dictionary(Of ???), you would get an object of some type from JSON. Or at least I'd hope.

    Can you show some JSON that isn't converting well? We could tell you how to iron out that wrinkle, or at least verify you found a case where you need a dictionary.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  28. #28

    Thread Starter
    King of sapila
    Join Date
    Oct 2006
    Location
    Greece
    Posts
    5,378

    Re: trying to call a service manually

    Hey.
    No there is no problem in a couple of classes I tried to translate with the tool.
    I get valid Json.
    What I mean is that , p.e. , this:
    Code:
    {
      "Member": {
        "MemberId": "string",
     "BalanceList": [
          {
            "BalanceTypeID": "string"
    }
    ]
    }
    }
    will translate (roughly, I cut out a couple of hundred of declarations) to this:

    Code:
      Public Class Member
            Public Property MemberId As String
             Public Property BalanceList As BalanceList()
      End Class
    
      Public Class BalanceList
            Public Property BalanceTypeID As String
      End Class
    So then I should create an object of type balancelist 'BX' and pass it to an object of type Member as Member.Balancelist = {BX}
    Last edited by sapator; Jan 30th, 2018 at 05:59 AM.
    Slow as hell.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width