0

In ajax if I write: data: JSON.stringify(cat) i get this error: The JSON value could not be converted to System.Collections.Generic.IEnumerable and if I write: data: cat I get this error: 'i' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0. So, I guess I'm doing something wrong with json but what?

Here are the relevant classes for category:

Area.Identity.Data.Category:

public class Category
    {
        //----------------------------------------------------
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }
        //----------------------------------------------------
        public string Name { get; set; }
 
        //----------------------------------------------------
        public ICollection<Post> Posts { get; set; }

        public Category(string name)
        {
            Name = name;
        }
    }

Models.Category:

 public class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }
 
        public Category(int id, string name)
        {
            Id = id;
            Name = name;
        }

    }

CategoryMapper.cs:

 public class CategoryMapper
    {
        public static Models.Category FromDatabase(Areas.Identity.Data.Category cat)
        {
            return new Models.Category
            (
                cat.Id,
                cat.Name
            );
            
        }
        
        public static Areas.Identity.Data.Category ToDatabase(Models.Category cat)
        {
            return new Areas.Identity.Data.Category
            (
                //id is database generated
                cat.Name
            );
        }
    }

CategoryRepository.cs:

public class CategoryRepository
    {
        private readonly MyContext _context;

        public CategoryRepository(MyContext context)
        {
            _context = context;
        }

        public IEnumerable<Models.Category> GetAll()
        {
            return _context.Category.Select(x => CategoryMapper.FromDatabase(x));
        }

        public void Save(Models.Category category)
        {
            _context.Category.Add(CategoryMapper.ToDatabase(category));
            _context.SaveChanges();
        }
    }

CategoryService.cs:

public class CategoryService
    {
        private CategoryRepository _catRepository;
        public CategoryService(CategoryRepository catRepository)
        {
            _catRepository = catRepository;
        }

        public IEnumerable<Models.Category> GetAll()
        {
            return _catRepository.GetAll();
        }

        public void Save(Models.Category cat)
        {
            _catRepository.Save(cat);
        }

    }

CategoryController.cs:

 public class CategoryController : Controller
    {
        
        // GET: Category
        public ActionResult Index()
        {
            return View();
        }

        // GET: Category/Details/5
        public ActionResult Details(int id)
        {
            ViewBag.ID = id;
            return View();
        }

        // GET: Category/Create
        public ActionResult Create()
        {
            return View();
        }

        // POST: Category/Create
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult Create(IFormCollection collection)
        {
            return View();
           
        }
   }

CategoryApiController.cs:

    [Route("api/category")]
    [ApiController]
    public class CategoryApiController : ControllerBase
    {
        private CategoryService _catService;

        public CategoryApiController(CategoryService catService)
        {
            _catService = catService;
        }


        [HttpGet]
        public ActionResult<List<Models.Category>> Get()
        {
            return _catService.GetAll().ToList();
        }

        [HttpGet("{id}")] // api/category/0
        public ActionResult<Models.Category> Get(int id)
        {
            return _catService.GetAll().ToList().Find(x => x.Id == id);
        }

        [HttpPost]
        //[Route("/api/category/save")]
        public IActionResult Save([FromBody] JObject json)
        {
            Models.Category c= CategoryDto.FromJson(json);
            _catService.Save(c);
            return Ok();
        }
    }

CategoryDto.cs:

 public static class CategoryDto
    {
        public static Models.Category FromJson(JObject json)
        {
            var id = json["id"].ToObject<int>();
            var name = json["name"].ToObject<string>();

            return new Models.Category(id, name);
        }
    }

Create.cshtml:

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf
@functions{
    public string GetAntiXsrfRequestToken()
    {
        return Xsrf.GetAndStoreTokens(Context).RequestToken;
    }
}

<h2>Create New Category </h2>

<table id="table">
    <thead id="table-head"></thead>
    <tbody id="table-body"></tbody>
</table>


<form class="AddCategory">
    <div class="form-group">
        <div class="form-group">
            <input required="" id="cat_input" class="form-control" />
            <span class="text-danger"></span>
        </div><!-- .form-group -->
        <div class="form-group">
            <label>Input category name:</label>
            <input type="button" value="Add new category value" class="btn btn-primary addCategory" />
        </div><!-- .form-group -->
    </div><!-- .form-group -->
</form>


<script type="text/javascript">

    'use strict';

    function createRow(JsonObj) {
        let row = document.createElement('tr');

        let cellId = document.createElement('td');
        cellId.innerHTML = JsonObj.id;

        let cellName = document.createElement('td');
        cellName.innerHTML = JsonObj.name;

        row.appendChild(cellId);
        row.appendChild(cellName);

        return row;
    }

    function createHeader(JsonObj) {
        let keys = Object.keys(JsonObj);
        let row = document.createElement('tr');
        for (let i = 0; i < keys.length; i++) {
            const item = keys[i];
            var cell = document.createElement('th');
            cell.innerHTML = item;
            row.appendChild(cell);
        }


        return row;
    }

    async function getAll() {
        return await axios.get('/api/category');
    }

    function afterGetAll(response) {
        console.log(response.data);
        document.getElementById('table-head').appendChild(createHeader(response.data[0]));
        for (let i = 0; i < response.data.length; i++) {
            const item = response.data[i];
            document.getElementById('table-body').appendChild(createRow(item));
        }

        //Add New Category
        $('.addCategory').on('click', function () {
            var cat_input = $('#cat_input').val();
            var _id = parseInt(response.data.length + 1);
            var cat = { id: _id, name: cat_input };
            console.log(cat);
            $.ajax({
                type: 'POST',
                contentType: 'application/json; charset=utf-8',
                url: '/api/category',
                dataType: 'json',
                data: JSON.stringify(cat),
                /*beforeSend: function (xhr) {
                    xhr.setRequestHeader("XSRF-TOKEN",
                        $('input:hidden[name="__RequestVerificationToken"]').val());
                },*/
                 headers: {
                        "RequestVerificationToken": '@GetAntiXsrfRequestToken()'
                    },
                success: function () {
                        console.log('ok');
                    },
                error: function () {
                        console.log('not ok');
                    }
                });
        });

    }

    $(document).ready(function () {

        getAll().then(response => afterGetAll(response));

    });

</script>

1 Answer 1

1

JObject works in previous version of ASP.NET Core 3, if you want to use it in 3.0 or later version, you have to download the package:

Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson -Version 3.1.6

Enable it in Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers().AddNewtonsoftJson();
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.