2

I have a web application with this controller:

    public class ServiceRequestController : Controller
    {

    [Authorize(Roles = "Customer")]
    public ActionResult Create()
    {
        return View();
    }

    [Authorize(Roles = "Customer")]
    public ActionResult CreateNewUserAccount()
    {
        return View();
    }

    [Authorize(Roles = "Customer")]
    [HttpPost]
    public ActionResult CreateNewUserAccount(ServiceRequest serviceRequest)
    {
        if (ModelState.IsValid)
        {
            serviceRequest.Log.Id = User.Identity.GetUserId().ToString();
            serviceRequest.Log.DateTimeLogged = System.DateTime.Now;
            serviceRequest.LogID = db.Logs.Max(item => item.LogID);
            serviceRequest.EstimatedResolveDate serviceRequest.CalculateEstimatedResolveDate();
            db.ServiceRequests.Add(serviceRequest);
            db.SaveChanges();
            return RedirectToAction("AllServiceRequests", "Log");
        }
        return View(serviceRequest);
    }

The serviceRequest.Log.Id = User.Identity.GetUserId().ToString(); (And any preceding line if this is commented out) throws a null reference exception. I presume the serviceRequest is somehow null?

The ActionLink which requests the CreateNewUserAccount() page is:

@Html.ActionLink("New User Account", "CreateNewUserAccount", "ServiceRequest")

I'm not sure how to resolve this exception?

The model is:

public partial class ServiceRequest
{
    public int ServiceRequestID { get; set; }
    public Nullable<int> LogID { get; set; }
    public string RequestType { get; set; }
    [DisplayName("Additional Information")]
    [Required]
    [StringLength(200)]
    public string AdditionalInformation { get; set; }
    public DateTime EstimatedResolveDate { get; set; }

    [Required]
    [DisplayName("Delivery Date")]
    public DateTime DeliveryDate { get; set; }

    public virtual Log Log { get; set; }


    public DateTime CalculateEstimatedResolveDate()
    {
        return System.DateTime.Now.AddDays(3);
    }

}

View code:

@model OfficiumWebApp.Models.ServiceRequest

@{
ViewBag.Title = "New User Account";
}
@using(Html.BeginForm("CreateNewUserAccount", "ServiceRequest", FormMethod.Post))
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
    @Html.ValidationSummary(true)

    <div class="form-group">
        @Html.LabelFor(model => model.RequestType, new { @class = "control-label col-md-2" })
        <div class="col-md-3">
            <div class="editor-field">
                @Html.TextBoxFor(model => model.RequestType, new { @Value = ViewBag.Title, @readonly = "readonly" })
                @Html.ValidationMessageFor(model => model.RequestType)
            </div>
        </div>
    </div>

    <div class="form-group">
        @Html.Label("Name of Account Holder", new { @class = "control-label col-md-2" })
        <div class="col-md-3">
            <div class="editor-field">
                @Html.TextBox("AccountName")
                @Html.ValidationMessageFor(model => model.RequestType)
            </div>
        </div>
    </div>

   <div class="form-group">
    @Html.Label("Department", new { @class = "control-label col-md-2" })
    <div class="col-md-3">
        <div class="editor-field">
            @Html.TextBox("Department")
            @Html.ValidationMessageFor(model => model.RequestType)
        </div>
    </div>
</div>

<div class="form-group">
        @Html.Label("Location", new { @class = "control-label col-md-2" })
        <div class="col-md-3">
            <div class="editor-field">
                @Html.TextBox("Location", null, new { id = "Location" }))
                @Html.ValidationMessageFor(model => model.RequestType)
            </div>
        </div>
    </div>


    <div class="form-group">
        @Html.LabelFor(model => model.AdditionalInformation, new { @class = "control-label col-md-2" })
        <div class="tags">
            <div class="col-md-10">
                @Html.TextAreaFor(model => model.AdditionalInformation)
                @Html.ValidationMessageFor(model => model.AdditionalInformation)
            </div>
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.DeliveryDate, new { @id = "VisitDateLabel", @class = "control-label col-md-2" })
        <div class="col-md-3">
            <div class="editor-field">
                @Html.JQueryUI().DatepickerFor(model => model.DeliveryDate).Inline(false)
                @Html.ValidationMessageFor(model => model.DeliveryDate)
            </div>
        </div>
    </div>
        <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-floppy-save"></span></button>
        </div>
    </div>
</div>
}
8
  • Can we see the ServiceRequest Model? Commented Feb 24, 2014 at 21:06
  • 2
    serviceRequest.Log is null, serviceRequest should be fine Commented Feb 24, 2014 at 21:13
  • Can you confirm what is null? If the entire serviceRequest is null, that's a problem with model binding, and you have to post your HTML/Razor code as well. Commented Feb 24, 2014 at 21:17
  • But the id field I need to set is in the Log. It can be accessed using just serviceRequest.Id. It needs the log part. Commented Feb 24, 2014 at 21:17
  • 1
    Almost all cases of NullReferenceException are the same. Please see "What is a NullReferenceException in .NET?" for some hints. Commented Feb 24, 2014 at 22:49

1 Answer 1

2

You need to return the view i.e.

[Authorize(Roles = "Customer")]
public ActionResult CreateNewUserAccount()
{
    var model = new ServiceRequest();
    model.Log = new Log();
    return View(model);
}

In your view you need to add a model reference too at the top i.e.

@model ServiceRequest

You could also initialise the Log object in your model as follows:

public class ServiceRequest
{
    public ServiceRequest()
    {
       Log = new Log();
    }

    ....
}

An action link will not post your model back, you need to include it within a form and include all the model values that you want to be updated on the client i.e.

@using (Html.BeginForm("CreateNewUserAccount", "ServiceRequest", FormMethod.Post)){

  @Html.EditorFor(m => m.AdditionalInformation)
  ...
  <input type="submit" value="submit" />

Update

Taken from the below comments, this was resolved by creating a new log on post i.e.

 var log = new Log { 
   Id = User.Identity.GetUserId().ToString(), 
   DateTimeLogged = System.DateTime.Now, 
   LogID = db.Logs.Max(item => item.LogID) }; 
 serviceRequest.Log = log;
Sign up to request clarification or add additional context in comments.

7 Comments

Ok. I did the first change but it made no difference. The second I already had and the 3rd I already have 'public virtual Log Log { get; set; }' this in the ServiceRequest class
@ASPCoder1450 Hi, did you also see my update with the form too? :)
@hutconoid yes i've added this in now but can confirm its made no difference
@ASPCoder1450 I think because you are not populating the ServiceRequest from the db initially. You should just be able to initialise it as follows in your get; model.Log = new Log(); I added that to the beginning of the question. I'm taking it that the User.Identity is populated as you are authenticated already.
@ASPCoder1450 How about just creating a new log on post i.e. var log = new Log { Id = User.Identity.GetUserId().ToString(), DateTimeLogged = System.DateTime.Now, LogID = db.Logs.Max(item => item.LogID) }; serviceRequest.Log = log;
|

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.