2

After writing webforms for many years, I am trying to make the transition to MVC. I'm having trouble getting away from Datatables and understanding how to create a model class properly. The big hiccup is my datasource is a restful webservice which returns XML.

Currently I am strongly typing the view's model as a datatable. Am I giving anything up by not using a model class? Am I including to much information in the controller?

The following is just a simple application which takes a querystring value, performs a search using a restful webservice, and spits out the results on the page. It works, but I don't feel like I've created an actual MVC application.

My Controller:

using System.Web.Mvc;
using System.Data;
using System.Configuration;

namespace mvc1.Controllers
{
    public class HomeController : Controller
    {
        dhRestful _datahandler = new dhRestful(ConfigurationManager.ConnectionStrings["service"].ConnectionString);

        //
        // GET: /Home/
        public ActionResult Index(string search = "")
        {
            ViewBag.Title = "You searched for: " + search;

            using (DataTable dt = _datahandler.get("tv_show?name=" + search))
            {
                return View(dt);
            }
        }

    }
}

dhRestful is a helper class I ported from a previous project. It makes restful webservice calls and serializes the response XML into a DataTable. If I should continue using this class, where should I be putting it in the project files?

using System.Data;
using System.Xml;

namespace mvc1
{
    public class dhRestful
    {
        string _hostPath = "";

        public dhRestful(string hostPath)
        {
            _hostPath = hostPath;
        }

        public DataTable get(string partialUrl)
        {
            using (XmlTextReader xr = new XmlTextReader(_hostPath + partialUrl))
            {
                using (DataSet ds = new DataSet())
                {
                    ds.ReadXml(xr);

                    if (ds.Tables.Count > 0)
                    {
                        return ds.Tables[0];
                    }
                    else
                    {
                        return new DataTable();
                    }
                }
            }
        }
    }
}

The View using razor:

@model System.Data.DataTable

<h2>@ViewBag.Title</h2>

<table border="1">
    <thead>
        <tr>
            <th>ID</th>
            <th>Show Name</th>
        </tr>
    </thead>
    <tbody>
        @foreach (System.Data.DataRow row in Model.Rows)
        {
            <tr>
                <td>@row["id"].ToString()</td>
                <td>@row["name"].ToString()</td>
            </tr>
        }       
    </tbody>
</table>

Sample XML where the search was on the name "Stargate":

<myService>
  <tv_show>
    <id>72449</id>
    <name>Stargate SG-1 </name>
  </tv_show>
  <tv_show>
    <id>83237</id>
    <name>Stargate Universe </name>
  </tv_show>
  <tv_show>
    <id>70852</id>
    <name>Stargate: Infinity </name>
  </tv_show>
  <tv_show>
    <id>70851</id>
    <name>Stargate Atlantis </name>
  </tv_show>
</myService>

1 Answer 1

3

I would recommend you to write this data access layer via dependency injection, at Composition root. So later on instead of a rest client you can inject a different client that satisfies a contract.

Another note, is to create view models. If you are VO's or DTO's that you are using directly within you application it is a good practice to wrap them. I guess this is your answer. You can have your view Models in Model folder or you can create subfolder etc.

Something like this:

   // you need to adjust your dependency accordingly
   Interface IRepository<T> : where t has a value
   {
     void Set(T item);
     T Get(some value that you indicate in T);
   }

    namespace mvc1.Controllers
    {
        public class HomeController : Controller
        {
            IRepository<SomeObject> _repo;

            public HomeController(IRepository<SomeObject> repository)
            {
               _repo = repository;
            }             


            //
            // GET: /Home/
            public ActionResult Index(string search = "")
            {
                ViewBag.Title = "You searched for: " + search;

                using (SomeObject obj = _repo.get("tv_show?name=" + search))
                {
                    // here you can use automapper to map a DTO or VO to View model.
                    FooViewModel model = someobject;
                    return View(model);
                }
            }

        }
    }

At composition root: global.asax you can bootstrap the container. Many ways to this, look at structure map and how to use container.

Sign up to request clarification or add additional context in comments.

1 Comment

+1 A framework like Knockout or Backbone can be very helpful in terms of view modeling, if you wanted to do so at the client level with javascript.

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.