1

In my REST Service I have the following: AssetController:

// GET: <AssetController>
[HttpGet("{companyID}/{machineName}")]
public Asset Get(int companyID, string machineName)
{
    Database db = new Database(configuration.ConnectionString);

    //DataSet ds = db.executeFunctionSelect("fngetallassets2()");
    DataSet ds = db.executeViewSelect("tblasset where LOWER(name) = '" + machineName.ToLower() + "'");
    //DataSet ds = db.executeDataSetProc("getallassets", null);            

    DataTable table = ds.Tables[0];
    DataRow row = table.Rows[0];

    Asset asset = new Asset
    {
        ID = int.Parse(row["ID"].ToString()),
        CompanyID = int.Parse(row["Company_ID"].ToString()),
        Name = row["Name"].ToString(),
        IPAddress = row["IP_Address"].ToString(),
        CreateDate = DateTime.Parse(row["Create_Date"].ToString()),
        IsActive = bool.Parse(row["Is_Active"].ToString())
    };

    return asset;
}

This works fine... Its the PUT that I need help with

   // PUT /<AssetController>/5
        // Insert record into the database
        [HttpPut("{asset}")]
        public void Put([FromBody] string asset)
        {
            Database db = new Database(configuration.ConnectionString);
            db.executeNonQuery("sp_AssetInsert", null);
        }

Here I am trying to pass (somehow) the same asset class

In the calling windows forms I use this way to call the PUT Method:

 public void InsertAsset(Asset asset)
        {
            ArrayList parameters = new ArrayList
            {
                asset.Name,
                asset.IPAddress
            };

             RestClient client = new RestClient("https://localhost:5001/Asset/");
             RestRequest request = new RestRequest(Method.PUT);
        request.AddJsonBody(asset);
        IRestResponse<List<string>> response = client.Execute<List<string>>(request);
            if (response.StatusCode == HttpStatusCode.OK)
            {

            }

I get an error on Response.StatusCode = unsupportedmedia or something like this. I need to know how to serialize or somehow pass either the class or the JSON string of it or whatever...

Can someone please help me figure out how to call the PUT methods as I have dozens of these to do.

Chris Dunlop
  • 135
  • 1
  • 13
  • You should probably send the parameters in the body of the request rather than as a route parameter. – SBFrancies Jun 03 '20 at 19:17
  • Second to what @SBFrancies said - The Asset should not be in your path. If you must have the Asset object in your Path you'd need to Base64 encode it atleast to allow the URL to be valid. But please put the Asset payload in your request body. – TeaBaerd Jun 03 '20 at 19:22
  • OT: instead of ToString followed by Parse, you can probably cast those row values to int directly. Much cleaner – Hans Kesting Jun 03 '20 at 20:31
  • `[FromBody] Asset asset`? But don't use Entity Framework entities as DTOs, decouple your database from your API. – CodeCaster Jun 03 '20 at 21:29
  • Asset is a class object, not an entity...I pass class objects around for getting and saving data. – Chris Dunlop Jun 03 '20 at 21:30

2 Answers2

1

Here is the calling and receiving code used to make this work.

calling:

RestClient client = new RestClient("https://localhost:5001/Asset/");

            RestRequest request = new RestRequest(Method.PUT);
            request.AddJsonBody(asset); <-- Asset is a class object
            RestResponse response = (RestResponse)client.Execute(request);
            if (response.StatusCode == HttpStatusCode.OK)
            {

            }

Receiving Code:

// PUT /<AssetController>/5
        // Insert record into the database
        [HttpPut]
        public void Put([FromBody] Asset asset)
        {
            Database db = new Database(configuration.ConnectionString);
            db.executeNonQuery("sp_AssetInsert", null);
        }

I needed to change the [FromBody] string asset to [FromBody] Asset asset

Chris Dunlop
  • 135
  • 1
  • 13
0

There are several ways to pass parameters:

  1. as url route i.e. https://localhost:5001/Asset/42/MyCompanyName
  2. as url parameter http:// localhost:5001/Asset?companyID=42&machineName=companyname
  3. in body, typically as a json serialized object

when you specify the route in [HttpPut("{paramaters}")] you are specifying option 1. You can use FromBody and FromUrl attributes on the parameter to control this. Simple parameters like numbers and string would typically be part of the URL, while complex objects like Asset will probably be easier to pass in the body.

See also

JonasH
  • 28,608
  • 2
  • 10
  • 23
  • I would like more information on how to pass the asset object: Here is the code I am using to try to pass the asset object RestClient client = new RestClient("https://localhost:5001/Asset/"); RestRequest request = new RestRequest(Method.PUT); request.AddHeader("Accept", "application/json"); request.AddJsonBody(asset); RestResponse response = (RestResponse)client.Execute(request); if (response.StatusCode == HttpStatusCode.OK) { } I have updated the code in the above text. – Chris Dunlop Jun 03 '20 at 21:07