Form post from partial view to API

475 Views Asked by At

I am trying to create an SPA application using Sammy. When I call #/entitycreate link, I return a partial view from Home controller which contains an html form to submit. Partial view comes as I expect but rest of it doesn't work. Below are my problems and questions, I'd appreciate for any help.

  1. KO binding doesn't work in partial view, even though I did exactly how it's done in the default SPA project template (see home.viewmodel.js).
  2. This one is the most critical: when I submit this form to my API with ajax/post, my model always comes back with a null value, therefore I can't create an entity via my API. I have tried with [FromBody] and without, model always comes null.
  3. In some sense a general question, should I include Html.AntiForgeryToken() in my form and [ValidateAntiForgeryToken] attribute in my API action?

Partial View:

@model namespace.SectorViewModel
<!-- ko with: sectorcreate -->
<div class="six wide column">
    <div class="ui segments">
        <div class="ui segment">
            <h4 class="ui center aligned header">Create New Sector</h4>
        </div>
        <div class="ui secondary segment">
            <form id="entity-create-form" class="ui form" action="#/sectorcreatepost" method="post" data-bind="submit: createEntity">
                <!-- I am not sure if I should include AntiForgeryToken for WebAPI call -->
                <!-- Html.AntiForgeryToken() -->
                <fieldset>
                    <div class="field required">
                        @Html.LabelFor(m => m.Name)
                        @Html.TextBoxFor(m => m.Name, new { data_bind = "value: name" })
                    </div>
                    <div class="ui two buttons">
                        <button class="ui positive button" type="submit">Create</button>
                        <button class="ui button" type="button" id="operation-cancel">Cancel</button>
                    </div>
                </fieldset>
            </form>
        </div>
    </div>
</div>
<!-- /ko -->

JS View Model:

function SectorCreateViewModel(app, dataModel) {
    var self = this;

    self.name = ko.observable("ko binding doesn't work");
    self.createEntity = function () {
        console.log("ko binding doesn't work");
    }

    Sammy(function () {
        this.get("#sectorcreateget", function () {
            $.ajax({
                url: "/home/getview",
                type: "get",
                data: { viewName: "sectorcreate" },
                success: function (view) {
                    $("#main").html(view);
                }
            });
            return false;
        });

        this.post("#/sectorcreatepost",
            function () {
                $.ajax({
                    url: "/api/sectors",
                    type: "post",
                    data: $("#entity-create-form").serialize(),
                    contentType: "application/json; charset=utf-8",
                    success: function (response) {
                        console.log(response);
                    },
                    error: function (xhr, status, error) {
                        console.log(xhr);
                        console.log(status);
                    }
                });
                return false;
            });

        this.get("#/yeni-sektor", function () {
            this.app.runRoute("get", "#sectorcreateget");
        });
    });

    return self;
}

app.addViewModel({
    name: "SectorCreate",
    bindingMemberName: "sectorcreate",
    factory: SectorCreateViewModel
});

API Action:

public HttpResponseMessage Post([FromBody]SectorViewModel model)
{
    // model is always null, with or without [FromBody]
    if (!ModelState.IsValid)
        return Request.CreateResponse(HttpStatusCode.BadRequest);

    // repository operations...

    return response;
}
1

There are 1 best solutions below

0
mnyarar On

I have removed contentType: "application/json; charset=utf-8", from ajax request based on the article here. #2 is now resolved, #1 and #3 still remains to be answered.