0

I've done a POST request with the HTTPClient class but now I'm struggling a bit. How can I achieve displaying it on my website? The goal is to post a json ( currently in a string) and then display it on the site again. As you can see my POST command goes to the home controller in mvc and then the about action. How can I now get the data and return it to a view?

public ActionResult About(string json)

Does adding paramters like this work? And if so how do I do it properly?

This is the method call:

post(JsonConvert.SerializeXmlNode(pack));

This is the method itself:

async Task post(string jsonText)
{
                    // Create a New HttpClient object and dispose it when done, so the app doesn't leak resources
      using (HttpClient client = new HttpClient())
      {
      // Call asynchronous network methods in a try/catch block to handle exceptions
          try
          {
               StringContent json = new StringContent(jsonText, Encoding.UTF8, "application/json");
               HttpResponseMessage response = await client.PostAsync("http://localhost:60000/home/about", json);
               response.EnsureSuccessStatusCode();
               string responseBody = await response.Content.ReadAsStringAsync();
               // Above three lines can be replaced with new helper method below
               // string responseBody = await client.GetStringAsync(uri);

               Console.WriteLine(responseBody);
               }catch (HttpRequestException e)
               {
                    Console.WriteLine("\nException Caught!");
                    Console.WriteLine("Message :{0} ", e.Message);
               }
           }
      }

Update

How can i give the PostAsync command my own class? It forces me give it a HttpContent.

As suggested i have created a new method to cache the whole data but what parameter do i have to give the method which saves the data to receive the class or httpcontent? (in the controller)

 [HttpPost]
        public HttpResponseMessage Data(//What parameter?)
        {
            //SaveData

            return new HttpResponseMessage(HttpStatusCode.OK);

        }
Peter K
  • 39
  • 2
  • 11
  • If you have the data, deserialize it and send it to the view as a view model? – JamesS Mar 21 '19 at 14:03
  • `public ActionResult About(string json) { return View(new ViewModel { Json = json }); }` I tried it like this with a viewmodel which has a string as property but the string is always null – Peter K Mar 21 '19 at 14:09
  • So when you call the About method and pass in the string, you're trying to return that string back to where it came from ? – Wayne Feltham Mar 21 '19 at 14:15
  • It maybe was a bit unclear the post method is from a console application in the same solution and the about method is on the mvc web application of the solution. Im trying to pass the data from the console application to the about controller and then return it to a view – Peter K Mar 21 '19 at 14:19

2 Answers2

1

So your question would be better asked as "How do I return json from an MVC Controller" I think. If that's the case then take a look at this...

ASP.NET MVC controller actions that return JSON or partial html

UPDATE #1

So I think the OP is actually trying to post from a console app and then be able to view the json that was sent from that console app within a website?

OP, When the console app posts the data, that's a single request with no persistence of the data unless YOU persist it. You would need to store that json string somewhere. Depending on the need, this could be a DB or some cache.

You would then need to amend your About method to retrieve the json from that storage location, deserialise it and return it within the ViewModel.

Alternatively, you could swap out the About method for an API call that simply retrieves the json and returns it - then you would need to implement a client-side get from your web page to retrieve the json from the api and display it.

Various options, various pros & cons to all of them and all dependant upon your requirements.

UPDATE #2

Further to OP adding a comment to this answer...

I would suggest you define the data that is going to posted between the Console application and your MVC application - don't just use a string. I would suggest adding a third project as a class assembly and define this class in here. You can then add a reference to this new project in both the Console project and the MVC project so that they can both reference the new class.

You currently have two uses of your About method, your Console app is POSTING data and your View is GETTING data - you should separate these things into two separate Methods and decorate each with appropriate attributes [HttpPost] and [HttpGet].

Update your Console application to use your new class, serialise it and post it similar to how you're currently doing it - the url should use the method from above decorated with the [HttpPost].

Adjust your [HttpPost] method to take the object you posted and store it somewhere. I get the impression this is a basic project or even a POC so just cache it for now. Here's an article about caching

Cache in-memory in ASP.NET Core

You may want to put the requests into a collection (List) and keep the collection itself in the cache - this will depend on what you need to display in your webpage.

In you [HttpGet] method, you now need to retrieve everything from the cache and pass it into your ViewModel - as you should now have a nice MyClass object (or List) this should be straight forward to render - in fact VS will likely generate the view for you!

There's really far too much to go into in this thread but hopefully this helps. I don't think it's going to be possible to post entire code samples unfortunately.

Hopefully while not the answer you may have been looking for, it'll help.

UPDATE #3

Ok - I've created a solution that should demonstrate what you need to do.

I'm sure there are other/better ways to do what you want to do BUT...hopefully this will help you understand the concepts.

https://github.com/dotnetter/ConsoleHttpExample

Just clone the repo and configure in VS to run both the website and the console app.

Wayne Feltham
  • 541
  • 4
  • 14
  • ...I've just re-read your last comment and I'm actually more confused. Are you saying you want to update a web page within your application based on the postings from a Console application? So User A opens a web browser and views the About page, meanwhile User B fires up a console application that sends a message to the web site, this does something and User A can see the results of that? – Wayne Feltham Mar 21 '19 at 14:29
  • the update u wrote is correct, what im exactly struggling with right now is how i can access the data from the post request to store somewhere after. I don't know how to access the posted data. – Peter K Mar 21 '19 at 14:59
  • I've updated my answer to offer some guidance. I would definitely define a common object (namely what you're posting from the Console app to the Website). You can then grab the object and just put it into the cache. – Wayne Feltham Mar 21 '19 at 16:16
  • thanks alot. ur answer helped me understand it alot more. However i still have a few small issues, i posted them in an update in my post. Thanks in advance for an answer :) – Peter K Mar 22 '19 at 08:42
  • Thanks again for the example project, I've understod it now and u were able to clear out all misconceptions. Thanks for your help :) – Peter K Mar 27 '19 at 14:56
0

you should access json data like this :

public ActionResult Insert(dynamic[] dynamicClass)
    {

        try
        {
            //do something...

var movie = //convert dynamicClass to whatever you want...  ;
             return View(movie);

        }
        catch (Exception ex)
        {
            // Otherwise return a 400 (Bad Request) error response
            return BadRequest(ex.ToString());
        }


    }

and for your question how to use in the view, its up to you. basiclly if youre using MVC your can store it in some class and use it like this(in cshtml file):

@model MvcMovie.Models.Movie

@{
    ViewData["Title"] = "Details"; 
}

<h1>Details</h1>

<div>
    <h4>Movie</h4>
    <hr />
    <dl class="row">
       <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Title)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Title)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.ReleaseDate)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.ReleaseDate)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Genre)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Genre)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Price)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Price)
        </dd>
    </dl>
</div>
Eran Peled
  • 767
  • 6
  • 6