Home > Mobile >  Post-request rejected by server
Post-request rejected by server

Time:05-04

Could anyone help to solve a problem? I'm trying to send data form from authorize user to protected controller method, using fetch and getting 400 error. I'm using NET CORE 5 MVC and on front-en bootstrap 5. If I remove ValidateAntiForgeryToken from AddItemToStore method I'm getting 415 error

C# code

  [Authorize]
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddItemToStore([FromBody] StoreUser itemsStore)
{
    StoreUser str = new StoreUser
    {

        Id = 1,
        UserId = itemsStore.UserId,
        CatrgoryId = itemsStore.CatrgoryId
    };

    return Ok(str);
}

JS-code

var buttonAddOrder = document.getElementById("addToOrder");

buttonAddOrder?.addEventListener("click", function () {
    var catId = document.querySelector("#formToStore input[name = 'cardId']").value;
    var userId = document.querySelector("#formToStore input[name = 'userId']").value;
    var antiForgeryToken = document.querySelector("#formToStore input[name = '__RequestVerificationToken']").value;
    var itemsStore = {
        __RequestVerificationToken: antiForgeryToken,
        UserId: userId,
        CatrgoryId: catId,
        Payed: false
    };
    var url = "/CategoriesToUser/AddItemToStore"; 
    

    var response = fetch(url, {
        method: 'POST',
        mode: 'cors',
        cache: 'no-cache',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8;'
        },
        body: {
           
            itemsStore: itemsStore
        }
    })
        .then((response) => {
            return response.json();
        }).catch((e) => console.log(e.message));
    console.log('buttonAddOrder', response);
   

HTML

<form id="formToStore" method="post" enctype="multipart/form-data">
  <input type="hidden" name="cardId" id="cardId" /> @{ var getUser = await UserManager.GetUserAsync(User); }
  <input type="hidden" name="userId" asp-for="@getUser.Id" />

  <div >
    <button type="button" id="buttonclose" name="buttonclose"  data-bs-dismiss="modal">Close</button>

    <button type="button" id="addToOrder" name="addToOrder" >
                        Add to Order
                    </button>
  </div>
</form>

An attempt of using FormData doesn't work, the same error.

buttonAddOrder?.addEventListener("click", function () {
  
    var url = "/CategoriesToUser/AddItemToStore";
    const  formToStore = document.getElementById('formToStore');
    var formOrder = new FormData(formToStore);
   
    let response = fetch(url, {
        method: 'POST',
        mode: 'cors',
        cache: 'no-cache',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8;'
        },
        body: formOrder
    })
        .then((response) => {
            return response.json();
        }).catch((e) => console.log(e.message));
    console.log('buttonAddOrder', response);
   
});

But If I send data to anonymous post method without using ValidateAntiForgeryToken on beck-end It's work. Example:

[AllowAnonymous]
[HttpPost]   
public IActionResult AddItemToStore([FromBody] StoreUser itemsStore)
{
    StoreUser str = new StoreUser
    {

        Id = 1,
        UserId = itemsStore.UserId,
        CatrgoryId = itemsStore.CatrgoryId
    };

    return Ok(str);
}

Screenshots

enter image description here


enter image description here


enter image description here


enter image description here


CodePudding user response:

Before coding, you need be sure the following inputs contain value:

<input type="hidden" name="cardId" id="cardId" /> @{ var getUser = await UserManager.GetUserAsync(User); }
<input type="hidden" name="userId" asp-for="@getUser.Id" />

Two ways you could follow:

1.From Body:

View

<form id="formToStore" method="post" enctype="multipart/form-data">
  <input type="hidden" name="cardId" id="cardId" value="1" /> 
  <input type="hidden" name="userId" value="466788cb-6aab-4798-81f1-f6b05cb71e32"/>

  <div >
    <button type="button" id="buttonclose" name="buttonclose"  data-bs-dismiss="modal">Close</button>

    <button type="button" id="addToOrder" name="addToOrder" >Add to Order</button>
  </div>
</form>
@section Scripts
{
    <script>
        var buttonAddOrder = document.getElementById("addToOrder");    
        buttonAddOrder?.addEventListener("click", function () {
            var catId = document.querySelector("#formToStore input[name = 'cardId']").value;
            var userId = document.querySelector("#formToStore input[name = 'userId']").value;
            var antiForgeryToken = document.querySelector("#formToStore input[name = '__RequestVerificationToken']").value;
            var itemsStore = {
               // __RequestVerificationToken: antiForgeryToken,  //remove this....
               UserId:userId,
               CatrgoryId: catId,
               Payed: false
            };
            var url = "/CategoriesToUser/AddItemToStore";          
            var response = fetch(url, {
                method: 'POST',
                mode: 'cors',
                cache: 'no-cache',
                headers: {
                    'Content-Type': 'application/json',          //change here...
                    "X-ANTI-FORGERY-TOKEN": antiForgeryToken,    //add this.....    
                },
                body: JSON.stringify(itemsStore)          //change here.....                   
            })
            .then((response) => {
                return response.json();
            }).catch((e) => console.log(e.message));

        })
    </script>
}

Controller

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddItemToStore([FromBody] StoreUser itemsStore)
{
    //do your stuff....
    return Ok(itemsStore);
}

Startup.cs:

services.AddAntiforgery(x => x.HeaderName = "X-ANTI-FORGERY-TOKEN");

2.From Form:

View

<form id="formToStore" method="post" enctype="multipart/form-data">

                      @*change name="cardId" to name="CatrgoryId"*@
  <input type="hidden" name="CatrgoryId" id="cardId" value="1" />  
  <input type="hidden" name="userId" value="466788cb-6aab-4798-81f1-f6b05cb71e32"/>
  <div >
    <button type="button" id="buttonclose" name="buttonclose"  data-bs-dismiss="modal">Close</button>
    <button type="button" id="addToOrder" name="addToOrder" >Add to Order</button>
  </div>
</form>
@section Scripts
{
    <script>
        var buttonAddOrder = document.getElementById("addToOrder");
        buttonAddOrder?.addEventListener("click", function () {
        var url = "/CategoriesToUser/AddItemToStore";
        const  formToStore = document.getElementById('formToStore');
        var formOrder = new FormData(formToStore);

        let response = fetch(url, {
            method: 'POST',
            mode: 'cors',
            cache: 'no-cache',
            //headers: {
            //    'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8;'
            //},                             //don't need to set the Content-Type header
            body: formOrder   
        })
            .then((response) => {
                return response.json();
            }).catch((e) => console.log(e.message));

        })
    </script>
}

Controller

Change [FromBody] to [FromForm].

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult AddItemToStore([FromForm] StoreUser itemsStore)
{
    //do your stuff...
    return Ok(itemsStore);
}
  • Related