In an Asp.net MVC view, how do I use jQuery to parse the XML just returned from a controller

时间:2022-11-30 18:15:37

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:

在我的MVC视图中(使用VS 2012 RC),我正在尝试解析从Controller中返回的XML。这是我的观看代码:

@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:

任何指导将不胜感激。这是我的Controller代码的一部分:

    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; }
    }
}

3 个解决方案

#1


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.

问题是您返回的是PortfolioResponse对象,但是将其XmlPortfolioResponse属性的值设置为等于XmlDocument本身,而不是它的输出。当你绑定到屏幕时,这会产生默认的C#输出 - 这只是调用PortfolioResponse.XmlPortfolioResponse.ToString() - 除非重载,否则将返回Object类的名称。 Hense - 您将System.Xml.XmlDocument输出到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.

您首先需要做的是将@ Model.XmlPortfolioResponse.OuterXml绑定到您的视图页面,而不是@ Model.XmlPortfolioResponse。您也很可能必须在@ Html.Raw()调用中包装此值,以使其实际呈现。

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

您在View页面中的新绑定可能如下所示:

<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:

对于你的JQuery,然后,要解析它,你会做类似的事情:

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:

但是,您可能会考虑一种更优雅的方法,而不是将原始XML绑定到您的页面,然后解析它/重新格式化/重新显示它 - 这会导致DOM膨胀和处理中的大量额外工作。我建议采用以下两种方法之一:

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:

1)直接输出XML并设置XML样式。 CSS非常能够为您输出的XML设置样式并使其按照您的意愿显示 - 假设您没有对格式进行重大更改。示例可能如下所示:

<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:

如果你有这种XML - 低属性,但很好地规范化 - 你可以写一个样式表,如:

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.

换句话说 - 直接设置XML样式。

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

2)但是,如果您具有以下XML:

<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加载数据。然后你的JQuery会改为:

$.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:

要在底部使用$ .ajax()方法,您需要一个类似于以下内容的控制器方法:

[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.
}

#2


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.

在将XmlDocument发送到客户端之前,您需要将其转换为字符串。最简单的方法是调用.OuterXml。

#3


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.

在控制器本身将xml数据转换为您需要的对象,例如portfolioummaries列表,然后使用viewdata或viewbag传递该对象以进行查看。

 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.

希望这会帮助你。

#1


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.

问题是您返回的是PortfolioResponse对象,但是将其XmlPortfolioResponse属性的值设置为等于XmlDocument本身,而不是它的输出。当你绑定到屏幕时,这会产生默认的C#输出 - 这只是调用PortfolioResponse.XmlPortfolioResponse.ToString() - 除非重载,否则将返回Object类的名称。 Hense - 您将System.Xml.XmlDocument输出到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.

您首先需要做的是将@ Model.XmlPortfolioResponse.OuterXml绑定到您的视图页面,而不是@ Model.XmlPortfolioResponse。您也很可能必须在@ Html.Raw()调用中包装此值,以使其实际呈现。

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

您在View页面中的新绑定可能如下所示:

<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:

对于你的JQuery,然后,要解析它,你会做类似的事情:

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:

但是,您可能会考虑一种更优雅的方法,而不是将原始XML绑定到您的页面,然后解析它/重新格式化/重新显示它 - 这会导致DOM膨胀和处理中的大量额外工作。我建议采用以下两种方法之一:

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:

1)直接输出XML并设置XML样式。 CSS非常能够为您输出的XML设置样式并使其按照您的意愿显示 - 假设您没有对格式进行重大更改。示例可能如下所示:

<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:

如果你有这种XML - 低属性,但很好地规范化 - 你可以写一个样式表,如:

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.

换句话说 - 直接设置XML样式。

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

2)但是,如果您具有以下XML:

<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加载数据。然后你的JQuery会改为:

$.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:

要在底部使用$ .ajax()方法,您需要一个类似于以下内容的控制器方法:

[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.
}

#2


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.

在将XmlDocument发送到客户端之前,您需要将其转换为字符串。最简单的方法是调用.OuterXml。

#3


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.

在控制器本身将xml数据转换为您需要的对象,例如portfolioummaries列表,然后使用viewdata或viewbag传递该对象以进行查看。

 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.

希望这会帮助你。