2
\$\begingroup\$

The problem is, I have to limit the results to only 10 by default and add a "Load More" button to display 10 more results each time when user click the button. But I'm worried about users having their JavaScript disabled, because in that case, users won't be able to see more blogs.

But I can also use MVC Razor Syntax codes to display more results by requesting the URL parameters by a button inside a form and it's also works fine and it's only a few lines of codes, but the only problem is the URL parameters showing in the address bar and I don't want them to be showing up.

Now I'm putting my MVC Razor Syntax codes to inside a <noscript></noscript> tag for JavaScript Backup and it's working perfectly.

What I want to know is there any disadvantage of doing this or if there is any better solution to achieve this. I don't know much about the NoScript tags or how that works with Razor Syntax codes.

.cshtml

<noscript>

    @{
        var rowsNumb = 10;
        var db = Database.Open("Northwind");
        rowsNumb = Request["lastRec"].AsInt() + 10;
        var maxRecs = db.QueryValue("SELECT COUNT([Product Id]) FROM Products");
        var sql = @"SELECT * FROM Products ORDER BY [Product Id] OFFSET 0 ROWS FETCH NEXT @0 ROWS  ONLY";
        rowsNumb = (rowsNumb > maxRecs ? maxRecs : rowsNumb);
        var result = db.Query(sql, rowsNumb);
    }

    <table>
        @foreach(var row in result){
            <tr>
                <td>@row["Product Name"]</td>
                <td>@row["English Name"]</td>
                <td>@row["Unit Price"]</td>
            </tr>
        }
    </table>
    <form>
        <input type="hidden" name="lastRec" value="@rowsNumb" />
        <button type="submit">Load More</button>
    </form>

</noscript>
\$\endgroup\$
3
\$\begingroup\$

Putting your JavaScript alternative in <noscript> is exactly what <noscript> was meant for. There is nothing in the specs that would make this a bad idea.

I have to note that the derivation of rowsNumb in your code is terrible:

    var rowsNumb = 10;   //<- RowsNumb is 10
    var db = Database.Open("Northwind");
    rowsNumb = Request["lastRec"].AsInt() + 10; //No longer 10, but last request + 10
    var maxRecs = db.QueryValue("SELECT COUNT([Product Id]) FROM Products");
    var sql = @"SELECT * FROM Products ORDER BY [Product Id] OFFSET 0 ROWS FETCH NEXT @0 ROWS  ONLY";
    rowsNumb = (rowsNumb > maxRecs ? maxRecs : rowsNumb); //Possibly not last request + 10 ..
    var result = db.Query(sql, rowsNumb);

You could try something like this:

    var db = Database.Open("Northwind");
    var maxRecs = db.QueryValue("SELECT COUNT([Product Id]) FROM Products");
    var rowsNumb = Math.min( Request["lastRec"].AsInt() + 10 , maxRecs )
    var sql = @"SELECT * FROM Products ORDER BY [Product Id] OFFSET 0 ROWS FETCH NEXT @0 ROWS  ONLY";
    var result = db.Query(sql, rowsNumb);

I am also not 100% about your SQL statement, but given that it goes against Nortwind..

\$\endgroup\$
  • \$\begingroup\$ My bad, only the name of database is Northwind, it's not the real the Northwind and my SQL statement works fine, try it yourself. \$\endgroup\$ – Anonymous Aug 23 '14 at 7:32
2
\$\begingroup\$

Any code that runs in Razor syntax will run on the server. The noscript tag is a client control mechanism and is used to help browsers when script is disabled.

Hence, by the time the html code reaches the browser there will be no indication that the razor code was even used. Hence, if view the source of the browser you might see something like.

<noscript>
    <table>
        <tr>
            <td>My product</td>
            <td>My english name</td>
            <td>1.34</td>
        </tr>
    </table>
    <form>
        <input type="hidden" name="lastRec" value="5" />
        <button type="submit">Load More</button>
    </form>
</noscript>

NOTE: There No razor syntax as that has already been evaluated when the server was processing the request and deciding what data to return.

So your code works, yes, because what is returned to the browser end's up being html only (no Razor), not for any other reason. However.....

One issue I noticed was with the html that may be generated. If there are no results from your query, then you run the risk of creating an empty table. I would probably suggest checking the result list and outputting something different if empty. For example:

<noscript>

    @if(result.Any()) {
        <table>
            @foreach(var row in result){
                <tr>
                    <td>@row["Product Name"]</td>
                    <td>@row["English Name"]</td>
                    <td>@row["Unit Price"]</td>
                </tr>
            }
        </table>
        <form>
            <input type="hidden" name="lastRec" value="@rowsNumb" />
            <button type="submit">Load More</button>
        </form>
    } else {
        <span>There are no products</span>
    }

</noscript>

I noticed in your razor you are including your sql and db access. This might be ok if you are just quickly whipping something up, but I think you are mixing the concerns of your view by including database, querying (T-SQL) and view concepts. I would consider instead making your view strongly typed to a ViewModel (or model if ViewModel is overkill) and then only using that. All of that razor syntax would then be evaluated in your controller action.

Essentially then, your view would have no need for this razor syntax at all and your question about whether it's right would be moot.

So yes, there is a disadvantage and something I wouldn't recommend from a best practice and maintainability point of view.

  1. Making your view responsible for knowing the implementation details of fetching data. It should only be responsible for knowing how to show data.
  2. Inability to share that logic in other views
  3. Your view is tied directly to your database. What happened if the source of the data changed i.e. a different table. You would have to change your view

Advantages? I guess it's quick to implement and test. But short turn gain, for possible long term here I think.

\$\endgroup\$
  • \$\begingroup\$ Right now, I'm testing and developing my website with database and plug-ins. I've only 1 table for that and it's not empty. I don't think, I will change the source of the data because I will change the name of the table to Articles and database name to my website's name. I can also use that as Partial View for share that logic in other views. For the 1st point, think about the WebMatrix sites because they do the same things. \$\endgroup\$ – Anonymous Aug 23 '14 at 16:42
  • \$\begingroup\$ @MaryMelody If you search for database logic in views mvc or similiar you will find plenty of recommendations for why not to do this. As for the first point. You can still achieve this by calling a Action method to render the view. \$\endgroup\$ – dreza Aug 23 '14 at 19:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.