I have a dropdown list on an ASP.NET MVC project that I am pretty sure is not binding to my model because of my nhibernate mapping.
I have tried many variations on the asp mvc side resulting in this post here.
MVC side of things seems fine
I believe the issue may be that my object is trying to bind, but my mapping is out of whack.
My mapping is:
<many-to-one name="Project" lazy="false"
class="AgileThought.ERP.Domain.Property.Project"
column="ProjectGUID" />
My View gives an error saying that the GUID from the dropdownList selected value is not valid. Which I think may be that it is trying to push the GUID into my related project object.
The value 'fd38c877-706f-431d-b624-1269184eeeb5' is invalid.
My related project list binds to the dropdown list just fine, it is just not binding to my models Project entity.
Does the related Project entity need to know about its relationship? Its really just a lookup list.
Many thanks for your time and best regards,
Rod
You'd probably need a custom binder that can essentially do this...
entity.Project = session.Load<Project>(selectedValue);
I think Sharp Arch has something like this...check out this + helper method.
If you want to keep it simple, maybe just do it manually.
Related
Given an extremely simple object with only fields, e.g.:
class Contact {
string firstName;
string lastName;
DateTime birthday;
...
}
When you add a strongly-typed View with view content "Create", you get a nice form with all the fields of your object that passes the form back to the controller, etc, and life is good.
However, when the object becomes slightly more complex, like say we want to store email addresses for Contacts (and of course a Contact can certainly have more than one email address):
class Contact {
string firstName;
string lastName;
DateTime birthday;
ICollection<EmailAddress> emailAddresses;
...
}
Now when you add the strongly-typed view with view Content "Create", you get the same form as before, and the collection is not represented in the form in any way.
So now you have a form which is complete with one exception: you would like to add a section where the user can enter in as many or as few email addresses as they like and have those wrapped up and passed to the Controller on submit.
Is there a standard best-practice way of doing this in ASP.NET MVC2? If so, what is it?
MVC3 handles this a lot better but as your using MVC2 take a look at Steve Sanderson's detailed post on Editing a variable length list, ASP.NET MVC 2-style.
Phil Haack's Model binding to a list also gives you further information on how the default MVC2 model binders handle lists
Well, conceivably you can have your entire view be
HTML.EditorForModel()
If you follow the answer I posted to How to display the content of asp.net cache? to allow the Editor to do a deep dive against your model.
That's not the optimal solution. Manipulating List data in MVC is HARD. Mostly because of years of ASP.NET development has left us so disjoint from the metal of the web that the concepts of editing a list client side is easily lost on us.
For working with lists, you will also most likely need to work with client templating to be able to add new elements and remove elements easily. This can be get very complex due to the fact MVC requires all lists to be indexed and follow numerically otherwise on post backs you will be missing items (aside: I feel this was a terrible design decision)
Now with this being said, I would recommend looking at the KnockoutJS and KnockoutMapping frameworks which with the combination of jQuery and jQuery templating will allow you to create a very rich client experience. This unfortunately will most likely be a very radical departure from your existing development style however I feel what Knockout brings to the table is revolutionary and will open up the web so much further to ASP.NET MVC developers.
Could someone with some good knowledge answer this question please. Im having a problem with the schema in my Students.aspx page. I have done the walkthrough, but I get an error and I have copied the edmx file from the sample into my application and I still get the error. This is the error:
'EnrollmentDate' is not a member of
type 'SchoolModel.Person' in the
currently loaded schemas. Near simple
identifier, line 6, column 4.
I have also created a new EntityDataSource and I have the same problem. The sample works fine but I can't seem to get the EnrollmentDate and HireDate fields to be part of the 'SchoolModel.Person' Entity. The part which is Upto setting the EntityTypeFilter then I run the app and I get problems
It sounds like you're following the example on MSDN. By the end of the example, the fields EnrollmentDate and HireDate are no longer on the SchoolModel.Person class, they're on the subclasses SchoolModel.Instructor and SchoolModel.Student.
I faced the same problem while going through that walkthrough. The solution: Just delete the old EntityDataSource control on the page, put new EntityDataSource, configure it as given in walkthrough (with entity set name: People; EntityTypeFilter: Student or instructor), And every thing works as it should!!
Faraz
It sounds like you may have missed one or more EDS controls when you added the EntityTypeFilter attributes. Are you sure all your EDS controls that access students or instructors have EntityTypeFilter="Student" or EntityTypeFilter="Instructor"?
I have recently started to use Nhibernate and i am quite happy with it until i needed to BIND to ASP.NET controls. I was having major issues binding a gridview to a collection of Products (IList). In the end i was forced to right a small routine to convert my IList to a DataTable. Once it was in datatable it worked flawlessy.
Now has come the time to bind a standard Dropdownbox to 1 field of a collection (IList) of Products but it appears i am having issues again.
So this has brought me to the conclusion that i must be doing something wrong?
I can't believe that it isn't possible to BIND ASP.NET controls to a collection (IList) of a class (in my case products) that is returned from NHibernate.
I would really appreciate any feedback anyone has on the situation... I am at a loss
Thank you
The problem is not that you can't bind, because you can. Generally issues like this come about when you're binding at the wrong time.
NHibernate supports laziness. So if your query is lazy, and properties on the returned objects are lazy, then the values won't be pulled from the database until the items and properties are referenced. If you bind these to controls in the UI, then the values won't be extracted until the page gets rendered.
At this point there is a good chance that you have already closed your database connection.
The simple solution is to make sure that the data you're binding to is not lazily loaded.
Create a List<T> or BindingList<T> object and pass the IList object from the query into the constructor. If the IList object is not a generic list, you can use LINQ, ilistObject.Cast<T>().ToList().
i'm a total newbie with asp.net mvc and here's my jam:
i have a 3 level list box which selection on box A shows options on box B and selection on box B will show the options for box C.
I'm trying to do the whole thing in asp.net MVC and what i see is that the nerd dinner tutorial uses the ORM method.
so i created a dbml to the database and drag the stored proc inside.
i create a datacontext object but i don't quite know how to connect the result from the stored proce which should be multiple rows of data and make it into a json.
so i can keep all the json data inside the html page and using jquery i could make the selection process faster.
i don't expect the data inside the three boxes to change so often thus i think this method should be quite viable.
Questions:
So how do i get the stored proc part
to return the data as json?
i've noticed some tutorial online
that the json return result part is
at the controller and not at the
model end.
Why is that?
Edit
FYI, i find what i mostly wanted to do here.
For the json part, i referenced here.
Return a JsonResult from your controller action. You may need to coerce the result from your stored procedure into a C# class serializable to Json.
Json conversion should be done in the controller because it's not really part of the domain. More a DTO in the MVVM (Model-View-ViewModel) style.
I have a problem with Gridview sorting that is similar to others but I'm binding to a collection object as opposed to a data table.
The existing business rules and data access layers of an application follow the pattern of having an object and, if you need a collection of objects of that type, to have another class inheriting CollectionBase and implementing IBindingList.
For desktop applications, it was easy to databind a gridview to one of these objects and there weren't any problems with turning on column sorting. Everything was 'in state' in the desktop app's presentation layer.
Now that code is being moved to a new web application (ASP.NET 2.0, VB codebehind pages).
I've played around with what I had to do to only have certain columns of the collection show up in the gridview and the gridview looked pretty good. When I turned on 'allow sorting', that's when the problems showed up.
I'm getting the error about not having a .Sorting method, etc. In researching this, I found all sorts of solutions that were easily implemented with dataviews if my source was a data table. But it's not - it's a collection. I tried to "cheap shot" a datasource by converting the collection to an XML memory stream and them trying to .ReadXML back into a dataset but that didn't work [Root element is missing error was as far as I got in the dataset.ReadXml(ioTemp) where ioTemp was the System.IO.MemoryStream used in the xml serializer].
Because of the old desktop apps, I've never had to worry about sorting a collection since the gridview handled it once it was loaded. In fact, it's a 'standard' that the collection's .SortProperty, .SortDirection and .ApplySort all through NotSupportedExceptions (I inherited this code from programmers long gone).
Is there an easy way to convert the collection to a data table or a way to sort the collection without having to go back to the database each time? Object Data Sources won't work becuase of the intricate rules in how the objects are built - the wizards in VS2005 just can't handle what we need to do (grabbing data from several tables conditionally to make an object).
Thanks in advance.
Have you considered client side sorting instead?
I have used the jquery tablesorter plugin in the past with ASP Gridviews.
http://tablesorter.com/
I had a similar issue and i needed to implement IComparable on the objects. Basically to sort a collection of objects you need a way to distinguish their order. The IComparable interface has one method called Compare which allows the .Net framework to work out the order of the objects when you sort them. You need to implement this method yourself to get the sort method to work.
Google results
You don't mention the error message so i cant be sure if this is the case, can you post the error?
EDIT :
In regards to your comment; you can implement multi column sorting, it just requires more work. You can specify the fields to sort the collection by and then use this information within the CompareTo Method.
Have a look at this
Given that you apparently are populating the grid with a collection of your own objects, this sounds like a perfect job for Linq for Objects. With just a little elbow grease you can achieve what is effectively an SQL Select statement against your collection. Very cool stuff.
http://www.hookedonlinq.com/LINQtoObjects5MinuteOverview.ashx
Also, do you really just want to sort the data in the grid? If so, then'd definitely pursue using Linq against your objects. However, rarely does sorting the contents of the grid really answer the problem ("sorting the grid" usually translates into changing the access path of the data used to fill the grid.) Browser apps aren't like Windows apps and don't have a full-time connection to the underlying data source to make things happen quite as magically as the DataGridView in Windows makes things seem.
You can put link buttons with an On_Click event as the header's of each column.
When the event is triggered, figure out which header was clicked on (one method per header or a commandArgument value). Once that is know, do a .orderBy or .OrderByDescending by on the collection of objects, and put the result back in as datasource of the gridview and databind on that.
In the year since I originally asked this question, I managed to get a new 'standard' implemented so that collections of business objects were now generic lists.
So now a "Collection class" that is little more than a "Inherits List(Of MyBusinessObject)" with a Sort Method that looks like this (performance wasn't an issue):
Public Overloads Sub Sort(ByVal strPropertyName As String, ByVal strDirection As String)
Dim arSortedList As New ArrayList
For Each item As MyBusinessObject In Me
arSortedList.Add(item)
Next
arSortedList.Sort(New CaseInsensitiveComparer(Of MyBusinessObject)(strPropertyName, strDirection))
For intI As Integer = 0 To arSortedList.Count - 1
Item(intI) = arSortedList(intI)
Next
End Sub
This seemed to work perfectly with the methodology used by the GridView for firing events.