0

I am new to web api in general and I am having problems with web api core when it comes to creating a new database entry using POST. The ajax call looks like;

addSelectedContract = function (contractId, url, callback) {
        // hard code url to get working
        url = "http://localhost:17972/api/selectedcontracts";
        var contract = JSON.stringify({ contractId: contractId });
        $.ajax({
            type: "Post",
            url: url,
            data: contract,
            contentType: "application/json"
        }).done(callback(status));
        };

My API method looks like;

namespace Properties.API.Controllers
{
    [Route("api/selectedcontracts")]
    public class SelectedContractController : BaseController
    {
        private readonly ISirUoW SirUoW;
        private readonly SirDb Db;

        public SelectedContractController(SirDb db, ISirUoW repo, Services.IMailService mailService)
            : base(mailService)
        {
            this.Db = db;
            this.SirUoW = repo;
        }

        [HttpPost()]
        public IActionResult Post([FromBody] SelectedContract contract)
        {
            try
            {
                this.SirUoW.SelectContract.Add(contract);
                return Ok(new OperationStatus
                {
                    Status = true,
                    OperationID = contract.SelectedContractId
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                var status = Mapper.Map<OperationStatus>(e);
                return Ok(status);
            }
        } 

My test from powershell gives this result;

Invoke-RestMethod http://localhost:xxxx/api/selectedcontracts -Method POST -Body (@{contractId="7"} | ConvertTo-Json) -ContentType "application/json"
[ERROR] Invoke-RestMethod : The remote server returned an error: (500) Internal Server Error.
[ERROR] At line:1 char:1
[ERROR] + Invoke-RestMethod http://localhost:xxxx/api/selectedcontracts -Method POST -Bod ...
[ERROR] + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[ERROR]     + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke- 
[ERROR]    RestMethod], WebException
[ERROR]     + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRes 
[ERROR]    tMethodCommand
[ERROR]  

The SelectedContract class is defined as; namespace SIR.Domain.Poco { using Interfaces; using System; using System.ComponentModel.DataAnnotations;

public class SelectedContract : IAuditCreated
{
    [Key]
    public int SelectedContractId { get; set; }

    public int ContractId { get; set; }

    public DateTime Created { get; set; }

    [MaxLength(50)]
    public string CreatedBy { get; set; }
}

} I have searched around for example code and I cannot see what I am doing wrong.

EDIT: I have made a change although I get the same result. The SelectedContract class is defined as;

    namespace SIR.Domain.Poco
    {
        using Interfaces;
        using System;
        using System.ComponentModel.DataAnnotations;

        public class SelectedContract : IAuditCreated
        {
            [Key]
            public int SelectedContractId { get; set; }

            public int ContractId { get; set; }

            public DateTime Created { get; set; }

            [MaxLength(50)]
            public string CreatedBy { get; set; }
        }
    }

However I am only sending one the fields, the ContractId. I do not want to send the primary key or the audit fields. So I have created a DTO class;

    namespace Properties.API.Models
    {
        public class SelectedContractDto
        {
            public int ContractId { get; set; }
        }
    }

And changed the signature of my Post method in the API;

        [HttpPost()]
        public IActionResult Post([FromBody] SelectedContractDto contract)
        {
            var selectedContract = new SelectedContract { ContractId = Convert.ToInt32(contract.ContractId) };
            try
            {
                this.SirUoW.SelectContract.Add(selectedContract);
                return Ok(new OperationStatus
                {
                    Status = true,
                    OperationID = selectedContract.SelectedContractId
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                var status = Mapper.Map<OperationStatus>(e);
                return Ok(status);
            }
        }

Still get the 500 Internal Server Error. I had a look in Fiddler and found this error as well

An unhandled exception occurred while processing the request.
InvalidOperationException: 'Microsoft.AspNetCore.Mvc.MvcOptions.InputFormatter c2 s' must not be empty. At least one 'Microsoft.AspNetCore.Mvc.Formatters.IInputFormatter' is required to bind from the body.
Microsoft.As fdc pNetCore.Mvc.ModelBinding.Binders.BodyModelBinderProvider.GetBinder(ModelBinderProviderContext context)

I cant find anything about this error online.

1 Answer 1

0

I assume that you call is hitting method but after that there is error which is not shown in try-catch block? Check "Common Language Runtime Exceptions" in Debug -> Windows -> Exception Settings and try again.

Post result.

Sign up to request clarification or add additional context in comments.

3 Comments

please add a structure of SelectedContract class and update your question. also read this and make sure that you are using [FromBody] properly.
read this and try to manipulate a little your ajax request and use your contract object without JSON.stringify() method
I am not making any headway, although I notice that the question you link to is for web api rather than web api core. Are they the same for POST methods on an API?

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.