1
public class AccountController : Controller
{

    private LoginModel loginModel = null;

    #region Constructor
    public AccountController(LoginModel loginModel)
    {
        this.loginModel = loginModel;
    }

    public AccountController()
    {
    }
    #endregion

    #region Login
    //
    // GET: /Account/Login
    public ActionResult Login()
    {
        return View();
    }

    //
    // POST: /Account/Login
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Login(string userName, string password, bool rememberMe, string returnUrl)
    {
        try
        {
            string displayFullName = null, token = null;

            LoginViewModel loginViewModel = new LoginViewModel();
            loginViewModel.UserName = userName;
            loginViewModel.Password = password;
            loginViewModel.RememberMe = rememberMe;

            ModelState.AddModelErrors(loginViewModel.ValidateLogIn());

            if (!ModelState.IsValid)
            {
                return View();
            }

            //login failed than return view. 
            if (!this.loginModel.LogIn(loginViewModel, ref displayFullName, ref token))
            {
                ModelState.AddModelError("_FORM", PortalErrors.IncorrectDataMsg);
                return View();
            }

            if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                    && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
            {
                return Redirect(returnUrl);
            }
            else
            {
                return RedirectToAction("Index", "Home");
            }

        }
        catch (Exception exc)
        {
            ModelState.AddModelError("_FORM", PortalErrors.CommonErrMsg);
            return View();
        }
    } 

I get the error on my above code on line if (!this.loginModel.LogIn(loginViewModel, ref displayFullName, ref token))

Can any one help with this to find what's wrong in this one?

John Saunders
  • 160,644
  • 26
  • 247
  • 397
updev
  • 623
  • 5
  • 14
  • 32
  • possible duplicate of [What is a NullReferenceException in .NET?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-in-net) – John Saunders Feb 21 '12 at 15:48
  • @JohnSaunders yeah I'd agree with that too; doesn't matter how much code goes up; a null reference always boils down to the same thing, really. – Andras Zoltan Feb 21 '12 at 15:54

5 Answers5

3

Well, you've got two cosntructor - one of them sets this.loginModel (although it doesn't check that it sets it to a non-null value); the other doesn't.

Which constructor is being called? If it's the parameterless one, then I'm not surprised you're getting that error. Do you need both constructors? Is this being instantiated by some DI framework?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Do i need to use DI framework if I am using both framework? How can i get rid off this error? – updev Feb 21 '12 at 15:59
  • @updev: I asked because it's unclear how your controller is being created. Do you *need* that parameterless constructor at all? – Jon Skeet Feb 21 '12 at 16:30
2

Surely it's because the loginModel is supposed to be set in the constructor; but MVC will not fire the constructor that sets it; it'll be firing the default constructor - so by that point it's null; hence the NullReferenceException.

I'm going to take a guess that you've inherited this Controller from someone else; and that they have written unit tests for it - hence the additional constructor; unless, as Jon has mentioned, there is some DI framework active on the site (in which case it's misconfigured).

If there's a DI framework creating the controller - then check that it can resolve an instance of LoginModel. An easy way, and good practise, is to check for a null LoginModel being passed in that constructor and throw an exception (typically ArgumentNullException; the use of Code Contracts as mentioned by another answer here is a good plan) and then run the site again. Either you'll get the same error (in which case there's probably no DI involved), or you'll get your ArgumentNullException - in which case there is and it's badly configured.

If there isn't, you need to modify the default constructor of the controller to create the default instance of LoginModel - presumably it has roots in a Database or something like that - ultimately you'll need to look at the rest of the project's code to figure that one out.

Andras Zoltan
  • 41,961
  • 13
  • 104
  • 160
  • you mean it will use the empty constructor? – updev Feb 21 '12 at 16:00
  • yes it will; MVC doesn't know how to fill out a Controller's constructor out of the box. Here's an MSDN lab on using Dependency Injection with MVC3 that might help: http://msdn.microsoft.com/en-us/gg618491. It introduces the Unity DI framework. – Andras Zoltan Feb 21 '12 at 16:08
1

Well, it looks like this.loginModel is null (or, it could be something within the call to this.loginModel.Login).

I suspect the former because you have

public AccountController() { }

where you never set this.loginModel.

Additionally, in this constructor

public AccountController(LoginModel loginModel) {
    this.loginModel = loginModel;
}

you didn't check that loginModel is not null. I think you remove the parameterless constructor and you should add a contract

Contract.Requires(loginModel != null);
jason
  • 236,483
  • 35
  • 423
  • 525
  • You can need to ensure that `this.loginModel` is not `null`. I'd suggest removing the parameterless constructor, and then making sure that you're only injecting non-`null` instances of `LoginModel` into the constructor `AccountController(LoginModel loginModel)`. – jason Feb 21 '12 at 16:25
1

Put a debugger breakpoint on the line in question.

When the code stops there, are any of the variables null?

My guess is that this.loginModel is null there. You can't call instance methods on null instances.

Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • 1
    In that case you'll need to figure out how to get a non-null loginModel before you can call any methods on it. For what it's worth, this might be a good place for a static method. Most `Login` methods I've seen are stateless, and in that case a static method is preferred. – Chris Shain Feb 21 '12 at 16:02
1

I'd guess loginModel is null. If the AccountController was instantiated with the parameterless constructor that will have caused this.

Jonny Cundall
  • 2,552
  • 1
  • 21
  • 33