2

In my MVC view (using VS 2012 RC), I'm attempting to parse the XML freshly returned from my Controller. Here is my view code:

@model RzMvc.Models.PortfolioResponse
@{
    ViewBag.Title = "PortfolioList";
}              

<script type="text/javascript">

    $(displayXmlResponse);

    function displayXmlResponse(){
        var resp = $("#xmlResp");
        $("#xmlTest").append(resp.children());

        var xml = $("xmlResp").text;      
            xmlDoc = $.parseXML(xml),
            $xml = $(xmlDoc),
            $title = $xml.find("portfolioSummary");            

        $("#xmlTest").append($title.text());      
    }    

</script>

<h2>PortfolioList</h2>

<div>
    <p id="xmlTest"></p>
    <p id="xmlResp" >@Model.XmlPortfolioResponse</p>    
</div>

The browser output looks like this:

PortfolioList

Portfolio Listing

System.Xml.XmlDocument

Any guidance would be greatly appreciated. Here's part of my Controller code:

    public ActionResult PortfolioList()
{
    XmlDocument xmlResponse = new XmlDocument();
    xmlResponse.LoadXml(portfoliosResponse);
    var portf = new PortfolioResponse { XmlPortfolioResponse = xmlResponse };


    return View(portf);
}

Model code is:

namespace RzMvc.Models
{

    public class PortfolioResponse
    {
        public XmlDocument XmlPortfolioResponse { get; set; }
    }
}
1
  • This has nothing to do with JavaScript (jQuery) at all. You'll have to process the XML data either in your View with C# code (bad idea, I don't like it) or, better way, some kind of repository should return decent objects, with the XML file as data source. Commented Jun 25, 2012 at 21:15

3 Answers 3

1

The problem is that you are returning a PortfolioResponse object, but setting the value of its XmlPortfolioResponse property to be equal to the XmlDocument itself, rather than it's output. This makes the default C# output when you bind to the screen occur - which is to simply call PortfolioResponse.XmlPortfolioResponse.ToString() - which will, unless overloaded, return the name of the Object's class. Hense - you are getting System.Xml.XmlDocument output to your HTML.

What you need to do, first and foremost, is bind @Model.XmlPortfolioResponse.OuterXml to your view page, rather than @Model.XmlPortfolioResponse. You will also most likely have to wrap this value in a @Html.Raw() call in order to get it to actually render appropriately.

Your new binding in the View page might look something like this:

<div class='XmlTest'></div>
<div class='XmlPortfolioResponse'>
 @Html.Raw(Model.XmlPortfolioResponse.OuterXml.ToString())
</div>

For your JQuery, then, to parse it, you would do something like:

var $title = $('.XmlPortfolioResponse').find('portfolioSummary').text();
$('.XmlTest').text($title);

However, you might consider a more elegant approach than binding raw XML into your page, then parsing it / reformatting it / re-displaying it - which leads to DOM bloat and a lot of extra work in processing. I would suggest one of 2 approaches:

1) Output XML and style the XML directly. CSS is more than capable of styling the XML you're outputting and making it appear as you wish - assuming you aren't making major changes to format. An example might look like:

<div class='XmlPortfolioResponse'>
  <portfolioSummary>
    <value>123456.78</value>
    <assets>
      <asset>
        <ticker>XYZ</ticker>
        <quantity>50</quantity>
        <value>456.78</value>
      </asset>
    </assets>
  </portfolioSummary>
</div>

If you have this kind of XML - low on attributes, but well normalized - you could write a stylesheet like:

portfolioSummary {
    display: block;
    border: 1px solid #eee;
    background: #fff;
    position: relative;
    margin-top: 25px;
    width: 100%;
    height: 100%;
    /* Whatever other styles you want for layout */
}
portfolioSummary value {
    float: right;
    font-weight: bold;
    position: absolute;
    top: 5px; right: 5px;
}
portfolioSummary asset {
    display: block;
}
/* Etc. */

In other words - directly style the XML.

2) If, however, you have XML like the following:

<div class='XmlPortfolioResponse'>
  <portfolioSummary value='123456.78'>
   <asset value='456.78' ticker='XYZ'>
   </asset>
  </portfolioSummary>
</div>

In other words, heavy on attributes which don't lend themselves to styling... Consider loading the data via AJAX. Your JQuery would then change to something like:

$.ajax({
    url: '/Portfolio/Load/12345',
    type: 'POST',
    async: true,
    success: function (data) {
        if (!data) // do validation
            alert('failed!');
        else {
            var $xml = $(data);
            var $title = $xml.find('portfolioSummary').text();
            $('.XmlTest').text($title);
        }
    },
    error: function (error) {
        alert('failed!');
    }
});

In order to use the $.ajax() method at the bottom, you need a controller method which is something like the following:

[HttpGet] // Original Method - allows GET
public ActionResult PortfolioList {
    return View(GetPortfolios()); // Or however you load them...
}

[HttpPost] // Allows this method to be accessed via POST calls
[ActionName("PortfolioList")]
public JsonResult PortfolioList_Async {        
    return Json(GetPortfolios()); // You may need to resolve serialization here,
                                  // but usually it works well out of the box.
}
Sign up to request clarification or add additional context in comments.

6 Comments

Troy-thank you for that response. The XML I'm reading back is NOT well normalized, and indeed does have a fair amount of attribs which i need to read. I much prefer using the $.ajax() technique and parsing the xml straight-away rather than having to bind it to my html page first (just as you stated above).
example portfolioSummary node:<portfolioSummary portfolioId="1726"> <readOnly>false</readOnly> -<portfolio id="1726"> <currency>CAD</currency> -<keys> <key value="ABC CA Cash" type="Member" sequenceValue="ABC CA Cash" sequenceNumber="100" displayValue="ABC CA Cash"/> <key value="HSVaR" type="ExpType" sequenceValue="14" sequenceNumber="2000" displayValue="Historical VaR"/> </keys>
directly following the <portolio id> element is the exposureProfile element with multiple <node> elements I need to pull: -<exposureProfile> -<node date="2012-01-19"> <tag>1D 99</tag> <exposure>18935.8899</exposure> </node></exposureProfile>
in addition, I WOULD like to reformat the XML. I want to display Portfolio information in a nice user-friendly way. I like the ajax idea, but I'm not yet clear what my URL: would be...am I calling directly into my controller (i.e. localhost:32572/Portfolios/PortfolioList) ?
You need to make sure you decorate your controller method with the [HttpPost] attribute - and have it return a JsonResponse. I will update my answer to reflect.
|
0

You'll need to convert your XmlDocument to a string before you send it to the client. The easiest way to do this is to call .OuterXml.

Comments

0

In controller itself convert the xml data into object of your need like list of portfoliosummaries and then pass that object using viewdata or viewbag to view.

 XmlNodeList elemList =xmlresponse.DocumentElement.GetElementsByTagName("portfoliosummary");
            List<string> lstportfoliosummarys= new List<string>();
            for (int i = 0; i < elemList.Count; i++)
            {
                if (elemList[i].ChildNodes[1].InnerText == "portfoliosummary")
                    lstEmails.Add(elemList[i].ChildNodes[2].InnerText);
            }
            ViewBag.contacts = new SelectList(lstportfoliosummarys);

Hope this will help you.

2 Comments

Not usually a good practice to start putting lists like this into the ViewBag. It becomes very easy to glut the ViewBag itself with a lot of extraneous information that you don't actually use for databinding. At the same time - your conversion method is a useful example of how to stop the XML conversion issue entirely - if that's desired. Seems like the poster is actually wanting to use XML so that it can be parsed via jQuery, though.
"Seems like the poster is actually wanting to use XML so that it can be parsed via jQuery, though." Yes that's correct. I want to be efficient as possible, thereby sending XML to the client and letting the client (i.e. jQuery) parse and display.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.