1

I'm trying to POST data but I can't seem to grasp the idea well. Followed instructions for posting data from google and Stack Overflow sources with no luck.

Still new to this and wished I knew people in real life to explain how to do it step by step. Really appreciate your help.

Here is what I have so far:

Models:

Customer.cs:

using System.Collections.Generic;

namespace Project.Models
{
    public class Customer
    {
       public string CustomerId { get; set; }
       public string FirstName { get; set; }
       public string LastName { get; set; }
       public string DateOfBirth { get; set; }
    }
} 

Order.cs:

using System.Collections.Generic;

namespace Project.Models
{
   public class Order
   {
       public string OrderId { get; set; }
       public string Product { get; set; }
       public string Status { get; set; }
       public double Price { get; set; }
       public string CustomerId { get; set; }
   }
}

Repositories:

using System.Collections.Generic;
using System.Linq;
using Project.Models;
using System.Net;
using System.Collections.Specialized;
using System.Text;


namespace Project.Repositories
{
   public class OrderRepository
   {

       private static List<Order> ORDERS;

       static OrderRepository()
       {
           ORDERS= new List<Order>();

           ORDERS.Add(new Order
           {
               CustomerId = "123",
               OrderId = "124",
               Product= "Shirts",
               Status= "On it's way",
               Price= 100.20,
           });

           ORDERS.Add(new Order
           {
               CustomerId = "123",
               OrderId= "122",
               Product= "Pants",
               Status= "Not ready",
               Price= 300.30,
           });

           ORDERS.Add(new Order
           {
               CustomerId = "789",
               OrderId= "143",
               Product= "Deadpool",
               Status= "On it's way",
               Price= 6.20,
           });

           ORDERS.Add(new Order
           {
               CustomerId = "578",
               OrderId= "156",
               Product= "Socks",
               Status= "Not ready",
               Price= 3.30,
           });

           // Not sure if this POST method should be placed here
           using (var client = new WebClient())
           {
              var values = new NameValueCollection();
              values["CustomerId"] = "578";
              values["OrderId"] = "156";

              var response = client.UploadValues("http://localhost:5000/customers/{CustomerID}/orders/{OrderId}/overview", values);

              var responseString = Encoding.Default.GetString(response);
           }

     }



     public static Order GetByOrderid(string customerId, string orderId)
     {
        return ORDERS
          .Where(x => x.CustomerId == customerId)
          .Where(x => x.OrderId== orderId)
          .SingleOrDefault();
     }

     public static List<Order> GetAllOrders(string customerId)
     {
        return ORDERS.Where(x => x.CustomerId == customerId).ToList();
     }
  }
}

Controllers:

OrderController.cs:

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Project.Models;
using Project.Repositories;

namespace Project.Controllers
{
   public class OrderController : Controller
   {
      [HttpGet("customers/{id}/orders/{orderId}")]
      public Order FindOneOrder(string customerId, string orderId)
      {   
          return OrderRepository.GetByOrderid(customerId, orderId);
      }

      [HttpGet("customers/{id}/orders")]
      public List<Order> GetCustomerOrders(string customerId)
      {
          return OrderRepository.GetAllOrders(customerId);
      }
    }
 }

Update OrderController:

[HttpPost("customers/{customerId}/orders/{orderId}/overview")]
public async Task<IAsyncResult> Post([FromRoute] string customerId, string orderId, string status, [FromBody] Order order)
{
     OrderRepository.SaveNewOrder(customerId, caseId, status, order);

     //all that is left is to return something, based on what you need.
     //a good return for this method is HTTP 201 - Created
     return CreatedAtAction(nameof(FindOneOrder), new { customerId = customerId, orderId = orderId}, order);
}

Update OrderRepository:

public static void SaveNewOrder(string customerId, string orderId, string status, Order order)
{
     order.CustomerID = customerId;
     order.OrderId= orderId;
     order.Status= status;
     Order.Add(order);

     //here you should also call any web service that does the saving
     //or store to the database, depending on your business logic
}
Niknak
  • 583
  • 1
  • 8
  • 22
  • What is the route you are trying to post data to? – PmanAce Jun 27 '18 at 17:27
  • I didn't see the post method on controller. This is a good start with you want to learn https://learn.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with-aspnet-web-api/tutorial-your-first-web-api – Pankwood Jun 27 '18 at 17:28
  • @PmanAce this one:"http://localhost:5000/customers/{CustomerID}/orders/{OrderId}/overview" – Niknak Jun 27 '18 at 17:28
  • @DaniloDebiaziVicente Is that what I'm missing? I have not seen that explained anywhere from what I have been reading. – Niknak Jun 27 '18 at 17:29
  • 2
    You haven't defined a POST action (you show two GET) therefore 404 Not Found. – Jasen Jun 27 '18 at 17:30
  • In any browser F12 is your friend. Click on the network tab to evaluate your local trafic. – Ole EH Dufour Jun 27 '18 at 17:33
  • @Jasen How do I define it since it's different from GET? I have not seen examples of how to do it. – Niknak Jun 27 '18 at 17:35
  • @Niknak https://stackoverflow.com/a/4015346/4180382 (Method D: WebClient (Also now legacy)) – Ole EH Dufour Jun 27 '18 at 17:36
  • 1
    First of all, there's no need to go back out to make a http request if you're trying to reach a controller in the same app -- move the code out of the controller to a common class shared by the controllers. Second, the route you're attempting looks like it belongs to a different (Customer) controller than the one you've shown us (Order). Use `[HttpPost]` to define a POST action. – Jasen Jun 27 '18 at 17:39
  • If I recall correctly, your parameter names need to match the placeholders in the route. E.g., in your first method, `caseId` should be named `orderId`. So after you get the route correct (use `HttpPost` attribute, or use a GET request from the client), you'll likely get null values from the client. – ps2goat Jun 27 '18 at 17:45
  • @ps2goat Ops typo, sorry =) – Niknak Jun 27 '18 at 17:47
  • and the same with `id` vs `customerId` – ps2goat Jun 27 '18 at 20:19

1 Answers1

0

In your OrderRepository, your first need to add a way to store new orders.

public static void SaveNewOrder(string customerId, Order order)
{
    order.CustomerId = customerId;
    ORDERS.Add(order);

    //here you should also call any web service that does the saving
    //or store to the database, depending on your business logic
}

Then, in your OrderController, add another method:

 [HttpPost("customers/{id}/orders")]
 public async Task<IAsyncResult> Post([FromRoute] string id, [FromBody] Order order)
 {
       OrderRepository.SaveNewOrder(id, order);

       //all that is left is to return something, based on what you need.
       //a good return for this method is HTTP 201 - Created
       return CreatedAtAction(nameof(FindOneOrder), new { id = customerId, orderId = order.OrderId}, order);
 }

I reccomend that you use [HttpPost] for new orders and [HttpPut] to update an existing order:

[HttpPut("customers/{id}/orders/{orderId}")]
public async Task<IAsyncResult> Put([FromRoute] string id, [FromRoute] string orderId, [FromBody] Order order)
{
    //do some work, like updating the order with the id {orderId} 
    //for the customer with the {id} in the URL.
}

Also, your FindOneOrder and GetCustomerOrders have different parameters in the route than the ones defined in the prototype. Make sure that you either use {id} or {customerId} in both places.

Ovi
  • 2,620
  • 7
  • 34
  • 51
  • How does that go with the POST method in OrderRepository.cs? I am not sure how to save it so it appears on the client site. And the route should be: "customers/{CustomerId}/orders/{OrderId}/overview" – Niknak Jun 27 '18 at 18:04
  • You don't have a Save action in your `OrderRepository`, that needs to be implemented separately and called from the Post/Put methods in the controller, just like you are doing it now for the `FindOneOrder` and `GetCustomerOrders` – Ovi Jun 27 '18 at 18:48
  • Now I'm confused xD Sorry trying to understand your concept. – Niknak Jun 27 '18 at 18:51
  • The code isn't that maintanable, i'll edit my answer above with a quick sample. – Ovi Jun 27 '18 at 18:53
  • Hmm..getting this error on return of CreatedAction: The name 'FindOneOrder' does not exist in the current context – Niknak Jun 27 '18 at 19:21
  • @Niknak naming the controller method `PostFindOneOrder` instead of `Post` should resolve correctly – ps2goat Jun 27 '18 at 20:21
  • @Niknak - post your updated code, there must be an error somewhere. For now, while you are still testing things out you could just `return Ok();` instead of the `return CreatedAtAction...` – Ovi Jun 27 '18 at 20:36
  • @Ovi Updated now, see above. – Niknak Jun 27 '18 at 20:45
  • @Ovi error on return of CreatedAction: The name 'FindOneOrder' does not exist in the current context..still the same xD – Niknak Jun 28 '18 at 16:12
  • @Ovi also updated OrderRepository.cs in case I have done anything wrong there =p see above. – Niknak Jun 28 '18 at 16:24
  • @Niknak, just do: `return Ok();` and it should work, the `CreatedAtAction` is just a quirck for better API design. You can safely ignore that part. Just test functionality. – Ovi Jun 28 '18 at 18:53
  • @Ovi I'm getting 404 error in return and i also changed **async Task** to **IActionResult** – Niknak Jun 28 '18 at 20:00
  • 404 means it’s not finding the method. Can you post the code from the view or where are you making the call? – Ovi Jun 29 '18 at 05:11
  • @Ovi oh sorry I thought you hadn't answere me. Above you will see trhe controller is calling to "SaveNewOrder" from repository. I may doing something wrong here but not sure what it is. Just trying to following your guidance. Sorry for late reply =p – Niknak Jul 01 '18 at 17:11