Include in enity framework 4 - asp.net-mvc

I've been using enity framework that came with 3.5sp. And now I've redone things for enityframework 4 and asp.net mvc 2. I've come across something (which worked in my previous version and asp.net mvc 1.0).
I have this:
public IQueryable<Booking> GetBookings()
{
return from b in _entities.Bookings.Include("BookingObject")
select b;
}
And in my controller I have:
return View("Index", new BookingsViewModel
{
Bookings = _br.GetBookings().ByDay(DateTime.Today)
});
And it doesnt seem to include the "BookingObject"-entity, so I can type like <%= Model.Bookings.BookingObject.BookingObjectName %> in my view.
What might be missing here? Do I need to turn something on in the diagram for it to include entities or?
/M

No, it should work exactly as before. I'm assuming you have a navigation property BookingObject on your Booking item - but then the .Include() would error out if you didn't. I don't think there's anything else you need to set up, or at least not that isn't done by default. I'd verify the definition of the navigation property in the .edmx editor at least.
You're definitely using the final RTM EF4 code? We hit a bug in the final RC building incorrect SQL and returning no results for one specific include sequence, but it was a lot more complex than that.
Failing that I would use SQL Server Profiler to trace out the SQL it's using and try and debug that.

Related

Howto: simply read SQL Server database to MVC 4 view?

I am relatively new to MVC. I am trying to just display the contents of a remote SQL Server table on a page. It is READ ONLY, and nearly everything I find online is utilizing the Entity Framework or something similar which is overkill for what I am after. I just need to print all the rows from a table out to a view.
So my questions are:
should I just hack the sqlconn and everything into the view that I want the data printing out to?
Or should I add the sql in that view's controller?
Create a model and somehow get that data back into the view?
I know step #3 is the 'correct' way to do it, however I am looking for something simple and quick. :)
Thanks everyone!
You say EF is overkill, but that's the easiest way to do this. Maybe use Linq to SQL, since that's more lightweight. This is all there is to it:
Generate the EF / L2S entity classes
Instantiate the database context in the controller, and get all records
Return the IEnumerable records to the view
In the view, use #Html.DisplayForModel()
Here's a simple example. Note that returning the database entity classes is considered bad practice, you should map / automap them to a View Model type class first.
Home Controller
public ActionResult Index()
{
MyEntityModel[] items = MyDatabaseContext.GetAllRows();
return View(items);
}
Home/Index View
#model IEnumerable<MyEntityModel>
#foreach (MyEntityModel item in Model)
{
#Html.DisplayFor(m => item)
}
Without EF / L2S it's almost as easy, but you'd have to create your own entity / wrapper class for the database records and populate them manually.
There are also scaffolding projects for MVC that will generate repository and controller classes, as well as Razor views. See for example MVC Scaffolding on NuGet.
Once you get used to forcing yourself to use Entity Framework for even your "small" applications then and only then will you truly understand that is it the simplest way.
Sure, if you come from a background of memorized ADO.NET dataset/datatable/datareaders etc.. then sure you have projects with "canned" operations that you port over and modify but it is truly just old and cost you more time in the long run.
Use EF
Use multiple projects in a solution
Use a repository pattern if you can, it pays off in dividends for reasons you will discover
Keep your controllers "skinny"
Dont' use a "ViewModel" just to use / do it.
The SOC of having View and Controller are critical, but the Models folders does not need to be used, you can wire things up without it if you want, just pay attention to where your "model" is and abiding by SOLID principle etc..

Best practices for debugging ASP.NET MVC Binding

Can you give me any general advice on how to debug ASP.NET MVC Binding?
When everything works as expected, ASP.NET MVC is great. But if something does not, like something doesn't bind for some unknown reason, I find it hard to trace down the problem and find myself spending hours tracking down a seemingly simple problem.
Let's imagine you land in a controller method like this:
[HttpPost]
public ActionResult ShipmentDetails(Order order)
{
//do stuff
}
Let's further imagine that the Order class looks like this:
public class Order
{
public decimal Total {get; set;}
public Customer Customer {get; set;}
}
public class Customer
{
public string Name {get; set;}
public string Phone {get; set;}
}
What are good places to start when Order in the controller method is not bound correctly? What are good places to start when only parts of the Order are bound correctly?
Although #russ's answer is useful and will sometimes be necessary, both options seem a little low level when the main question is more about the big picture. Thus, I'd recommend Glimpse.
From its about page:
… Glimpse allows you to debug your web site or web service right in the browser. Glimpse allows you to "Glimpse" into what's going on in your web server. In other words what Firebug is to debugging your client side code, Glimpse is to debugging your server within the client.
And since you've specifically asked about data binding, you'll want to look at the binding tab documentation. You'll be able to see, again from the docs:
Ordinal: Order in which the MVC Model Binding infrastructure attempted to bind the available data
Model Binder: Model Binder that was used in a given scenario
Property/Parameter: Name of the thing that the Binder was trying to bind
Type: Type of the thing that the Binder was trying to bind
Attempted Value Providers: Providers that the Binder attempted to use to get a given value (and whether it was successful)
Attempted Value: The actual value that the provider has to work with (post type conversation, etc.)
Culture: The culture that was used to parse the raw value
Raw Value: The raw value that the provider has to work with (pre type conversation, etc.)
See the quick start. Briefly:
Install the glimpse.mvc3 package
Go to http://yourhost/yourapp/Glimpse.axd and "turn it on."
Click on the glimpse icon on the bottom right of any view in your app for details.
As Darin has suggested, start with inspecting what is being sent from the client to the server using something like Firebug, Fiddler, or other web debugging proxy tool.
Failing that, you might want to step through the source code to see what's happening during binding.
Two ways that I can recommend doing this are
Include the System.Web.Mvc source code project in your application and reference this. This is good for learning but probably not recommended for a commerical application.
Download the symbols for System.Web.Mvc from the Microsoft Symbol servers, change your settings to be able to debug framework source code and set a break point appropriately to step through.
In my case looking at the ModelState property in the controller method provided the answers why the modelbinding was failing.
A good place to start is download and install FireBug and see what gets posted from the client to the server. Then you will see what's missing, incorrect, ... Blog posts such as Model Binding to a List are good reads as well to get acquainted with the proper syntax that the default model binder uses.
From Visual Studio side:
Set a breakpoint on entry to your endpoint.
Open the Immediate via the Debug menu option.
Type in ModelState.Keys.ToList()
This will show the binding errors by name/key.
Better yet type in ModelState.Values.ToList()...
Put a breakpoint in your controller-method and make a watch for Request.Params to see what is actually coming in to the controller in terms och parameters.

Is it possible to add a value in MVC2 RC DataTokens collection?

I'm using ASP.NET MVC2 RC and I have built security on top of the Areas/Controller/Action specification, using basically a table that tells the infrastructure which role has permission to execute which controller action.
The code I used to get the "area" was this
RouteData.Values["area"]
And then I checked that in the Database. My problem is that when I migrated from MVC 1 RTM to MVC2 RC, the area goes in the DataTokens collection, and if the controller that is being called is in the root area, the following code returns null
RouteData.DataTokens["area"]
Do you know if there's any way to tell MVC that if "area" is not in the DataTokens collection, it should have string.Empty?
I'm trying to avoid modifying my code to check that for null.
Thanks!
As a work around, you can manually add the value from RouteData.Values to RouteData.DataTokens. But ideally you need to address the root cause.
Here's the work around for the issue:
if (controllerContext.RouteData.Values.ContainsKey("area"))
{
ControllerContext.RouteData.DataTokens.Add("area", ControllerContext.RouteData.Values["area"]);
}
Why not simply check if RouteData.DataTokens["area"] is null (or empty) and assume the default area when it is?
Edit
Apologies, I didn't read the the last line of your question before answering. What's the issue with modifying the code?

Spark View Engine and using viewdata confusion

I can't seem to get a grasp on how to use the viewdata structure in the spark view engine. I have the following code in my controller:
// Retrieve the project list from the database
var projects = from p in _context.Repository<project>()
orderby p.name ascending
select p;
return View(projects.ToList<project>());
This code works, as I have unit tests returning the correct projects, and my non-spark view worked perfectly. Now I am trying to switch to Spark View Engine and I'm just confused on the syntax. As a side note, I have verified that spark view engine is working and reading my .spark view.
Here is what I am using in my list.spark view:
<h2>Available Projects</h2>
<viewdata model="IList[[project]]"/>
Count: ${model.count}
When rendering this view the following error occurs:
.../List.Spark(3,16): error CS0103: The name 'model' does not exist in the current context
This is referring to the model.count line. Why doesn't this work? I tried passing the project list to the ViewData["projects"] (and replaced model in the spark code with projects) and I get the same error (take out the model.count for projects.count).
This is probably something stupid, but I can't seem to figure this out.
Update:
Well I fixed this. It seems that the MVC2 web.config file created by VS 2010 Beta 2 was bad. I used a MVC2 web.config file created by VS 2010 RC and it now works. Thanks!
I think you want this:
<h2>Available Projects</h2>
<viewdata model="IList[[project]]"/>
Count: ${ViewData.Model.Count}
or this:
<h2>Available Projects</h2>
<viewdata model="IList[[project]]"/>
<var model="ViewData.Model" />
Count: ${model.Count}
The viewdata element declares the types of the entries in the ViewDataDictionary. For "model", this is actually declaring the type of the ViewDataDictionary's Model property.
Note also that these expressions and type names are C# code, and thus case sensitive.
EDIT: syntax updated for 1.0 stable release.
Reference - using view data in the documentation

subsonic, mvc and activerecord

i am using subsonic 3.0 and active record with a mysql database
now everything is fine, but i cant seem to create views see example:
public ActionResult Index()
{
return View(contact.GetPaged(1,20));
}
now normally i would right click and choose Add View
i would then choose strongly typed and find the class for the repositary
however for some reason the only classes i get showing up are for subsonic only
but expect to see the new class from the new generated graniteMysqlDB
if anyone could please advice i would be most grateful as there doesent seem to be
any forum links or anything for subsonic.
thanks
okay i have solved the problem, but the answer is here should anyone need it or wants to know what happened.
i put my TT files into the models folder, my namesspace should have been test2.Models
however it was test2
also i needed the using directive of using test2.Models; at the top of my page.
still get an error where i have to correct the view on the inherites it puts
i have to change this to
very nice now is this subsonic very very fast loading compared to other stuff i have used.
ta

Resources