2

Am new to MVC, I was following a tutorial and got this error

Image Here

I followed the every steps in the tutorial, but still getting the same error Here is the code for my view

@model _234CrudDemo.Models.ComplaintTicket

<div class="form-horizontal">
    <h4>ComplaintTicket</h4>
    <hr />
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Message, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Message, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Message, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Attachment, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <input type="file" name="ImageFile" required />
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Ministry, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Ministry, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Ministry, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
</div>

And here is my controller

public class ComplaintTicketController : Controller
{
    //CRUDDataComplaintsEntities db = new CRUDDataComplaintsEntities();
    //// GET: ComplaintTicket
    //public ActionResult Index()
    //{
    //    //var tickets = db.ComplaintsTickets.ToList();
    //    var tickets = (from x in db.ComplaintTicket
    //                   join a in db.mins on x.Ministry equals a.Id
    //                   select new TicketsIndexLists() { Id = x.Id, Title = x.Title, Message = x.Message, Attachment = x.Attachment, Name = a.Name }).ToList();
    //    return View(tickets);
    //}
    [HttpGet]
    public ActionResult Add()
    {
        return View();
    }
    [HttpPost]
    public ActionResult Add(ComplaintTicket imageModel)
    {
        string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
        string extension = Path.GetExtension(imageModel.ImageFile.FileName);
        fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
        imageModel.Attachment = "~/Image/" + fileName;
        fileName = Path.Combine(Server.MapPath("~/Image/"), fileName);
        imageModel.ImageFile.SaveAs(fileName);
        //db.ComplaintTicket.Add(imageModel);
        //db.SaveChanges();
        //ModelState.Clear();
        return View();
    }
}

Here is my model class

public partial class ComplaintTicket
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Message { get; set; }
    [DisplayName("Upload Image")]
    public string Attachment { get; set; }
    public Nullable<int> Ministry { get; set; }

    public virtual mins mins { get; set; }

    public HttpPostedFile ImageFile { get; set; }
}

Please how do I resolve this, I have search for solutions here and try answers given to previous similar questions, but none worked for, its still giving me the same error, help needed. Am new to c# Thanks

marc_s
  • 675,133
  • 158
  • 1,253
  • 1,388
  • @SimplyGed No, I tried the solutions – Yahbueze Mannesseh Dec 11 '19 at 04:01
  • imageModel --- most likely its null. Check value and path and you'll get it working. – Jawad Dec 11 '19 at 04:05
  • @Jawad Please explain better, I don't understand – Yahbueze Mannesseh Dec 11 '19 at 04:08
  • In your controller, this line is causing your NullReferenceExceptions... string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName); You need to check why imageModel is null – Jawad Dec 11 '19 at 04:11
  • 1
    @YahbuezeMannesseh In your HTML code, you never assign a value to the `ImageFile` property and when your controller tries to access that property with the line `string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);` the `ImageFile` property is null - which produces the error you are seeing. Please re-read the original link as that has the best advice on how to fix a `NullReferenceException` – Simply Ged Dec 11 '19 at 04:14

3 Answers3

3

Please check this example.

Note: in your question maybe you forget the form tag when the file is uploaded ,form tag is required, with the required attributes enctype = "multipart/form-data".

Apart for this you can upload upload file using jquery/ajax or some another plugin.

cshtml markup:

<div class="form-horizontal">
    <h4>ComplaintTicket</h4>
    <hr />
    @using (Html.BeginForm("Add", "ComplaintTicket", FormMethod.Post,
                              new { enctype = "multipart/form-data" }))
    { 
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
        @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Message, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Message, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Message, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Attachment, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            <input type="file" name="ImageFile" required />
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.Ministry, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Ministry, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Ministry, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" value="Create" class="btn btn-default" />
        </div>
    </div>
    }
</div>

Controller code:

public class ComplaintTicketController : Controller
{
    //CRUDDataComplaintsEntities db = new CRUDDataComplaintsEntities();
    //// GET: ComplaintTicket
    //public ActionResult Index()
    //{
    //    //var tickets = db.ComplaintsTickets.ToList();
    //    var tickets = (from x in db.ComplaintTicket
    //                   join a in db.mins on x.Ministry equals a.Id
    //                   select new TicketsIndexLists() { Id = x.Id, Title = x.Title, Message = x.Message, Attachment = x.Attachment, Name = a.Name }).ToList();
    //    return View(tickets);
    //}
    [HttpGet]
    public ActionResult Add()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Add(ComplaintTicket imageModel,FormCollection formCollection)
    {
        try
        {
           // you can check with Request.Files.Count also
           // if(Request.Files.Count > 0) then your logic to save file
            if(imageModel.ImageFile!=null)
            {
                string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
                string extension = Path.GetExtension(imageModel.ImageFile.FileName);
                fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
                imageModel.Attachment = "~/Image/" + fileName;
                fileName = Path.Combine(Server.MapPath("~/Image/"), fileName);
                imageModel.ImageFile.SaveAs(fileName);
            }

            db.ComplaintTicket.Add(imageModel);
            db.SaveChanges();
            ModelState.Clear();
            //after save your return value
        }
        catch(Exception ex)
        {
        }

        return View();
    }
}
marc_s
  • 675,133
  • 158
  • 1,253
  • 1,388
jishan siddique
  • 1,733
  • 2
  • 8
  • 16
2

i have did few modification in your code, you can refer that and try on your end. Basically you need to take care few conditional approach for directory exists or not as well object referece null or not.

I have update you code with all aspect. Even you need to use enctype="multipart/form-data" while you post the image to controller, otherwise file object will remain null always.

Let me know in case of anything else required.

.cshtml Code

@model _234CrudDemo.Models.ComplaintTicket

<form method="post" action="@Url.Action(" Add ")" enctype="multipart/form-data">
  <div class="form-horizontal">
    <h4>ComplaintTicket</h4>
    <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" })
    <div class="form-group">
      @Html.LabelFor(model => model.Title, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Title, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Title, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      @Html.LabelFor(model => model.Message, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Message, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Message, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      @Html.LabelFor(model => model.Attachment, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        <input type="file" name="ImageFile" required />
      </div>
    </div>

    <div class="form-group">
      @Html.LabelFor(model => model.Ministry, htmlAttributes: new { @class = "control-label col-md-2" })
      <div class="col-md-10">
        @Html.EditorFor(model => model.Ministry, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Ministry, "", new { @class = "text-danger" })
      </div>
    </div>

    <div class="form-group">
      <div class="col-md-offset-2 col-md-10">
        <input type="submit" value="Create" class="btn btn-default" />
      </div>
    </div>
  </div>
</form>

Controller Code

public class ComplaintTicketController : Controller
{
    //CRUDDataComplaintsEntities db = new CRUDDataComplaintsEntities();
    //// GET: ComplaintTicket
    //public ActionResult Index()
    //{
    //    //var tickets = db.ComplaintsTickets.ToList();
    //    var tickets = (from x in db.ComplaintTicket
    //                   join a in db.mins on x.Ministry equals a.Id
    //                   select new TicketsIndexLists() { Id = x.Id, Title = x.Title, Message = x.Message, Attachment = x.Attachment, Name = a.Name }).ToList();
    //    return View(tickets);
    //}
    [HttpGet]
    public ActionResult Add()
    {
        return View();
    }

[HttpPost]
        public ActionResult Add(ComplaintTicket imageModel)
        {
            if (imageModel.ImageFile != null)
            {
                string fileName = Path.GetFileNameWithoutExtension(imageModel.ImageFile.FileName);
                string extension = Path.GetExtension(imageModel.ImageFile.FileName);
                fileName = fileName + DateTime.Now.ToString("yymmssfff") + extension;
                imageModel.Attachment = "~/Image/" + fileName;
                string folderPath = Server.MapPath("~/Image/");
                if (System.IO.File.Exists(folderPath))
                {
                    fileName = Path.Combine(folderPath, fileName);
                    imageModel.ImageFile.SaveAs(fileName);
                }
                else
                {
                    System.IO.Directory.CreateDirectory(folderPath);
                    fileName = Path.Combine(folderPath, fileName);
                    imageModel.ImageFile.SaveAs(fileName);
                }
            }
            //db.ComplaintTicket.Add(imageModel);
            //db.SaveChanges();
            //ModelState.Clear();
            return View();
        }
}

Modal Class

public partial class ComplaintTicket
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Message { get; set; }
    public string Attachment { get; set; }
    public Nullable<int> Ministry { get; set; }
    public HttpPostedFileBase ImageFile { get; set; }
}
ankitkanojia
  • 2,872
  • 4
  • 18
  • 30
1

You need to pass an instance of ComplaintTicket to the View from the controller. In the Add controller method with HttpGet you can do this:

return View(new ComplaintTicket());

Instead of returning View(). This way the model passed to the view is not null.

Matt U
  • 3,586
  • 3
  • 23
  • Still getting the same error, Object reference not set to an instance of an object. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. Exception Details: System.NullReferenceException: Object reference not set to an instance of an object. – Yahbueze Mannesseh Dec 11 '19 at 04:49
  • 1
    Use the debugger and verify that `imageModel` and `imageModel.ImageFile` are not null. – Matt U Dec 11 '19 at 04:51
  • Instead of the plain file input try `@Html.TextBoxFor(m => m.ImageFile, new { type ="file" })` – Matt U Dec 11 '19 at 04:58