2

I have this wiered behavior in my project and I've followed this, this and this links but with no success. Everytime my controller method gets hit while debugging, the model will be always null. Can anyone tell what else methods I can try to pass the model through form.serialize()

Here is my Model:

public class AddNewUser
{
     public string uname { get; set; }
     public string password { get; set; }
     public string Role { get; set; }
     public string fname { get; set; }
     public string lname { get; set; }
     public HttpPostedFileBase profilepic { get; set; }
     public string email { get; set; }
     public string contact { get; set; }
}

Here is my view:

@model AdminViewModel.AddNewUser
@{
    var uRole = TempData["UserRole"] as string;
    TempData.Keep("UserRole");
}

@using (Html.BeginForm("AddUser", "Admin", FormMethod.Post, new { id = "frmAddUser", @class = "form-admin col-lg-8 col-lg-offset-2" }))
{

    <h2 class="form-login-heading mar-pad">Add new user</h2>

     <label style="font-weight:normal" for="#txtuserName">Username *</label>
     @Html.TextBoxFor(m => m.uname, new {type="text",name="uname",tabindex="1",id="txtuserName", style="padding-right:20px", autocomplete="off", spellcheck="false",placeholder="Enter username", @class="form-control ip" })

     <label style="font-weight:normal" for="#txtPassword">Password *</label>

     @Html.PasswordFor(m => m.password, new { name = "password", tabindex = "2", id = "txtPassword", autocomplete = "off", spellcheck = "false", @class = "form-control ip", placeholder = "Enter password", data_tog = "tooltip", title = "Your Password must contain : <br />- at least 1 upper case character, <br /> - at least 1 lower case character, <br /> - at least 1 numerical character, <br /> - at least 1 special character.", data_placement = "top" })

     @if (uRole == "Admin")
     {

             <label style="font-weight:normal;margin-left:15px !important" for="#selectRole">Select Role *</label><br />
             <select id="selectRole" class="selectpicker show-menu-arrow full_wid col-md-12" tabindex="3" data-size="5">
                   <option value="0" selected disabled>Please select a role</option>
                   <option value="1">Admin</option>
                   <option value="2">Manager</option>
             </select>

             @Html.HiddenFor(m => m.Role, new { id="hdnRole", data_selected=""})

             <label style="font-weight:normal" for="#txtFName">First name *</label>
             @Html.TextBoxFor(m => m.fname, new { id="txtFname", style="padding-right:20px !important;", tabindex="4", autocomplete="off", spellcheck="false", placeholder="Enter user first name", @class="form-control ip"})

             <label style="font-weight:normal" for="#txtLName">Last name *</label>
             @Html.TextBoxFor(m => m.lname, new { id = "txtLname", style = "padding-right:20px !important;", tabindex = "5", autocomplete = "off", spellcheck = "false", placeholder = "Enter user last name", @class = "form-control ip"})

       }
       else
       {
             <label style="font-weight:normal" for="#txtFName">First name *</label>
             @Html.TextBoxFor(m => m.fname, new { id = "txtFname", style = "padding-right:20px !important;", tabindex = "3", autocomplete = "off", spellcheck = "false", placeholder = "Enter user first name", @class = "form-control ip" })

             <label style="font-weight:normal" for="#txtLName">Last name *</label>
             @Html.TextBoxFor(m => m.lname, new { id = "txtLname", style = "padding-right:20px !important;", tabindex = "4", autocomplete = "off", spellcheck = "false", placeholder = "Enter user last name", @class = "form-control ip" })
       }

     Upload image @Html.TextBoxFor(m => m.profilepic, new { type="file", id="userImageFile", tabindex=6, data_charset="file"})

     <label style="font-weight:normal" for="#txtUEmail">Email [optional]</label>
     @Html.TextBoxFor(m => m.email, new { id = "txtUEname", style = "padding-right:20px !important;", tabindex = "7", autocomplete = "off", spellcheck = "false", placeholder = "Enter user email[optional]", @class = "form-control ip" })

     <label style="font-weight:normal" for="#txtUContact">Contact [optional]</label>
     @Html.TextBoxFor(m => m.contact, new { id = "txtUContact", style = "padding-right:20px !important;", tabindex = "8", autocomplete = "off", spellcheck = "false", placeholder = "Enter user contact[optional]", @class = "form-control ip", data_maxlength="10" })

     <button class="btn btn-theme btn-block" name="add" onclick="javascript:AddUser(this);" tabindex="9" id="btnAddUser" type="submit"><i class="fa fa-save"></i> Save</button>

     <button class="btn btn-default btn-block" name="cancel" onclick="javascript: ResetAddUserForm('#frmAddUser');" tabindex="10" id="btnClear" type="button"><i class="fa fa-refresh"></i> Clear</button>

}

and here is my ajax call:

function AddUser(ctrl)
{
    var data = "";
    $("#frmAddUser").on("submit", function (e) {
        e.preventDefault();
        ValidateForm("#frmAddUser");
        var formContainer = $('#frmAddUser .text-danger');
        if ($(formContainer).text().length == 0) {
            $.ajax({
                url: '/Admin/AddUser',
                type: "POST",
                dataType:'json',
                contentType: "application/json",
                data: $('form#frmAddUser').serialize(),
                success: function (data) {
                    if (data.result) {
                        ResetForm('#frmAddUser');
                        toastr.success(data.message, "Success");
                    }
                    else {
                        toastr.error(data.message, "Failed");
                    }
                },
                error:
                function (data) {
                    toastr.error(data.message, "Failed");
                }
            });
        }

        $("#frmAddUser").unbind('submit');
        return false;
    });
}

and atlast my controller method:

[HttpPost]
  public ActionResult AddUser(AdminViewModel.AddNewUser usermodel) //->Always null
  {
       ......
  }

Waiting for any help!!

EDIT - I know this can be done using FormData instead of $('form').serialize() but I just want to try with this method!!

Community
  • 1
  • 1
Guruprasad J Rao
  • 29,410
  • 14
  • 101
  • 200
  • 1
    Is the model `null` or its properties `null`? –  May 02 '15 at 10:41
  • `model` itself is null @StephenMuecke – Guruprasad J Rao May 02 '15 at 10:43
  • 1
    Cant spot anything obvious (although you have some pointless code like trying to set the `name` attributes of controls and a select which does not post back its value). What does `console.log($('#frmAddUser').serialize());` return? –  May 02 '15 at 10:48
  • 1
    Why are you writing `on('submit'..` inside `AddUser()`? Either write submit handler or the click event but *not* both. – Shaunak D May 02 '15 at 10:51
  • @StephenMuecke.. Select value I'll be setting in a hidden field on chage of select and that hidden field is strongly typed with model value. `Console.log` gives some string which I feel is like a query string. I'll post it. Give me a minute.. – Guruprasad J Rao May 02 '15 at 10:54
  • @ShaunakD. It doesn't cause any problem till now for me, I mean there is only one event n one handler and as per me it's not bad. Correct me if am wrong. – Guruprasad J Rao May 02 '15 at 10:57
  • 1
    Did you try adding debugger inside the `AddUser()` function and check whether it is being called? – Shaunak D May 02 '15 at 10:58
  • 1
    You will also never post back any files from your form with this (you would need to use `FormData` to do so) –  May 02 '15 at 10:58
  • @StephenMuecke.. `"uname=kaushikdsds&password=Kdasdas%4012121&Role=Admin&fname=adasd&lname=ada&email=&contact="` This is how am getting it in `console.log` but I feel that am not getting complete data!! :( – Guruprasad J Rao May 02 '15 at 11:07
  • @ShaunakD.. Yes bro!! Everything is fine except `model` in controller method is coming null!! – Guruprasad J Rao May 02 '15 at 11:08
  • @StephenMuecke. If I need to postback any files with this, then what changes I need to make?? – Guruprasad J Rao May 02 '15 at 11:09
  • @GuruprasadRao, My [answer here](http://stackoverflow.com/questions/29293637/how-to-append-whole-set-of-model-to-formdata-and-obtain-it-in-mvc/29293681#29293681) explains how to post a form including files using ajax. But the output for `form.serialize()` looks fine. Most common cause is naming your method parameter the same as one of your properties but that does not appear to be the case. –  May 02 '15 at 11:13
  • Yea!! I feel so!! Well I totally forgot about your said answer!! Thanks for reminding.. I can follow that but as mentioned in question I wanted to try without using `formdata`. Anyways if no solution I will go with your mentioned answer. So there is some wiered thing happening for `model` to appear as `null` right? – Guruprasad J Rao May 02 '15 at 11:19
  • 1
    @GuruprasadRao. I cant spot anything wrong (and `FormData` is only necessary is you are uploading a file using ajax) so if this is not working then using `FormData` probably wont work either. But then again your code is dreadfully hard to read (could easily be cut in half) so I may have missed something. –  May 02 '15 at 11:26
  • @StephenMuecke.. Could you please let me know which part is hard to read? `View`, `js` or `controller` or `model`? I hope `view`!! But that view is shortened to make it readable! :( – Guruprasad J Rao May 02 '15 at 11:30
  • Ok @StephenMuecke. I've achieved it with your answer mentioned in the link!! Thanks for that!! :) But still am wondering about this question here!! Anyways!! I'll go with that trick!! Thanks again Stephen.. Can you post that link as an answer here so that it will be useful for others in future!! :) – Guruprasad J Rao May 02 '15 at 11:37
  • 1
    The view - whats the point of the `tabindex = "#"` on all your controls (they are already in that order. `name="someValue"` is pointless. Why all the `id="txtSomeValue"` instead of using the default `id` generated by the helper (and then just use `@Html.LabelFor(m => m.yourProperty)`. And why all those inline styles instead of using css etc etc. –  May 02 '15 at 11:37
  • Oh!! Those things!! Ok. I'll modify all the things suggested by you.. :) I am not using default id because I've mu custom validation in js file for all the controls which are referred by this `ids` other than that everything i'll modify! Thanks for the suggestion @StephenMuecke. – Guruprasad J Rao May 02 '15 at 11:40
  • 1
    But the helper generates an `id` for your - in the case of `@Html.TextBoxFor(m => m.uname)` its `id="uname"` so why not use that? (and why is it `uname` and not `UserName` anyway?). But using `FormData` still does not explain why parameter `usermodel` is `null`. The property `profilepic` would be `null` using `.serialize()` but the other properties should still be populated so I wont post an answer unless I can find the issue. –  May 02 '15 at 11:46
  • @StephenMuecke. That's so nice of you!! anyways!! I'll try to implement maximum things mentioned by you! Thanks for your time and suggestions.. :) – Guruprasad J Rao May 02 '15 at 11:48

1 Answers1

1

You can use Ajax.BeginForm instead of Html.BeginForm

Html vs Ajax beginform Reference: here

imGreg
  • 900
  • 9
  • 24