1

I'm going straight to the point here guys,

I have a form. when I save the form... it only gets the firstname, middlename and lastname.. it doesn't get the files... however, if I only get the photo and comment out other inputs... the photo is captured on my model.. I dunno why it behaves like this.. I'm really new to asp.net mvc.. so please bear with me..

@model Impulse.ViewModels.AgentViewModel

@{
    ViewBag.Title = "AgentForm";
    Layout = "~/Views/Shared/_SiteLayout.cshtml";
}

<div class="custom-container">
    <h1 class="title"><strong>Add New Agent</strong></h1>
    <hr />
   @using (Html.BeginForm("Save", "Agent", FormMethod.Post, new { enctype = "multipart/form-data" }))
   {

    <div class="row">
        <div class="col-md-3">
            <div id="preview">
                <img src="~/Content/Assets/no-image.png" id="profile_image" class="img-thumbnail" />
            </div>
            <div class="form-group">
                <label>Profile Picture</label>
                <input type="file" name="photo" id="photo" />
            </div>
        </div>
        <div class="col-md-9">
            <div class="row">
                <div class="col-md-4">
                    <div class="form-group">
                        @Html.LabelFor(m => m.Agent.FirstName)
                        @Html.TextBoxFor(m => m.Agent.FirstName, new { @class = "form-control" })
                        @Html.ValidationMessageFor(m => m.Agent.FirstName)
                    </div>
                </div>
            </div>
            <div class="row">
                <div class="col-md-4">
                    <div class="form-group">
                        @Html.LabelFor(m => m.Agent.MiddleName)
                        @Html.TextBoxFor(m => m.Agent.MiddleName, new { @class = "form-control" })
                        @Html.ValidationMessageFor(m => m.Agent.MiddleName)
                    </div>
                </div>
            </div>

            <div class="row">
                <div class="col-md-4">
                    <div class="form-group">
                        @Html.LabelFor(m => m.Agent.LastName)
                        @Html.TextBoxFor(m => m.Agent.LastName, new { @class = "form-control" })
                        @Html.ValidationMessageFor(m => m.Agent.LastName)
                    </div>
                </div>
            </div>
        </div>
    </div>


    <input type="submit" class="btn btn-primary" value="Save" />
   }


</div>

Controller

   [HttpPost]
    public ActionResult Save(AgentModel agent)
    {
        //I debug here to see the data passed by my view
        return Content("Sample");
    }

Model

public class AgentModel
{
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string MiddleName { get; set; }
        [FileSize(10240)]
        [FileTypes("jpg,jpeg,png")]
        public HttpPostedFileBase photo { get; set; }

    }
Sam Teng Wong
  • 2,379
  • 5
  • 34
  • 56
  • http://stackoverflow.com/questions/5149116/mvc-how-to-post-file-upload-and-other-form-fields-to-one-action – CRice Jan 16 '17 at 07:16
  • @CRice thank you for this but I have tried what `kevalsing` suggested to make the input file in Razor format and it captures now..... but I am, wondering why it doesn't capture when it's on html format... – Sam Teng Wong Jan 16 '17 at 07:20
  • The model in the view is `AgentViewModel` but the model you have shown is `AgentModel` (not the same thing). I assume `AgentViewModel` contains a property `AgentModel Agent` (which is awful practice - a view model should never contain a property which is a data model when editing) so the input would need `name="Agent.photo"` assuming the POST method is `public ActionResult Save(AgentViewModel model)` –  Jan 16 '17 at 07:33

2 Answers2

2

you can try like this

Model

public class UploadFileModel 
{
    public UploadFileModel()
    {
        Files = new List<HttpPostedFileBase>();
    }

    public List<HttpPostedFileBase> Files { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string MiddleName { get; set; }
}

View

@using (Html.BeginForm("UploadData", "Home", FormMethod.Post, new { encType="multipart/form-data" }))
{
    @Html.TextBoxFor(m => m.FirstName)
    <br /><br />

    @Html.TextBoxFor(m => m.Files, new { type = "file", name = "Files" })<br /><br />
    <input type="submit" value="submit" name="submit" id="submit" />
}

Controller

public ActionResult UploadData(UploadFileModel model)
{
    var file = model.Files[0];
    return View(model);
}
Pranav Patel
  • 1,541
  • 14
  • 28
  • Question: why it doesn't work with normal `input type file`? but when I changed it to razor syntax it work.. – Sam Teng Wong Jan 16 '17 at 07:36
  • @SamTengWong, The problem is that you using a different model in the view from the model in the POST method, and then compounding the problem by giving the POST method parameter the same name as a property in your model –  Jan 16 '17 at 07:38
  • @StephenMuecke however, the `AgentViewModel` only have these property. `public AgentModel agent {get;set;}` and `List of Cites and Provinces`. so when I instantiate the the `AgentViewModel` class the values of the agent is the same with the `AgentModel`.. – Sam Teng Wong Jan 16 '17 at 08:29
  • 1
    @SamTengWong, As I noted above, that is bad practice - `AgentViewModel` should contain properties `FirstName`, `LastName` etc, plus `List` etc. Refer [What is ViewModel in MVC?](http://stackoverflow.com/questions/11064316/what-is-viewmodel-in-mvc). –  Jan 16 '17 at 08:32
  • @StephenMuecke another question... is it advisable to just inherit the property of the AgentModel to AgentViewModel and I just add the photo property and list of cities and provinces on the AgentViewModel? – Sam Teng Wong Jan 17 '17 at 01:14
  • @SamTengWong, No, I would not recommend that. Your data models and view models should have not knowledge of each other (the controller is responsible for mapping one to the other) –  Jan 17 '17 at 03:26
1
  1. you are binding to view to AgentViewModel so you will get AgentViewModel when you post server. so the parameter to action save should be viewmodel. Or Else change view to bind to AgentModel.
  2. The file control that you have used is html input type. try using below code.

@Html.TextBoxFor(m => Model.File, new { type = "file" , accept=".pdf"}) @Html.ValidationMessageFor(m => Model.File)

kevalsing
  • 196
  • 8
  • nope... the agentViewModel consists of AgentModel, ProvincesModel, and CitiesModel. I haven't included some of the info of the agent.. but I guess the data that I provieded will suffice – Sam Teng Wong Jan 16 '17 at 07:12
  • ok, then on your action method, pass the parameter as AgenViewModel. And with the code change I suggested let me know if it works. – kevalsing Jan 16 '17 at 07:21
  • I've tried using the Razor syntax for generating the input type file and it works now.. thanks – Sam Teng Wong Jan 16 '17 at 07:21