Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie
Hi all,
Vanilla are planning an update to the site on April 24th (next Wednesday). It is a major PHP8 update which is expected to boost performance across the site. The site will be down from 7pm and it is expected to take about an hour to complete. We appreciate your patience during the update.
Thanks all.

MVC4 question, displaying data in a grid...

Options
  • 13-06-2014 11:05pm
    #1
    Closed Accounts Posts: 1,143 ✭✭✭


    Hi folks,

    I'm in the very early stages of learning MVC, I have a lot of previous experience using ASP Webforms, where I regularly used data presentation tools that were basically provided out of the box in webforms, in particular I use a lot of GridView and DetailsView solutions...

    Now I'm using MVC to develop a mobile website for my company, I previously used Webforms to develop a desktop website, but I want to merge the two tasks that I have at hand, (wanting to learn MVC and having to develop a mobile website for my business)...

    I've developed a simple mobile website which I've built and uploaded onto the web and it works fine and I'm learning by tinkering around with that. I'm moving now from the displaying text and images stage, (the "hello world!" phase!), to now trying to develop a simple solution where I build a simple form and put in a product ID, say "9" into a textbox, use a submit button, and I get back the data relating to that particular product.

    To start with, I just want to wire up my page to a very small database and display a row of data in the format below...

    Tonight I've used WebGrid to do this, which is kind of like what I would have used GridView for when I was using Webforms, in that it gives you a list of columns ordered left to right on the page, and a list of data rows sorted from top to bottom on the page.

    What I'm looking for now is the MVC equivalent of a DetailsView, where my database single row data is displayed with the columns from top to bottom...

    I've Googled the shít out of this tonight and I don't seem to be connecting with the solution I'm trying to find...

    Could anyone point me in the right direction on this?

    Thanks in advance for any pointers...


«1

Comments

  • Registered Users Posts: 586 ✭✭✭Aswerty


    One of the big differences between WebForms and MVC is that MVC doesn't have the out-of-the-box components like WebForms does. This might seem like a point in favour of WebForms but it isn't. While WebForms might allow you to do things more rapidly during early development it also is far more restrictive in how you want to do things. This is the beauty of MVC, you can pretty much create any component you want with just a little HTML/CSS knowledge.

    The following are the steps needed to implement what you have described:

    1. Create the form in which you can submit a product ID. This form will be submitted to the relative URL "/Products/Info" and the name of the product ID input might be "productId".
    2. You'll have a Controller in your MVC application called ProductsController and this will have an action method called Info with a single parameter called productId of type int.
    3. In the action method you then perform the query against the DB (or more correctly you'd use a class which implements the query).
    4. The result from the DB then needs to be added to a data object class that just contains properties correlating to the columns of the DB Product table. We will call this class ProductViewModel and it might contain the following properties: int Id, string Name, string Description, decimal Price, etc.
    5. The ProductViewModel class can be considred a View Model class as per the View Model pattern. Google how a View Model is used in an ASP.NET MVC application. They are integral to building sane and maintainable Views and Controllers.
    6. Now we are pretty much at the point where we want to construct the Table that the user will see.
    7. In the View folder in the MVC project structure you should have a Products folder where the application will look for Views associated with the ProductsController (when said controller was made the folder should have been automatically created). In this folder create a new View called Info.cshtml (or whatever extension fits the rendering engine your using).
    8. You will pass the ProductViewModel class you created after your DB query into this view.
    9. Now that you have a view with a ViewModel containing your data you can now create a basic HTML Table. So the Info view might look like (excluding HTML boilerplate):
    @model <NamespaceGoesHere>.ProductViewModel.
    
    <!-- using css we can sex up the table by the selector #productInfo -->
    <table id="productInfo">
      <tr>
        <td>DB Column Names</td>
        <td>DB Data</td>
      </tr>
      <tr>
        <td>ID</td>
        <td>@Model.Id</td>
      </tr>
      <tr>
        <td>Name</td>
        <td>@Model.Name</td>
      </tr>
      <tr>
        <td>Description</td>
        <td>@Model.Description</td>
      </tr>
      <tr>
        <td>Price</td>
        <td>@Model.Price</td>
      </tr>
     </table>
    

    The Info action method would look like:
    public ActionResult Info(int productId)
    {
        // <<DB query code goes here>> and it returns an object which we'll call dbResult
    
    
        ProductViewModel model = dbResult.CreateProductViewModel(); // just a made up method that we might use to convert data
    
        return View(model); // by convention we don't need to specify view name since it is same as this methods name
    }
    

    And ProductViewModel would look like:
    public class ProductViewModel
    {
        public int Id {get;set;}
        public string Name {get;set;}
        public string Description {get;set;}
        public decimal Price {get;set;}
    }
    


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Thanks a mil for that, I'm going to give it a shot now. I know the lazy thing to do here would be to stick with the familar and keep with Webforms but the mobile development end of things seems to be with MVC now, so I'm trying to pick it up, although it is harder than I thought as I used a lot of drag and drop controls like DetailsView, FormView, DropDownlists, SqlDataSource, etc.

    I have found a CRUD solution in MVC though that can be pretty much automatically generated, I gave that a try last night although it isn't running right for me, something isn't hooked up properly it would seem. I'm going to give your suggested solution a try now, thanks for setting that up for me!


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Right I've scrapped my CRUD solution as it was way too messy and wouldn't work and I don't have the experience yet to run through everything and check what needs to be hooked up to what... When I used Webforms, I used SqlDataSource a lot, it was very handy, or so I thought, for setting up a connection string to a db and then you'd just connect up the control to the relevant SqldataSource and use ControlParameters to filter the data if that was required.

    Is there anything in MVC that can be used along the lines of SqlDataSource? I've tried going into the Model-->Add, and creating am ADO Entity Data Framework but what emerges out of that is around 5 files, none of which I can see a db connection in. I want to keep it simple so I can work with it better and learn faster, rather than having to wade through excess code.

    In my web.config file I can see a data connection string to my sql db on the web. Can I access this in my model or controller, to get the data I need?

    I know these questions will seem stupid as I'm so early stage with this...


  • Registered Users Posts: 586 ✭✭✭Aswerty


    This is another example of WebForms having out-of the-box components, MVC has no corresponding class. You instead just use any type of data access layer you want. The most straight forward is to use the .NET data providers. See the following for easy approaches: http://msdn.microsoft.com/en-us/library/dw70f090%28v=vs.110%29.aspx. If the database you are using is MS SQL Server just go with the first approach. As to accessing the connection string in Web.config, look at the following http://msdn.microsoft.com/en-us/library/ms178411%28v=vs.100%29.aspx. But until you actually get the database interface up and running, I'd advise you to just hardcode the connection string as per the first link I provided.

    I'll just reiterate that in MVC the data access layer is completely separate to the web framework. You could read/write to a .txt file instead of a DB if you so choose as far as the MVC framework is concerned.


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    First bug bear with MVC, I created a model cs file that accesses my DB.

    I build my solution.

    I then wish to go back onto my model and add in a column that I didn't previously have in the model...

    Now I'm getting a stupid error that says that the model has been update since the DB was created! BIG DEAL!

    I've tried deleting the model and rebuilding the solution and adding the new updated model again but no, I keep getting this pointless error!


  • Advertisement
  • Registered Users Posts: 586 ✭✭✭Aswerty


    It sounds like you're using Entity Framework and the the database first approach (e.g. you have an .edmx file in your solution). If this is the case you can open the .edmx file which should show you a graphical model of your DB schema. In this file you can right click and update the model from the database. This should update the model to include the new column.

    If I'm right in the above then this is not an MVC issue, you are having issues with Entity Framework which is a totally separate tool to wrap your head around. If your not currently trying to learn to use an ORM (which is what Entity Framework is), I'd advise you to just use a plain old SQL approach as I linked to in my previous post.


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Aswerty wrote: »
    It sounds like you're using Entity Framework and the the database first approach (e.g. you have an .edmx file in your solution). If this is the case you can open the .edmx file which should show you a graphical model of your DB schema. In this file you can right click and update the model from the database. This should update the model to include the new column.

    If I'm right in the above then this is not an MVC issue, you are having issues with Entity Framework which is a totally separate tool to wrap your head around. If your not currently trying to learn to use an ORM (which is what Entity Framework is), I'd advise you to just use a plain old SQL approach as I linked to in my previous post.

    Thanks so much for your advice with this... I'm really taken aback with how hard it actually is as someone with intermediate Webform development skills, to transition to MVC. I relied a lot on drop and drag controls, a lot of the connectivity with Webforms is easy to hook up, SqlDataSource to a DB and a control to an SqldataSource, I've obviously been taking all this out of the box functionality for granted!


  • Registered Users Posts: 586 ✭✭✭Aswerty


    I think coming from WebForms to MVC is tougher than if you didn't have any web dev experience. This is because you have to throw away most of all your knowledge because it doesn't translate at all. This is one of the reasons people have issue with WebForms, it's just a crazy technology Microsoft came up with so desktop developers could develop for the web without understanding how it works. Whereas if you were coming from Ruby on Rails, Java and Spring, Python and Django, etc. your understanding of how to build for the web would be hugely transferable. And this is also why pretty much everyone agrees MVC is the way forward in terms of the Microsoft stack.


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Aswerty wrote: »
    I think coming from WebForms to MVC is tougher than if you didn't have any web dev experience. This is because you have to throw away most of all your knowledge because it doesn't translate at all. This is one of the reasons people have issue with WebForms, it's just a crazy technology Microsoft came up with so desktop developers could develop for the web without understanding how it works. Whereas if you were coming from Ruby on Rails, Java and Spring, Python and Django, etc. your understanding of how to build for the web would be hugely transferable. And this is also why pretty much everyone agrees MVC is the way forward in terms of the Microsoft stack.

    This is EXACTLY the problem I have, I'm a small business owner so Webforms worked for me, it let me build a website, with exactly the functionality I wanted, without having to understand the technology in really deep detail. Now here I am having to throw most of what I picked up there with Webforms, completely out the window, to pick up this way of doing things using MVC.

    Visual Studio pulling against you with this stupid fúcking error as well relating to the model being newer than the DB or whatever, isn't helping! I wrote a model as follows:

    ////////////////////////////////////////////////////////////////////////

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Data.Entity;

    namespace Mobile.Models
    {
    public class QueryDB
    {
    public int ID { get; set; }
    public string ProductType { get; set; }
    public string Description { get; set; }
    public string EngineSpec { get; set; }
    public string TechInfo { get; set; }
    public string StockCode { get; set; }
    public DateTime Timestamp { get; set; }

    }

    public class QueryDBContext : DbContext
    {
    public DbSet<QueryDB> TradeOrders { get; set; }
    }
    }

    ///////////////////////////////////////////////////////////////
    (Apologies that I can't properly wrap that, I only have under 50 posts so can't use any posting tools yet!)...

    I don't have an .edmx file in my Models, it's just a .cs file, and then I went into Controllers --> Add and used the tool there to use a controller with Model Class set to QueryDB and Data Context Class set to QueryDBContext...

    This then added in a controller and a load of views (Index, Edit, Delete, Create)...

    Am completely bamboozled with how this framework operates and it is stopping me from learning how to use it, I've tried a few times now to sit down for a weekend and try to get this working and if it isn't this I've run into, it's been something else!


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Feel like I've reached Everest Base Camp One haha, I now have an MVC solution where I can Create Read Update and Delete a record of data, hooked up to my DB and running away, big thanks for the help from Aswerty...


  • Advertisement
  • Registered Users Posts: 586 ✭✭✭Aswerty


    Congrats man! Just remember Entity Framework is not part of MVC, its just one option you can use to interface with a DB. Mind you its a very good solution (which I favour myself) but it requires a bit of work to get up to speed on it.


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    The one thing i can't get my head around, is this thing where the DB has to be newer than the model? WTF?!? Say I have a client with a DB and his site is built using Webforms, he asks me to knock together a mobile website for him using MVC, but no can do as the Model is newer than the DB?!? What purpose is served by that?!?!?


  • Registered Users Posts: 586 ✭✭✭Aswerty


    I expect you're getting that error because your mapping and entity class for a specific table do not match the current state of table. So you either didn't create these classes correctly or you since changed the database and did not update your classes or vice versa.


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Just a problem I've run into... I've uploaded my MVC solution onto my web server, I've created a sub domain for it and it all works fine, my (non data displaying, for that I mean all views in my "Home" folder), views all load, and all looks well.

    I have a folder in my Views called "Stock" and this contains the views for "Index", "Details", "Delete", Edit", Create". I have a controller called "StockController" and a model that accesses my MS 2005 DB on my web server.

    I also have a connection string in my web.config file that sets up a connection to my DB on the web. Funnily, on my laptop here which is my Visual Studio development environment, all the Views in my "Stock" folder are working perfectly. I can create/edit/view/delete a new DB record.

    When when I upload the whole project to my sub domain on my web server, I get an error saying, "An Error occurred while processing your request"... The View itself appears to be loading, as the page is themed properly, so it seems to be routing to the correct page/view.

    Say I type in the URL: www.mobile.MyDomainName.com

    My Index view in the Home folder will load, which is what I expect.

    But if I type in: www.mobile.MyDomainName.com/Stock

    I get the errror above, but if I type in [url]http://localhost:5xxxxx/Stock[/url] when visual studio builds the solution locally, it runs fine?!? :confused::confused::confused:


  • Registered Users Posts: 586 ✭✭✭Aswerty


    Not a lot of information there to work with. The error message is very generic, is there a bit more information it gives you? If you haven't done the following give it a whirl, you may get a better error message. Add <customErrors mode="Off" /> under the <system.web> node in Web.config. You should reverse this change on the live version once you've solved the issue since it creates a security issue.

    Can you access the live DB? If you are only getting the issue where requests hit the DB then this is a good indication of your problem. If this is the issue and you are using Windows Integrated Authentication then you should probably just use SQL Authentication which I find to be more straight forward.


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury




  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury




  • Registered Users Posts: 586 ✭✭✭Aswerty


    As per the answer to that link. Have you got .NET 4.5 installed?

    Also check the properties of you MVC project in Visual Studio and see what version of the .NET Framework the application is using. If it is v4.5 and you don't have it installed on your server then that is most definitely an issue.


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Aswerty wrote: »
    As per the answer to that link. Have you got .NET 4.5 installed?

    Also check the properties of you MVC project in Visual Studio and see what version of the .NET Framework the application is using. If it is v4.5 and you don't have it installed on your server then that is most definitely an issue.

    This seems to be the issue. I checked the build on my local project, it is set to 4.0. I changed it to 4.5 and uploaded it and it says the target framework is using 4.0. So I changed my local project back to 4.0 (which brings me back to my original prob!). I probably need to get onto my hosting company and ask them to put it up to 4.5?


  • Registered Users Posts: 586 ✭✭✭Aswerty


    Or you might be able to try using an earlier version of EF if that is what is causing the issue. If you don't already you should use NuGet to manage EF for you, you can then easily change the version.

    Also just changing the .NET version in the properties can cause issues with libraries that target specific versions of .NET so any error arising might be due to that. On top of that your hosting provider may not support .NET 4.5 so they may or may not be able to upgrade you.

    There shouldn't be an issue getting this up and running with .NET 4.0. You're not doing anything that requires .NET 4.5.


  • Advertisement
  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Aswerty wrote: »
    Or you might be able to try using an earlier version of EF if that is what is causing the issue. If you don't already you should use NuGet to manage EF for you, you can then easily change the version.

    Also just changing the .NET version in the properties can cause issues with libraries that target specific versions of .NET so any error arising might be due to that. On top of that your hosting provider may not support .NET 4.5 so they may or may not be able to upgrade you.

    There shouldn't be an issue getting this up and running with .NET 4.0. You're not doing anything that requires .NET 4.5.

    The link I posted above where someone had a very similar problem, it didn't seem to be the .NET version that was causing the issue, I mean in my web.config file, it was initially running on 4.0 and the web server was running on 4.0 and my Views that were not hooked up to my DB were running fine, but the other guy seemed to be saying that his problem was with the version of the entity framework, in my Web.config, it is set ay 5.0.0.0, I've tried fidding around with it but I don't know how to change it to match what the hosted web server is running on.

    But I do suspect that the line in the attached image is where the issue might be...
    311162.png


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Was onto my web hosting provider this afternoon, they are upgrading me to a plan that is more suitable for what I need, faster server, higher spec, etc, so I'm waiting for that to come through and then will try this again...


  • Registered Users Posts: 586 ✭✭✭Aswerty


    The version number the red arrow is pointing at is the version number for Entity Framework. So that doesn't have anything to do with your hosting environment.

    While upgrading servers might be a good thing it doesn't in anyway mean that this will solve your issue. Said issue looks to be compatibility between EF and the underlying .NET framework.

    Actually just while typing I thought of this, in IIS you should check the .NET version for the application pool which your application is running in. Sometimes it will default to .NET 2 and it should be running as .NET 4.


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Aswerty wrote: »
    The version number the red arrow is pointing at is the version number for Entity Framework. So that doesn't have anything to do with your hosting environment.

    While upgrading servers might be a good thing it doesn't in anyway mean that this will solve your issue. Said issue looks to be compatibility between EF and the underlying .NET framework.

    Actually just while typing I thought of this, in IIS you should check the .NET version for the application pool which your application is running in. Sometimes it will default to .NET 2 and it should be running as .NET 4.

    This was originally an issue that stopped any views running on my web server, and this was resolved, so my views that didn't hook up to my DB would load, but any views that involved accessing my StockController would display this error. To be honest, my whole site, bothdesktop and mobile (the desktop is built using Webforms and the mobile site is built using MVC and is running on a sub domain (and separate app pool), of the main site...

    I've been having all sorts of issues lately as the project grew, from the site taking too long to load a page, to memory issues, so this upgrade will resolve those issues apparently, as the package I've been on is not really for something on the scale that my site has evolved into.

    My next big learning challenge is returning filtered data from my DB, based on a Textbox (string) value, watch this space lol! I can try to learn this on my development environment which is running everything fine.

    Previously I would have set up a TextBox and used an event handler such as SQLDataSourceSelecting and set up a Selectparameter and passed this into my SqlDataSource using a "Select * FROM Column Where @StockCode = [StockCode]"...

    This is where experience has to go out the window again... :(


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Some good news for me, whatever the issue was with my Views that needed to hook up to my DB, not displaying properly and generating the error above, this issue has resolved itself, so I'm free to continue on my MVC learning curve! :cool::cool::cool::cool::cool:


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    I'm really starting to get my head around this MVC after a few false starts I have to say...

    What I have now is a Controller that takes a string in via a Textbox, and displays a record based on a DB match.

    In my View, I have my data displayed in a Fieldset. The only thing I'm not happy with is that even before I run my query by entering a stock code into my Textbox and hitting return, the Fieldset display fields are visible.

    Is it possible to hide these until the data is actually returned? As it looks a bit sloppy at the mo. If I was back on planet Webforms, I would just set the GridView/DetailsView control to visible = "false" in my aspx page when it first loads, and would then dynamically change this to visible = "true" on a databound event handler for the control ...

    [HTML]
    <fieldset name="MyDBStockData" style="border-width:0px;">
    <legend>StockDB</legend>

    <div class="display-label">
    @Html.DisplayNameFor(model => model.StockCode)
    </div>
    <div class="display-field">
    @Html.DisplayFor(model => model.StockCode)
    </div>

    <div class="display-label">
    @Html.DisplayNameFor(model => model.ItemDescription)
    </div>
    <div class="display-field">
    @Html.DisplayFor(model => model.ItemDescription)
    </div>

    <div class="display-label">
    @Html.DisplayNameFor(model => model.QuantityInStock)
    </div>
    <div class="display-field">
    @Html.DisplayFor(model => model.QuantityInStock)
    </div>
    </Fieldset>
    [/HTML]

    I just want my Fieldset to not be visible (say on pageload), until it has run a query and is actually displaying data?


  • Registered Users Posts: 47 NoelOC


    There a few ways you could do it.

    The fastest and easiest way I would suggest is to add a variable in your ViewModel for the page.
    You could also use a ViewBag instead depending on your ViewModel but it's the same concept.

    Wrap your Fieldset in an @if statement

    @if (ViewBag.Show == true )
    {
    <fieldset.......>
    }

    In your controller set ViewBag.Show = false on the page load and set it to true when your returning the page with data.

    Hope that makes sense.


  • Registered Users Posts: 586 ✭✭✭Aswerty


    NoelOC wrote: »
    There a few ways you could do it.

    The fastest and easiest way I would suggest is to add a variable in your ViewModel for the page.
    You could also use a ViewBag instead depending on your ViewModel but it's the same concept.

    Wrap your Fieldset in an @if statement

    @if (ViewBag.Show == true )
    {
    <fieldset.......>
    }

    In your controller set ViewBag.Show = false on the page load and set it to true when your returning the page with data.

    Hope that makes sense.

    Thats a fine way to do it. Though it might be handier to just check if the model is null in the if statement as opposed to having a seperate ViewBag value dedicated to it.

    A step up from this approach is to dynamically load the fieldset containing the data. So initially you would load your page without the field set. Once you submit your stock code you would load a partial view containing the fieldset and insert into into the page on the client side. This approach requires the use of javascript to dynamically load the fieldset. So it is not a trivial undertaking.


  • Closed Accounts Posts: 1,143 ✭✭✭LordNorbury


    Aswerty wrote: »
    Thats a fine way to do it. Though it might be handier to just check if the model is null in the if statement as opposed to having a seperate ViewBag value dedicated to it.

    A step up from this approach is to dynamically load the fieldset containing the data. So initially you would load your page without the field set. Once you submit your stock code you would load a partial view containing the fieldset and insert into into the page on the client side. This approach requires the use of javascript to dynamically load the fieldset. So it is not a trivial undertaking.

    Yeah I'm trying to steer away from Javascript as I have very little experience with it, I'm gonna try the @if statement suggested above...

    Thanks for the help with it lads...


  • Advertisement
  • Registered Users Posts: 47 NoelOC


    I agree with Aswerty - The ideal and my preferred solution would be a JavaScript approach.

    Since you're not comfortable with using JavaScript then using the @if statement checking for a null model will also do.

    Something like this below depending on your Model

    @if (Model != null )
    {
    <fieldset.......>
    }


Advertisement