Get User Action
[HttpGet]
[ActionName("Index")]
public ActionResult Get(int id)
{
User u = UserCore.GetUser(id);
if (u == null)
return Content("user not found", "text/plain");
return new XmlResult(u);
}
UserCore.GetUser
public static User GetUser(int UserID)
{
using (PanamaDataContext db = new PanamaDataContext())
{
return (from u in db.Users where u.UserID == UserID select u).FirstOrDefault();
}
}
The Route
routes.MapRoute(
"GetUser",
"user/{id}",
new { controller = "Users", action = "Index" }
);
And finally the test URLs
/user/9000 returns “user not found” as expected (does not exist currently)
/user/75 (actually exists in the DB) however returns:
Cannot access a disposed object. Object name: ‘DataContext accessed
after Dispose.’.[ObjectDisposedException: Cannot access a disposed object. Object
name: ‘DataContext accessed after Dispose.’.]
System.Data.Linq.DataContext.GetTable(Type type) +1020550
System.Data.Linq.CommonDataServices.GetDataMemberQuery(MetaDataMember
member, Expression[] keyValues) +120
System.Data.Linq.DeferredSourceFactory1.ExecuteKeyQuery(Object[]1.Execute(Object instance) +928
keyValues) +258
System.Data.Linq.DeferredSourceFactory
System.Data.Linq.DeferredSource.GetEnumerator() +53
System.Data.Linq.EntitySet1.Load() +1121.get_Count() +9
System.Data.Linq.EntitySet
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterUser.Write14_User(String
n, String ns, User o, Boolean isNullable, Boolean needType) +5060
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationWriterUser.Write15_User(Object
o) +144[InvalidOperationException: There was an error generating the XML
document.]
System.Xml.Serialization.XmlSerializer.Serialize(XmlWriter xmlWriter,
Object o, XmlSerializerNamespaces namespaces, String encodingStyle,
String id) +646
System.Xml.Serialization.XmlSerializer.Serialize(TextWriter
textWriter, Object o, XmlSerializerNamespaces namespaces) +72
System.Xml.Serialization.XmlSerializer.Serialize(TextWriter
textWriter, Object o) +10 …
I’m assuming this is because the referenced object no longer exists but what can I do? Somehow copy the object that is returned from the DataContext?
Either way it should be returning XML and not that error.
You should use view models. Basically you should construct a view model inside the lifetime of the DataContext and pass this view model to the view result (in your case the XmlResult). This view model should be constructed by mapping properties of the actual domain model returned by your datacontext and all this should happen inside this context lifetime. Ayende Rahien has a great series of blog posts about view models (It’s for NHibernate but the problem of disposed context is exactly the same as with EF data datacontexts).