2

How can I create a form in ASP.NET MVC2, send the data to a controller that adds something to the database and then redirects to the home page? Can you give me an example/snippet of how it's done in the View?


For some reason, I have a bug in my form. Here's the code:

AddEvent.aspx

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

<h2>Add Event</h2>
<% using (Html.BeginForm()) { %>

    <div>
        <%= Html.LabelFor(x => x.EventName) %>: 
        <%= Html.TextBoxFor(x => x.EventName) %>
    </div>
    <div>
        <%= Html.LabelFor(x => x.EventDate) %>: 
        <%= Html.TextBoxFor(x => x.EventDate) %>
    </div>
    <div>
        <%= Html.LabelFor(x => x.EventLocation) %>: 
        <%= Html.TextBoxFor(x => x.EventLocation) %>
    </div>
    <div>
        <%= Html.LabelFor(x => x.EventDescription) %>: </br> 
        <%= Html.TextAreaFor(x => x.EventDescription) %>
    </div>

    <input type="submit" value="Submit" />
<% } %>

HomeController.cs

    public ActionResult AddEvent()
    {
        return View();
    }

    [HttpPost]
    public ActionResult AddEvent(Event e)
    {
        e.EventCreatorName = Session["UserName"].ToString();
        DatabaseModels db = new DatabaseModels();
        db.AddEvent(e);

        return RedirectToAction("Index", "Home");
    }

DatabaseModels.cs

    public bool AddEvent(Event e)
    {
        anEvent eventToAdd = new anEvent();
        eventToAdd.creator_nickname = e.EventCreatorName;
        eventToAdd.event_category = 1; // TODO
        if (e.EventDate == null)
        {
            eventToAdd.event_date = new DateTime();
        }
        else
        {
            eventToAdd.event_date = DateTime.Parse(e.EventDate);
        }
        eventToAdd.event_location = e.EventLocation;
        eventToAdd.event_name = e.EventName;

        m_db.AddToevents(eventToAdd);
        m_db.SaveChanges();
        return true;
    }

I type in details in the form and I get the following Exception:

This property cannot be set to a null value.

on event_location. Can anyone help solve this?

3
  • Have you checked what is the value of e.EventLocation? From your description, it seems like it is null while event_location can't be null. Commented Jan 25, 2011 at 18:33
  • I have debugged it as much as I can, and as far as I can tell, the controller doesn't get any of the data inserted in the form. Commented Jan 25, 2011 at 18:36
  • Well, apparently I forget {get; set;}... It works now. Commented Jan 25, 2011 at 18:46

1 Answer 1

4

The asp.net/mvc site contains numerous examples, videos and tutorials about MVC that are worth reading. Here's an example of how the scenario you are asking about could be implemented:

Model:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Controller:

public class PersonsController: Controller
{
    public ActionResult Index()
    {
        return View(new Person());
    }

    [HttpPost]
    public ActionResult Index(Person person)
    {
        // The person object here will have it's FirstName
        // and LastName properties bound to whatever values
        // the user entered in the corresponding textboxes in the form

        // TODO: save person to database 

        // redirect to /home/index
        return RedirectToAction("index", "home");
    }
}

View:

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

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <% using (Html.BeginForm()) { %>
        <div>
            <%= Html.LabelFor(x => x.FirstName) %>:
            <%= Html.TextBoxFor(x => x.FirstName) %>
        </div>

        <div>
            <%= Html.LabelFor(x => x.LastName) %>:
            <%= Html.TextBoxFor(x => x.LastName) %>
        </div>

        <input type="submit" value="Save" />
    <% } %>
</asp:Content>

Now you might be wondering about the TODO part. Usually I create a repository to decouple my data access logic from my controller:

public interface IPersonsRepository
{
    void Save(Person person);
}

and then use constructor injection of this repository into my controller:

public class PersonsController: Controller
{
    private readonly IPersonsRepository _repository;
    public PersonsController(IPersonsRepository repository)
    {
        _repository = repository;
    }

    public ActionResult Index()
    {
        return View(new Person());
    }

    [HttpPost]
    public ActionResult Index(Person person)
    {
        // The person object here will have it's FirstName
        // and LastName properties bound to whatever values
        // the user entered in the corresponding textboxes in the form

        // save person to database 
        _repository.Save(person);

        // redirect to /home/index
        return RedirectToAction("index", "home");
    }
}

Obviously now the last part that's left is the implementation of this repository. This will depend on how/where your data is stored and the particular data access technology you would be using. So are you using a relational database, flat text file, XML file, object database, some database stored on the cloud, ... how are you going to access it: EF, NHibernate, Linq-to-XML, some REST API, ...

Once you make your choice you simply implement the interface and instruct your DI framework to pass the proper implementation to the controller constructor.

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

1 Comment

Thanks! I do have a bug with this though, please take a look at the edited question.

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.