0

Here I am trying to add new comment on click of button of id="abc". On Click of button ajax must be called from which Create action of TaskAssignedDailyLogController is called. In other word ajax did not hit the create action of TaskAssignedDailyLogsController
Now, the problem is that ajax didn't call the create action

Below is Ajax

<script>
    $(document).ready(function () {

    $(document).on('click', '#abc', function () {
        debugger          
        var you = $("#myForm1").serialize();       
        var parameter = { taskAssignedDailyLog: you };

        $.ajax({
            url: '@Url.Action("Create", "TaskAssignedDailyLogs")',
            type: "post",
            dataType: "html",
            data: parameter,
            success: function (data) {
                alert(data);
                $(".newCommentList").empty();

                $(".newCommentList").html(data);
            }
        });

    });
});
</script>


Below is Create.cshtml

@using (Html.BeginForm("Create", "TaskAssignedDailyLogs",   FormMethod.Post, new { @id = "myForm1" }))
{
    @Html.AntiForgeryToken()

<div class="form-horizontal empcreate">
    @Html.ValidationSummary(true, "", new { @class = "text-danger" })

    @Html.HiddenFor(x => x.TskAssId)

    <div class="form-group">
        @Html.LabelFor(model => model.Comments, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.Comments, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.Comments, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.WrkHrs, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.WrkHrs, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.WrkHrs, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        @Html.LabelFor(model => model.PercentCompleted, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.EditorFor(model => model.PercentCompleted, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.PercentCompleted, "", new { @class = "text-danger" })
        </div>
    </div>

    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <button type="button" value="Create" class="btn btn-default" id="abc"> Add</button>
        </div>
    </div>
</div>
}



Below is Controller

 [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create(TaskAssignedDailyLog taskAssignedDailyLog)
    {
        if (ModelState.IsValid)
        {

            taskAssignedDailyLog.PostedBy = 1;
            taskAssignedDailyLog.PostedOn = DateTime.Now.Date;
            db.TaskAssignedDailyLogs.Add(taskAssignedDailyLog);
            db.SaveChanges();
            return RedirectToAction("Index", new { ProjectId =1 , TskAssId = taskAssignedDailyLog.TskAssId });
        }           
        return View(taskAssignedDailyLog);
    }
ADyson
  • 57,178
  • 14
  • 51
  • 63
Cross Word
  • 13
  • 2
  • Have you tried to rebuild your project after changes? – Salah Akbari May 29 '17 at 16:48
  • How your routes are defined? – Tushar Gupta May 29 '17 at 16:49
  • 1
    first thing you should do is check your console and network tab for ajax errors, and report the results here. that will give us a starting point to work from. you've given no indication of the nature of the problem other than "doesn't work" – ADyson May 29 '17 at 16:51
  • btw your controller should really return a partial view not a whole one, or else it will insert an entire page including the head tags, css/js references into the "newCommentList" element, creating invalid markup (due to nested "html" tags etc) and potential errors with script conflicts, unexpected layout issues and generally just a big mess – ADyson May 29 '17 at 16:54
  • maybe you should try to change dataType: "html", to dataType: "application/json" – Bruno Casarotti May 29 '17 at 16:57
  • @BrunoGrisoliaCasarotti why? the intention is clearly to return html. the request is apparently not even getting to the controller, so it's hard to see how the return type could be the cause of that, it never gets close to trying to return the data. – ADyson May 29 '17 at 17:01
  • post the class file for TaskAssignedDailyLog model – Jayakrishnan May 29 '17 at 17:01
  • 1
    Yeah right, dumb answer, sorry, but looking again, I think the problem is that you are validating the anti forgery token, are you passing it in the http call? I can't see you doing that – Bruno Casarotti May 29 '17 at 17:03

1 Answers1

0

I saw one possible solution for this problem once here in SO. I don't remember who wrote this code, but it works as expected:

/***********************************************
 * AuthorizeAttribute filter for JsonResult methods
 * 
 * Validates AntiForgeryToken from header of AJAX request.
 * AntiForgeryToken must be placed into that header.
 ************************************************/

/*
 View
    @Html.AntiForgeryToken()
    <script>
        var headers = {};
        headers["__RequestVerificationToken"] = $('[name=__RequestVerificationToken]').val();
        $.ajax({
            type: "POST", //Type must be POST
            url: url,
            dataType: "json",
            headers: headers,

 Controller
    [ValidateJsonAntiForgeryToken]
    public JsonResult Method() { }
*/

public sealed class ValidateJsonAntiForgeryToken : AuthorizeAttribute
{
    public JsonResult deniedResult = new JsonResult()
    {
        JsonRequestBehavior = JsonRequestBehavior.AllowGet,
        Data = new { StatusCode = HttpStatusCode.Forbidden, Error = "Access Denied" }
    };

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        System.Diagnostics.Debug.WriteLine("ValidateJsonAntiForgeryToken");
        var request = filterContext.HttpContext.Request;

        if (request.HttpMethod == WebRequestMethods.Http.Post && request.IsAjaxRequest() && request.Headers["__RequestVerificationToken"] != null)
        {
            AntiForgery.Validate(CookieValue(request), request.Headers["__RequestVerificationToken"]);
        }
        else
        {
            filterContext.Result = deniedResult;
        }
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        System.Diagnostics.Debug.WriteLine("ValidateJsonAntiForgeryToken HandleUnauthorizedRequest ");
        filterContext.Result = deniedResult;
    }

    private static string CookieValue(HttpRequestBase request)
    {
        var cookie = request.Cookies[AntiForgeryConfig.CookieName];
        return cookie != null ? cookie.Value : null;
    }
}

Just decorate your method with the new attribute: [ValidateJsonAntiForgeryToken]

There is another solution like this one here

Let me know if it works for you.

Bruno Casarotti
  • 623
  • 8
  • 23