1

This is driving me crazy. I'm not including any code because I want to know the best approach to do this conceptually without influencing the answer.

In Asp.Net MVC 2 (beta 2010 incidently) I have a MasterPage Site.Master with a UserControl "SignIn". This user control has 3 fields that I want to get data from. The TextBox value "Email", the TextBox value "Password" and the bool CheckBox value "RememberMe". Now I have tried a number of things but all of them relate to the action being passed to the HomePageController which has its own Model type which is not the same as the UserControl's Model type. UserControl Model = User class, HomePageController Model = specialized HomePageData Model which has things I need to populate my HomePage View Content.

I can wire into the HomePageController Action "SignIn" both via ActionLink and a specific Post with parameters (string Email, string Password, bool? RememberMe) but no values of my HtmlHelper controls residing on the UserControl SignIn.ascx ever get passed into the conroller seemingly no matter what I try.

The SignIn control truly needs to reside on the Site.Master but I'm not sure I'm doing the right thing by using the HomePageController vs. setting up an "AccountController" but the point is moot unless I can somehow get the values entered by the user into the 3 input fields of the UserControl.

To note: I have tried UpdateModel (which does not throw an exception but all of the fields of the user object are null, TryUpdateModel with similar results, TryUpdateModel returns true but all null properties on the user instance, [AcceptVerbs["Post"]] in a HomePageController method "SignIn" with and without parameters, again no values passed or able to be retrieved from the UserControl correctly. ad nauseam.)

I have scoured the internet and cannot find an example accomplishing exactly what I'm trying to do with the MasterPage->UserControl->XyzController scenario (again, I'm not insistent on using HomePageController for this so the proper way to do this may use a "viewless" controller.

Somebody give me a Merry Christmas (if anyone's working lol)

Thanks in advance... oh and if you only know Vb.Net that's fine as well, I'll convert your answer to C#.

OK - I tried the suggestions below to no avail. I created a simple example (without the suggestions being used as a base to start from)

my MasterPage (Site.Master) is as follows...

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
</head>
<body>
    <% Html.RenderPartial("SignIn"); %>
    <asp:ContentPlaceHolder ID="MainContent" runat="server" />
</body>
</html>

and my SignIn UserControl is as follows

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<StackOverflowExample.Models.WebUser>" %>

Email: <%= Html.TextBox("Email") %>
Password: <%= Html.TextBox("Password") %>

<%= Html.ActionLink("Sign In", "SignIn", "Home") %>

...and my simplified Model is as follows ....

namespace StackOverflowExample.Models
{
    public class WebUser
    {
        public string Email { get; set; }
        public string Password { get; set; }
    }
}

... and my HomeController is as follows ...

namespace StackOverflowExample.Controllers
{
    [HandleError]
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult SignIn()
        {
            var user = new WebUser();

            try
            {
                UpdateModel(user);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex);
                throw;
            }

            return Redirect("Index");
        }
    }
}

... from this simple example, if I can get data into the WebUser instance inside HomeController, or any other Controller for that matter I can use the posted example to fix my real-world website. I know I'm missing something very fundamental here and I'm 99% sure is has to do with the fact that the SignIn control is strongly-typed to the WebUser class but the HomeController or HomeView (Index.aspx) is not strongly typed to the same (or any other) Model.

Here's the skimpy Index.aspx Home View (just in case anyone needs it ...)

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
</asp:Content>
Dave Jellison
  • 924
  • 13
  • 22

3 Answers3

2

in your control you are missing Html.BeginForm("SignIn")

<% using (Html.BeginForm("SignIn","Home") [ %>
Email: <%= Html.TextBox("Email") %>
Password: <%= Html.TextBox("Password") %>

<%= Html.ActionLink("Sign In", "SignIn", "Home") %>
<% } %>

and try to include a submit button first in that form.

Alexander Taran
  • 6,655
  • 2
  • 39
  • 60
  • OK - This works with the caveat that I use a Submit Button .... Now...why doesn't the ActionLink work? Also, I need to have a "Join" button on the page as well, using the same fields and I need to be able to tell whether Join -or- SignIn was clicked whether it be in two different actions inside the controller or a parameter inside the same action... The Join will actually not just redirect to another page, I need to fetch the values put in and do something specific with the entered data for the user to "join" as a member... – Dave Jellison Dec 25 '09 at 22:52
  • 1
    For different buttons you use the same name for buttons, but different value.. in your action you add that name to parameters Action(string buttonname) and check buttonname's value to figure out wich button was pressed.. for links to work as submit buttons you'll have to use some javascript. That's another story. – Alexander Taran Dec 25 '09 at 23:08
  • 2
    I'm guessing you have some webforms background.. About those ActionLinks not passing input values - MVC is like pure HTML there is no ViewState.. actually no state at all.. In webForms your full page of contolls is wraped up into a form wich posts back on every action. in MVC to post something back you yous forms or javascript. – Alexander Taran Dec 25 '09 at 23:13
  • You're absolutely correct, I am from the Asp.Net world. I am however trying to balance the MVC framework/"helper" ways of doing thing on top of pure HTML/JavaScript methodology so the help you've provided is appreciated. Again, thanks. – Dave Jellison Dec 26 '09 at 17:03
  • For anyone else needing multiple input/submit buttons on the same MVC form: http://stackoverflow.com/questions/442704/how-do-you-handle-multiple-submit-buttons-in-asp-net-mvc-framework – Dave Jellison Dec 26 '09 at 17:48
0

When you POST a form, the only thing that will get passed to your post action are controls. So if you have a User object containing ID, E-mail, Password, RememberMe and First Name ... but you only have controls for E-mail, Password, and RememberMe, then ID and First Name would be blank after your UpdateModel. Most likely the ID would already be available, but First Name definitely wouldn't.

So, the key is to fill this data BEFORE doing an UpdateModel. Example (syntax is likely off, sorry, no VS in front of me):

public ActionResult LoginUser(int id, User user)
{
  User userToSave = UserRepository.FetchUser(id);
  UpdateModel(userToSave);

  if (!UserIsValid(userToSave)) //may be in a service, or part of domain
  {
    //either return View with model state error, or redirect to LoginUser Get for PRG support
  }
  return RedirectToAction("LoggedIn");
}

If there's a better way to do this, I'd love to know too =)

Andrew
  • 1,765
  • 2
  • 17
  • 24
0

Specify the action, controller and other attributes in your Beginform properly, it should work have a look at this link

Community
  • 1
  • 1
San
  • 2,316
  • 4
  • 26
  • 35