Archive for ‘MVC’

September 25, 2012

ASP.NET MVC with Ajax calls to controller actions

Recently I was trouble shooting an ASP.NET MVC project which relies on some Ajax calls to controller
actions. The project has a view in which there are a couple of drop down lists which trigger an
action result as soon as an item is selected in each list.

The view has a drop down list defined as follows:

@Html.DropDownList("searchTemplate",
new SelectList(Model.DefaultSearchTemplates, "SearchFilterTemplateId", "Name"), "Choose")

And a change event triggers the action result:

$("select#searchTemplate").change(function () {
    var selectedTemplate = $("select#searchTemplate").val();
    
    if (selectedTemplate) {
	$.ajax({
	    url: '@Url.Action("ApplySearchTemplate","Quote")',
	    data: { templateId: selectedTemplate }
	});
    }
});

The functionality of the Action isn’t important for this post, but it essentially saves a users
last search criteria so that the next time they log in, they will see the same results.

The problem with the application was that the selection of a search template only worked once. And
on further inspection, it turned out that the controller action was not being called at all after
the first time.

This was an interesting problem because the change event was certainly being called every time that
an item was selected in the list. My initial thought was that there must be some bug in ajax itself,
but it did seem fairly unlikely that such a bug would have gone un-noticed.

As expected, after digging through the ajax source, the problem became apparant; user error. Ajax
caches requests by default and even though these particular calls are not returning values nor
expecting results; the requests are still cached.

Since the requests were cached, each subsequent selection in the dropdown list resulted in ajax
“ignoring” the request since it “already knew the results”.

Once I understood what was happening, it was just a matter of disabling ajax caching for the view.
There are two ways to disable the cache; the first is to disable it individually for each request:

$("select#searchTemplate").change(function () {
    var selectedTemplate = $("select#searchTemplate").val();
    
    if (selectedTemplate) {
	$.ajax({
	    url: '@Url.Action("ApplySearchTemplate","Quote")',
	    data: { templateId: selectedTemplate },
	    cache: false
	});
    }
});

The second option is to globally disable ajax caching using ajaxSetup:

$.ajaxSetup({ cache: false });

Since this particular view has multiple similar calls to controller actions, setting it globally was
the solution that was chosen.

July 2, 2012

List recent WordPress Blog Posts in ASP.NET MVC

Recently I was tasked with adding a list of recent blog posts from our WordPress site inside of an ASP.NET MVC web site. The initial strategy was going to involve fetching from the RSS feed, but after discovering the WordPress supported XML-RPC, I decided to explore that route first.

Using XML-RPC was supposed to be easy considering there is an available .NET library for it created by Charles Cook. The task should have been further simplified because there are several C# WordPress wrappers available.

After spending time with a couple of the WordPress wrappers available, it quickly became clear that the process of updating the wrappers to comply with the latest version of WordPress would be far more work than it was worth; especially considering the scope of this task.

So it was back to the original strategy of creating an RSS reader specifically for WordPress. After digging around a bit, I thankfully stumbled across the Syndication Feed class that is available in .Net 4.0 and above.

The Syndication Feed class basically provides the quick and easy solution that I was looking for while exploring the XML-RPC route. It really turned out to be a lot easier than I thought it could ever be.

So let’s get started. For this, I will assume that you are using an existing MVC application.

The first step is to add a reference to System.ServiceModel to your project as this is where the Syndication Feed class resides.

The second step is to create a View Model that will define a List of SyndicationItem’s:

using System.Collections.Generic;
using System.ServiceModel.Syndication;

namespace MvcApplication1.Models
{
    public class FeedViewModel
    {
        public FeedViewModel()
        {
            Posts = new List<SyndicationItem>();
        }

        public List<SyndicationItem> Posts { get; set; } 
    }
}

And in the Controller, we will need to populate the list:

using System.Linq;
using System.Web.Mvc;
using System.ServiceModel.Syndication;
using System.Xml;
using MvcApplication1.Models;

namespace MvcApplication1.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var model = new FeedViewModel();

            using (var reader = XmlReader.Create("https://blog.yojimbocorp.com/feed/"))
            {
                var feed = SyndicationFeed.Load(reader);
                foreach (var post in feed.Items.Take(10))
                {
                    model.Posts.Add(post);
                }
            }

            return View(model);
        }
    }
}

You will of course want to customize the reader URL to be your own and most likely will want to create a configuration entry for it.

And finally, display the data in your view:

@model MvcApplication1.Models.FeedViewModel
           
@foreach (var post in Model.Posts)
{
    <td><a href="@post.Id" target="_blank">@Html.DisplayFor(model => post.Title.Text)</a></td>
    <br />
    
}

I highly recommend reviewing the SyndicationItem documentation when creating your view.