locked
Razor Pages - Access value from cshtml in codebehind RRS feed

  • Question

  • User-69881190 posted

    Hello all.  Most of my development experience has been inWebforms in asp.NET, and I am trying to figure out how to use Razor Pages and .net Core.  I have designed a web page that is pulling order data from a SQL database hosted in AWS, then accessing an external site via API to find shipping information regarding that order.  I have all the data connections setup and working correctly, but I am am having a hard time trying to understand how to get the two pieces to work together.  I have hard coded an order number in the code behind to find the correct shipping information to display, but I do not not how to wire up the code to find the data dynamically from the cshmtl page.  In the code below, I am searching the API response for a route named 90 and searching the notes for order number 123456.

    I have coded the API call in the OnGetAsync() task in the code behind.  I assume this is the correct way to do this.

    Here is the code I am using in the code behind.

           public async Task OnGetAsync()
            {
                var acks = from m in _context.Acknowledgement
                             select m;
                acks = acks.Where(s => s.AckNumber.Equals(SearchString) || s.CustomerPO.Equals(SearchString));
    
                Acknowledgement = await acks.ToListAsync();
    
                using (var httpClient = new HttpClient())
                {
    
                    using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://apicall.url"))
                    {
                        request.Headers.TryAddWithoutValidation("Accept", "application/json");
                        
                        var response = await httpClient.SendAsync(request);
                        string json = response.Content.ReadAsStringAsync().Result;
                        var objResponse1 = JsonConvert.DeserializeObject<List<Routes.Root>>(json);
                        
                        var result =
                            from r in objResponse1
                            from s in r.dispatch_jobs
                            where r.name.Equals("90") && s.notes.Contains("123456")
                            select new { Name = r.name, ID = r.id, Stops = s.destination_name, Lat = s.destination_lat.ToString(), Lng = s.destination_lng.ToString(), Addr = s.destination_address, SchTime = s.scheduled_arrival_time_ms };
    
                        foreach (var str in result)
                        {
                            RouteName = str.Name;
                            DestinationLat = str.Lat;
                            DestinationLng = str.Lng;
                            DestinationAddress = str.Addr;
    
                            Maplink = "https://maps.google.com/maps?q=" + DestinationLat + "," + DestinationLng + "&output=svembed";
    
                        }
                    }
                }
            }


    Here is the cshtml page code

    @page "{searchString?}"
    @model sandbox.Pages.Acks.IndexModel
    
    @{
        ViewData["Title"] = "Index";
    }
    
    <head>
        <style>
            .table td{
                border: 0px solid lightgray;
            }
    
            .acktext {
                font-weight: bold;
                width: 135px;
            }
        </style>
    </head>
    
    <table class="table">
        <tbody>
            @foreach (var item in Model.Acknowledgement)
            {
            <tr>
                <td class="acktext">
                    Ack Number
                </td>
    
                <td>
                    @Html.DisplayFor(modelItem => item.AckNumber)
                </td>
                <td class="acktext">
                    Customer PO
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.CustomerPO)
                </td>
            </tr>
            <tr>
                <td class="acktext">
                    Address
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.ShipAddress1)
                    @Html.DisplayFor(modelItem => item.ShipAddress2)
                    @Html.DisplayFor(modelItem => item.ShipCityState)
                </td>
                <td class="acktext">
                    Samsara Address
                </td>
                <td>
                    @Model.DestinationAddress
                </td>
            </tr>
    
            <tr>
                <td class="acktext">
                    Scheduled Arrival Time
                </td>
                <td>
                    @Model.ScheduledArrivalTime
                </td>
                <td class="acktext">
                    Route Number
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Route)
                </td>
            </tr>
                <tr>
                    <td class="acktext">
                        API Data
                    </td>
                    <td>
                        @Model.Apidata
                    </td>
                </tr>
                <tr>
                    <td colspan="4" align="center">
                        <iframe src=@Model.Maplink width="450" height="338" frameborder="0" style="border:0;" allowfullscreen="" aria-hidden="false" tabindex="1"></iframe>
                    </td>
                </tr>
            }
        </tbody>
    </table>

    Any help would be greatly appreciated!

    Friday, February 19, 2021 3:47 AM

Answers

  • User-69881190 posted

    I was able to solve this issue.  Thank you both for your suggestions.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, February 20, 2021 4:44 AM

All replies

  • User1120430333 posted

    IMHO, you have too much going on in the page behind. You are doing direct database access in the page behind. You are not implementing SoC. Razor page is still using the MVC pipeline. And the VS project  layout for a Razor page project is still ASP.NET MVC. With that being said, here are a few things to consider in architectural design.

    Separation of concerns - Wikipedia

    Understanding Separation Of Concern in ASP.NET MVC (c-sharpcorner.com)

    Architectural principles | Microsoft Docs

    Kinds of Models | DevIQ

    Layered or N-tier

    Chapter 3: Architectural Patterns and Styles | Microsoft Docs

    Understanding ViewModel in ASP.NET MVC (dotnettricks.com)

    A DTO travels through layers or tiers.

    Data Transfer Object Design Pattern in C# - CodeProject

    The DAO pattern.

    Data Access Object (DAO) design pattern in Java - Tutorial Example (javarevisited.blogspot.com)

    Again the Razor page project layout in Visual Stuido is an ASP.NET MVC project layout.

    Understanding Models, Views, and Controllers (C#) | Microsoft Docs

    <copied>

    An MVC model contains all of your application logic that is not contained in a view or a controller. The model should contain all of your application business logic, validation logic, and database access logic. For example, if you are using the Microsoft Entity Framework to access your database, then you would create your Entity Framework classes (your .edmx file) in the Models folder.

    A view should contain only logic related to generating the user interface. A controller should only contain the bare minimum of logic required to return the right view or redirect the user to another action (flow control). Everything else should be contained in the model.

    In general, you should strive for fat models and skinny controllers. Your controller methods should contain only a few lines of code. If a controller action gets too fat, then you should consider moving the logic out to a new class in the Models folder.

    <end>

    All of it can be applied to a Razor page project that is an ASP.NET MVC project layout in Visual Stuido.

    And all of what I have shown with other links can be applied in a Razor page project.

    domain model = DM and view model = VM for the classes you see in the Models folder.

    Here is a Razor Page solution implementing the things I have shown that you can examine . One project was named wrong and it Razor not Blazor. The solution is using a layered style.

    darnold924/PubCompanyCore3.x (github.com)

    HTH

    Friday, February 19, 2021 6:22 AM
  • User1686398519 posted

    Hi gollumthegodfather, 

    not not how to wire up the code to find the data dynamically from the cshmtl page

    Do you want to pass data from the page to the backend?Or do you want to get the data on the page in the backend?

    In this case, you meed to learn about model binding.

    1. For example, route data may provide a record key, and posted form fields may provide values for the properties of the model.
    2. In general, you need to write code to retrieve each of these values ​​and convert them from strings to .NET types, but model binding automates the process.
    3. You can click the link below to help you understand.

    Best Regards,

    YihuiSun

    Friday, February 19, 2021 3:07 PM
  • User-69881190 posted

    Thank you both for the responses.  I am going through the links you both provided to try to determine what my next steps are.

    Do you want to pass data from the page to the backend?Or do you want to get the data on the page in the backend?

    I have the page setup to query data from a SQL database to display information related to an order number.  In the code behind, I am trying to access the order number and the trip number to use to return shipping data from a shipping website via an API call.  I am trying to figure out how to pass the order number and trip number to the code in order to grab the correct data from the json response.

    Friday, February 19, 2021 6:25 PM
  • User-69881190 posted

    I was able to solve this issue.  Thank you both for your suggestions.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, February 20, 2021 4:44 AM