user8231050
user8231050

Reputation: 11

Model always null when passing model from Ajax (BeginForm) to controller

I am new to C# ASP.Net MVC stuff having come from Java/Spring. I am having issues currently binding a model to the form and passing it through. It's always coming in to the controller as null. I've tried various things to no avail. Must be something simple I'm doing wrong. Any ideas?

// View

@model BensHub.Models.VisitorMessage
@using (Ajax.BeginForm(
                "PostMessage",
                "VisitorBoard",
                new AjaxOptions { HttpMethod = "POST" }))
            {
                @Html.TextBoxFor(msg => msg.Name, new { @class = "board- 
                field", @style = "margin-top:8px;", @minlength 
                             ="1",maxlength = "28", placeholder ="Name" })

                @Html.TextAreaFor(msg => msg.Message, new { @class = 
                "board-field", @rows = "4", @minlength = "1", @maxlength = 
                "128",  @placeholder = "Something nice?", })

                <input class="board-submit" type="submit" value="Say It"/>
            }

// Controller

namespace BensHub.Controllers
{
public class VisitorBoardController : Controller
{
    [HttpPost]
    public ActionResult PostMessage(VisitorMessage message)
    {
        if (ModelState.IsValid)
        {

        }

        return Json(message);
    }
}
}

// Route

        routes.MapRoute(
            "MessagePost",
            "VisitorBoard/PostMessage",
            new { controller = "VisitorBoard", action = "PostMessage" }
        );

// Model

namespace BensHub.Models
{
    public class VisitorMessage
    {
        [Key]
        public int Id { get; set; }

        public DateTime DateTime { get; set; }

        [Required]
        [StringLength(28, MinimumLength = 1)]
        public string Name { get; set; }

        [Required]
        [StringLength(128, MinimumLength = 1)]
        public string Message { get; set; }
    }
}

Upvotes: 0

Views: 960

Answers (3)

dionm
dionm

Reputation: 43

I copy and pasted the code you provided into a new project and it works as expected! Something that you haven't posted here is whats causing the issue. I would double check your routes, mine are setup as follows:

routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapRoute(
    "MessagePost",
    "VisitorBoard/PostMessage",
    new { controller = "VisitorBoard", action = "PostMessage" }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

The order of the routes will affect which one gets hit, if i were to swap the order of my bottom two routes then a different action would get called

Upvotes: 0

user8231050
user8231050

Reputation: 11

Ok so, I figured out this issue for anybody interested.

[HttpPost]
public ActionResult PostMessage(VisitorMessage message)

The action parameter 'message' conflicts with a property of the same name in the model sending the model binder crazy etc. Just rename it to something else, or the property name.

Upvotes: 1

Alex Sham
Alex Sham

Reputation: 468

I suggest that you should add [FromBody] attribute before your input parameter:

public class VisitorBoardController : Controller
{
    [HttpPost]
    public ActionResult PostMessage([FromBody] VisitorMessage message)
    { // ...
    }
}

Upvotes: 0

Related Questions