locked
MVC .NET C# - How to display my SOAP response in a MVC View from the generated proxy? RRS feed

  • Question

  • User1391845369 posted

    Step 1) I created a Webservice Reference in my MVC project called NemsisPmWsPort using the available WSDL,  https://perfmeasures.nemsis.org/perfMeasureWs.wsdl .    The reference document to this Webservice is located at:  

    https://nemsis.org/wp-content/uploads/2019/06/NEMSISV3PerformanceMeasureServiceTechnicalGuide.pdf

    Results 1) It auto generated a proxy reference library with all the exposed classes, methods and properties which is contained in the Reference.cs file.

    Step 2) Next, I created a controller called,  NEMSISmeasuresWSRController.cs.  In the controller I wrote some request code to request "RetrieveBenchmarkRequest".   I used the requested SOAP code that was given on the reference document and the new proxy library references that was created,  write the following code.   Also I provided the SOAP request code that is give in the reference document link.  I kinda of stumbled my way through it.

    SOAP request example given in the reference document:

    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.nemsis.org/"> 
    <soapenv:Header/> 
    <soapenv:Body> 
    <ws:RetrieveBenchmarkRequest> 
    <ws:benchmark id="Trauma-01" /> 
    </ws:RetrieveBenchmarkRequest>
    </soapenv:Body>
    </soapenv:Envelope>

    My code in controller NEMSISmeasuresWSRController.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Data;
    using NEMSIS.PerformanceMeasures.Models;
    using System.Xml;
    
    namespace NEMSIS.PerformanceMeasures.Controllers
    {
        public class NEMSISmeasuresWSRController : Controller
        {
            // GET: NEMSIS Webservice data
            public ActionResult Index()
            {
           
                using (var client = new NemsisPmWsPort.NemsisPmWsPortClient())
                {
                    //This block of code gets me all the data I need, 
    //but not sure how to get a handle on it and display it in a view. var request = new NemsisPmWsPort.RetrieveBenchmarkRequest(); request.benchmark = new NemsisPmWsPort.BenchmarkRequest(); request.benchmark.id = "Trauma-01"; var response = client.RetrieveBenchmark(request); } return View("Home"); } } }

    Results 2) I was able to get a handle on all the data.  This is were my lack of experience is holding me back.   I need to be able to grab the data items in the results array,  called "numerator" and "denominator" especially,  plus any other data like "databaseUpdateDateTime" and "database records"  .  I have played around with some code but I am totally clueless. 

    Step 3) I need to display the following data explain in Results 2 in a view.  Can any one get me on the right track please?   The SOAP results code from the link reference document is:

    The service will return a message that contains the benchmark data in numerator/denominator form as defined by EMS Compass, along with some metadata.  I am not sending a direct SOAP request, I am doing it through the proxy reference. 

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:ns2="http://ws.nemsis.org/">   
    <SOAP-ENV:Header/>   
    <SOAP-ENV:Body>     
    <ns2:RetrieveBenchmarkResponse>       
    <ns2:database>         
    <ns2:databaseUpdateDateTime>2019-06-01T12:12:28.510-06:00         </ns2:databaseUpdateDateTime>         
    <ns2:databaseRecords>23821188</ns2:databaseRecords>       
    </ns2:database>       
    <ns2:benchmark id="Trauma-01"/>       
    <ns2:data denominatorType="xs:nonNegativeInteger" numeratorType="xs:nonNegativeInteger" records="3149842" states="45">         
    <ns2:result records="3149842">           
    <ns2:numerator>1732451</ns2:numerator>           <ns2:denominator>3149842</ns2:denominator>         
    </ns2:result>       
    </ns2:data>     
    </ns2:RetrieveBenchmarkResponse>   
    </SOAP-ENV:Body> </SOAP-ENV:Envelope>

    Thursday, August 22, 2019 5:28 PM

All replies

  • User1120430333 posted
    A SOAP response is just XML. You can load the response into a XMLdocument and use Linq2XML to access the data.
    https://www.dotnetcurry.com/linq/564/linq-to-xml-tutorials-examples
    Thursday, August 22, 2019 6:01 PM
  • User475983607 posted

    The response is here...

    var response = client.RetrieveBenchmark(request);

    Which is of some unknown type.

    In other words response is the model.  Simply pass the model to the View.

    return View("Home", response);

    In the "Home" View define the model that's being passed at the top.  I'm not sure of the type but you have this information.

    @model NemsisPmWsPort.RetrieveBenchmarkResponse

    Drill into the data like you would any model (object) within the View.

    <div>@Model.SomePropertyThatYouWantToSee</div>

    It might be a good idea to go through a few MVC getting started tutorials so you understand the fundamentals of passing a model to a View.

    https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/introduction/getting-started

    Thursday, August 22, 2019 6:10 PM
  • User1391845369 posted

    Great Advice, I will take a stab at this and respond back! 

    Thursday, August 22, 2019 10:01 PM
  • User1391845369 posted

    I am actually not sending the physical Soap request that you see in my post.  I am using the proxy model to pull my data.  If I was getting a raw Soap response I believe this method would be ideal?  Not sure me statement is totally correct because I am still a little green around the gills.  

    Thursday, August 22, 2019 10:04 PM
  • User1391845369 posted

    So I believe I am almost there but I have a slight problem I can not figure out. 

    So I created a view and in this view I have:

    @using NEMSIS.PerformanceMeasures.NemsisPmWsPort;
    @model Result
    @{
        Layout = null;
    }
    @{
        ViewBag.Title = "View";
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    <!DOCTYPE html>
    
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title>NEMSIS Web Service Page</title>
    </head>
    <body>
        <form method="post" name="Display">
            <h2>NEMSIS Web Service Page</h2>
    
            <br />
    
            <table border="1">
                <thead>
                    <tr>
                        <td>
                            NEMSIS Caps
                        </td>
                        <td>
                            Numerator
                        </td>
                        <td>
                            Denominator
                        </td>
                        <td>
                            Percentage Rate
                        </td>
                    </tr>
                </thead>
                <tr>
                    <td><b>Seizure-01</b></td>
                    <td>@Model.numerator </td>
                    <td>@Model.denominator  </td>
                    <td>  </td>
                </tr>
            </table>
            <br />
    
        </form>
    </body>
    </html>  

    and my newest controller script:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.Data;
    using NEMSIS.PerformanceMeasures.Models;
    using System.Xml;
    //using NEMSIS.PerformanceMeasures.NemsisPmWsPort;
    
    namespace NEMSIS.PerformanceMeasures.Controllers
    {
        public class NEMSISmeasuresWSRController : Controller
        {
             
            public ActionResult Index()      {
    
                
                
                using (var client = new NemsisPmWsPort.NemsisPmWsPortClient())
                {
                     
                    var request = new NemsisPmWsPort.RetrieveBenchmarkRequest();
                    request.benchmark = new NemsisPmWsPort.BenchmarkRequest();
                    request.benchmark.id = "Trauma-01";
                                
                    var response = client.RetrieveBenchmark(request);            
                    return View("Home", response);
    
                }                                    
    
                                       
            }
    }
    }
           

    I am able to see the fields from the result model class but I am getting a error:

    The model item passed into the dictionary is of type 'NEMSIS.PerformanceMeasures.NemsisPmWsPort.RetrieveBenchmarkResponse', but this dictionary requires a model item of type 'NEMSIS.PerformanceMeasures.NemsisPmWsPort.Result'.

    Friday, August 23, 2019 3:34 PM
  • User475983607 posted

    The error is telling you that you defined the View's model as...

    @model NEMSIS.PerformanceMeasures.NemsisPmWsPort.Result

    but you passed the type...

    NEMSIS.PerformanceMeasures.NemsisPmWsPort.RetrieveBenchmarkResponse

    to the View.

    return View(result)

    Here, result is a type of NEMSIS.PerformanceMeasures.NemsisPmWsPort.RetrieveBenchmarkResponse

    I recommend stopping the usage of "var" and start using the actual type so you can better keep track of the types you are using.  

    Friday, August 23, 2019 3:43 PM
  • User1391845369 posted

    So you are saying convert the data type before I pass it to the view?

    Friday, August 23, 2019 4:43 PM
  • User475983607 posted

    steven0608

    So you are saying convert the data type before I pass it to the view?

    I'm did NOT recommending a type conversion.    The rule is very simple.  The Type passed to the View must match the View's defined type.  If you need to populate a different type to get the View working as expected then do so.  

    Friday, August 23, 2019 5:06 PM
  • User1391845369 posted

    OK I am a little lost, I am reality new to C# and .NET MVC so a little more information or direction would be great.   I have tried a few things but I am totally in the dark at this point.   Everything up to this point make perfect sense. 

    Friday, August 23, 2019 8:33 PM
  • User1520731567 posted

    Hi steven0608,

    Vs automatically generates the RetrieveBenchmarkResponse class via wsdl to represent the message returned by the web serviece.

    But between the RetrieveBenchmarkResponse class and the result you need to use, you need to do a mapping.

    Best Regards.

    Yuki Tao

    Monday, August 26, 2019 5:24 AM
  • User1391845369 posted

    OK so what do you mean by mapping and yes I see the RetriveBenchmarkResponse class with the data in it when I use debug.

    Monday, August 26, 2019 2:43 PM
  • User1391845369 posted

    So since I am new at C#, I am not sure how to map/grab the data from the response var that I created.  If you could get me start in the direction needed that would be great. 

    Monday, August 26, 2019 4:40 PM
  • User475983607 posted

    steven0608

    So since I am new at C#, I am not sure how to map/grab the data from the response var that I created.  If you could get me start in the direction needed that would be great. 

    We cannot answer this question as we cannot see your code but mapping values is very easy.

    MyObject.PropertyName = MyOtherObject.PropertyName;

    Do this for each and every property you wish to map.  

    Monday, August 26, 2019 5:27 PM
  • User1391845369 posted

    Well I kind of know what you are talking about but the value I want to get is about 3 levels deep.   Not sure how to get to it.  I tried to upload a image of my response data but it want let me browse.  Is there away to upload an image?

    Monday, August 26, 2019 6:47 PM
  • User475983607 posted

    Well I kind of know what you are talking about but the value I want to get is about 3 levels deep.   Not sure how to get to it.  I tried to upload a image of my response data but it want let me browse.  Is there away to upload an image?

    Accessing a property three levels deep is not difficult.

    var theValue = object.subclass1.subclass2.propertyName

    You need a working knowledge of types to program in C#. 

    What's puzzling, is you have the SOAP service response.  All you have to do is pass the response to the View as illustrated above.  Then use dot notation to drill into the object to display the items you wish to display. 

    Monday, August 26, 2019 7:15 PM
  • User1391845369 posted

    Oh my goodness, that makes sense now.  Thank you!!!!

    Monday, August 26, 2019 7:17 PM
  • User1391845369 posted

    OK so I think I am understanding this more now, I need to create a view model then set those objects to the objects from the response then display the object model with the new object/properties. 

    Monday, August 26, 2019 7:35 PM
  • User475983607 posted

    OK so I think I am understanding this more now, I need to create a view model then set those objects to the objects from the response then display the object model with the new object/properties. 

    That works too.   Using a ViewModel is a stand MVC pattern and especially useful if you only have a subset of data you wish to display or update.

    Monday, August 26, 2019 8:01 PM