简体   繁体   中英

Multiple Json objects are not bound to asp.net mvc controller action on HttpPost

I am passing to json objects to an asp.net mvc controller action. Both parameters are null.

Can someone spot the error prolly wrong naming?

/* Source Unit */
var sourceParent = sourceNode.getParent();
var sourceUnitParentId = sourceParent == null ? null : sourceParent.data.key;
var sourceUnit = { unitId: sourceNode.data.key, parentId: sourceUnitParentId };
var sourceUnitJson = JSON.stringify(sourceUnit);

/* Target Unit */
var targetParent = targetNode.getParent();
var targetUnitParentId = targetParent == null ? null : targetParent.data.key;
var targetUnit = { unitId: targetNode.data.key, parentId: targetUnitParentId };
var targetUnitJson = JSON.stringify(targetUnit);

moveUnit(sourceUnitJson, targetUnitJson);



function moveUnit(sourceUnit, targetUnit) {
        $.ajax({
            url: '@Url.Action("Move", "Unit")',
            type: 'POST',
            data: { sourceUnit: sourceUnit, targetUnit: targetUnit },
            success: function (response) {

            },
            error: function (e) {

            }
        });
    }

[HttpPost]
        public ActionResult Move(DragDropUnitViewModel sourceUnit, DragDropUnitViewModel targetUnit)
        {
            Unit sUnit = Mapper.Map<DragDropUnitViewModel, Unit>(sourceUnit);
            Unit tUnit = Mapper.Map<DragDropUnitViewModel, Unit>(targetUnit);
            _unitService.MoveUnit(sUnit, tUnit);
            return new EmptyResult();
        }

Why don't you use a view model? If you want to pass JSON to a controller action then define a view model containing the 2 properties and then JSON.stringify the entire request.

Here's your view model:

public class MoveViewModel
{
    public DragDropUnitViewModel SourceUnit { get; set; }
    public DragDropUnitViewModel TargetUnit { get; set; }
}

Now your controller action will take the view model as argument:

[HttpPost]
public ActionResult Move(MoveViewModel model)
{
    Unit sUnit = Mapper.Map<DragDropUnitViewModel, Unit>(model.SourceUnit);
    Unit tUnit = Mapper.Map<DragDropUnitViewModel, Unit>(model.TargetUnit);
    _unitService.MoveUnit(sUnit, tUnit);
    return new EmptyResult();
}

and finally invoke this controller action using AJAX and send JSON request by making sure that you have specified the correct request content type, otherwise ASP.NET MVC wouldn't know how to deserialize back the JSON request:

/* Source Unit */
var sourceParent = sourceNode.getParent();
var sourceUnitParentId = sourceParent == null ? null : sourceParent.data.key;
var sourceUnit = { unitId: sourceNode.data.key, parentId: sourceUnitParentId };


/* Target Unit */
var targetParent = targetNode.getParent();
var targetUnitParentId = targetParent == null ? null : targetParent.data.key;
var targetUnit = { unitId: targetNode.data.key, parentId: targetUnitParentId };

/* build the view model */
var moveModel = { sourceUnit: sourceUnit, targetUnit: targetUnit };

/* Pass the view model to the server using an AJAX request */
moveUnit(moveModel);



function moveUnit(moveModel) {
    $.ajax({
        url: '@Url.Action("Move", "Unit")',
        type: 'POST',
        // It's very important to specify the correct content type
        // request header because we are sending a JSON request
        contentType: 'application/json; charset=utf-8',
        data: JSON.stringify(moveModel),
        success: function (response) {

        },
        error: function (e) {

        }
    });
}

Summary:

  • Every time you have a controller action taking more than 1 single argument you are doing it wrong. Stop and define a view model immediately.
  • Every time you have a controller action passing a domain model to a view you are doing it wrong. Stop and define a view model immediately.

As you can see it's all about view models in ASP.NET MVC.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM