0

I have ASP.NET Core application which auto validates every POST request for AntiforgeryToken:

services.AddMvc(options =>
{                
    options.Filters.Add(new AuthorizeFilter(authorizationPolicy));
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());                              
});

Then I have Telerik's Kendo Grid which is using AJAX binding for the Grid. One of the columns in the grid has a button that simply does a form POST:

@(Html.Kendo().Grid<ItemModel>()
    .Name("SearchItems")
    .Columns(col =>
    {
        col.Bound(p => p.ID).Title("ID").Width(75);
        col.Bound(p => p.Name);                        
        col.Bound(p => p.ID).ClientTemplate("<form method='post' action='/items/#: ID #/copy'><button type='submit' class='btn btn-link'>copy</button></form>");
    })
    .AutoBind(true)
    .DataSource(dataSource => dataSource
        .Ajax()
        .Model(m=>m.Id(p=>p.WorkItemID))
        .PageSize(50)
        .ServerOperation(true)
        .Read(read => read.Action("Search", "Items"))
    )
)

Controller method

[HttpPost]
[Route("items/search")]
public async Task<ActionResult> Search([DataSourceRequest] DataSourceRequest request)
{
    var workItems = await _Service.GetItems();
    var result = workItems.Select(x => new ItemModel()
    {
        ID = x.ID,
        Name = x.Name,
        Token = ?? // How do I get request verification token here

    }).ToList().ToDataSourceResult(request);
     
    return Json(result);
}
    
            
[HttpPost]
[Route("items/{id}/copy")]
public async Task<ActionResult> Copy([FromRoute]int id)
{
    // do something here
}

Is there a way to get _RequestVarificationToken in the controller's action method, so that I can use it in the ClientTemplate and put it inside the form?

1 Answer 1

1

Got it. I have to inject IAntiforgery service

public class ItemsController : BaseController
{
    private readonly IItemService _service;
    private readonly IAntiforgery _antiforgery;
    public ItemsController(IItemService service, IAntiforgery antiforgery)
    {
        _service = service;
        _antiforgery = antiforgery;
    }
    
    
    [HttpPost]
    [Route("items/search")]
    public async Task<ActionResult> Search([DataSourceRequest] DataSourceRequest request)
    {
        var token = _antiforgery.GetAndStoreTokens(HttpContext).RequestToken;
        var workItems = await _service.GetItems();
        var result = workItems.Select(x => new ItemModel()
        {
            ID = x.ID,
            Name = x.Name,
            Token = token

        }).ToList().ToDataSourceResult(request);
     
        return Json(result);
    }       

}

and then client template would be

col.Bound(p => p.ID).ClientTemplate("<form method='post' action='/items/#: ID #/copy'><input name='__RequestVerificationToken' type='hidden' value='#: Token #' /> <button type='submit' class='btn btn-link'>copy</button></form>");

Not the answer you're looking for? Browse other questions tagged or ask your own question.