简体   繁体   中英

Displaying a user control in ASP.NET MVC

This seemed easier in Web Forms; I'd have a user control, with the logic in the code-behind, and I could just drop it on a page.

But apparently code-behinds are a no-no in MVC, and the logic is in controllers. I'm a little confused about how logic for a user control is "wired up".

I want to display an RSS Feed user control. So I have a page:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Home Page
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <p>
        <% Html.RenderPartial("RssFeed"); %>
    </p>
</asp:Content>

I have my user control:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewPage<SyndicationFeed>" %>
<%@ Import Namespace="System.ServiceModel.Syndication" %>

<p>
    <%: ViewData.Model.Title.Text %>
</p>

<div>
    <% foreach (var item in ViewData.Model.Items)
    {
       string url = item.Links[0].Uri.OriginalString;
    %>
    <p><a href='<%= url %>'><b><%= item.Title.Text %></b></a></p>

    <% } %>
</div>

And I have this code that I need to run to get the rss data:

using (XmlReader reader = XmlReader.Create(ConfigurationManager.AppSettings["RssFeed"]))
{
    SyndicationFeed rssData = SyndicationFeed.Load(reader);

    return View(rssData);
}

But where does it go? In the controller for the page that contains the control?

Based on my understanding.... Yes, it can go in the controller in the page that contains the control. The partial can use the parent's ViewModel

See here (the bit on Partial Views)

http://msdn.microsoft.com/en-us/library/dd410123.aspx

EDIT To include your RSS feed If my controller were named RssController and it had a ViewResult method named RssFeed, I'd include the following on the .Master.

This causes the RssController to get invoked and return the view for your partial (assuming that's what View(rssData) sent back.

In ASP.NET MVC 2+, you can use Html.RenderAction to render an action's result inline.

Giving the action a [ChildActionOnly] attribute will prevent users from navigating to the action normally, making it usable only in this kind of "child" context.

To sum it up, this is how you can do it

[HttpGet, ChildActionOnly]
// put this in RssController
public ActionResult RssFeed()
{
    // prepare the model
    SyndicationFeed rssData;
    using (XmlReader reader = XmlReader.Create(ConfigurationManager.AppSettings["RssFeed"])) 
    {
        rssData = SyndicationFeed.Load(reader);
    }

    return PartialView(rssData);
}

Usage:

<% Html.RenderAction("RssFeed", "Rss"); %>

And put a check into your ASCX if the Model you are sending in is null and if so, skip everything so it won't render anything. If you leave it like you have it now, it will end in an exception if the Model sent in is null.

I had a vaguely similar problem (using Razor view engine) which I solved by putting the code into the page since there wasn't anywhere else I wanted to put it. Mine actually related to rendering a menu.

The trick is to use the @functions { ... } construct.

Some pertinent info about the layout stuff here: http://weblogs.asp.net/scottgu/archive/2010/10/22/asp-net-mvc-3-layouts.aspx

Kind of like this in your case (not exactly right; it's late and I'm not on my dev box, but it hopefully gives the idea). That way you don't need any RSS controller at all if you are only doing this small piece of RSS related stuff.

@foreach (var item in RssFeed().Items)
{
    <p><a href='@item.Links[0].Uri.OriginalString'><b>@item.Title.Text</b></a></p>
} 



@functions {
        public SyndicationFeed RssFeed()
          {
             using (XmlReader reader = XmlReader.Create(ConfigurationManager.AppSettings["RssFeed"]))
             {
                  return SyndicationFeed.Load(reader);
             }
          }
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM