I'm hosting an ASP.NET MVC site on Winhost and recently added a WCF data service for users providing feedback. The service works fine from my local machine, but when I deploy it I get the following System.NullReferenceException returned in Fiddler whenever I try to save an entry to the service:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code></code>
<message xml:lang="en-US">An error occurred while processing this request.</message>
<innererror>
<message>Object reference not set to an instance of an object.</message>
<type>开发者_Python百科;System.NullReferenceException</type>
<stacktrace> at System.Data.Services.Providers.ObjectContextServiceProvider.SetValue(Object targetResource, String propertyName, Object propertyValue)
at System.Data.Services.Serializers.Deserializer.SetPropertyValue(ResourceProperty resourceProperty, Object declaringResource, Object propertyValue, ContentFormat contentFormat, IDataService service)
at System.Data.Services.Serializers.PlainXmlDeserializer.ApplyProperty(XmlReader reader, String propertyName, ResourceType resourceType, Object resource)
at System.Data.Services.Serializers.PlainXmlDeserializer.ApplyContent(XmlReader reader, ResourceType resourceType, Object resource)
at System.Data.Services.Serializers.PlainXmlDeserializer.ApplyContent(Deserializer deserializer, XmlReader reader, ResourceType resourceType, Object resource, EpmAppliedPropertyInfo propertiesApplied, Int32 currentObjectCount)
at System.Data.Services.Serializers.SyndicationDeserializer.ApplyProperties(SyndicationItem item, ResourceType resourceType, EpmAppliedPropertyInfo propertiesApplied, Object resource)
at System.Data.Services.Serializers.SyndicationDeserializer.CreateObject(SegmentInfo segmentInfo, Boolean topLevel, SyndicationItem item)
at System.Data.Services.Serializers.SyndicationDeserializer.CreateSingleObject(SegmentInfo segmentInfo)
at System.Data.Services.Serializers.Deserializer.ReadEntity(RequestDescription requestDescription)
at System.Data.Services.Serializers.Deserializer.HandlePostRequest(RequestDescription requestDescription)
at System.Data.Services.DataService`1.HandlePostOperation(RequestDescription description, IDataService dataService)
at System.Data.Services.DataService`1.ProcessIncomingRequest(RequestDescription description, IDataService dataService)
at System.Data.Services.DataService`1.HandleNonBatchRequest(RequestDescription description)
at System.Data.Services.DataService`1.HandleRequest()</stacktrace>
</innererror>
</error>
Turn on tracing both on the server and on the client (see http://msdn.microsoft.com/en-us/library/ms733025.aspx), then use SvcTraceViewer (http://msdn.microsoft.com/en-us/library/ms732023.aspx). It will usually give you a more detailed exception.
My problem turned out to be 2 issues:
- My site reroutes Url's for all GET requests to lower case. ODATA queries are case sensitive. This was causing me trouble with diagnosing the problem but wasn't causing the POST issue. Removing this for my service uri helped me identify the real problem.
- The real issue was that my DataContext for my POCO entities had proxy generation enabled.
Here's a lengthier description of how I found the problem in case it helps anyone debug a similar issue:
Per Dan's suggestion, I enabled tracing to see if I could get any additional details. This showed me that I was getting a System.ServiceModel.CommunicationObjectAbortedException. I searched for the cause of this for a while with no success.
Next, I set my EntitySetRights for my DataService to EntitySetRights.All to see if I could determine the error by attempting to read my entity set (note that in my case this is a temporary change for debugging).
static public void InitializeService(DataServiceConfiguration config) {
...
config.SetEntitySetAccessRule("myentityset", EntitySetRights.All);
...
}
I then queried the service http://mydomain.com/myservice.svc/myentityset and received the following error:
Resource not found for the segment 'myentityset'
This turned out to be due to my site forcing all urls to lower case (apparently ODATA queries are case sensitive). My entity set is named something like 'MyEntitySet', but it was being queried as 'myentityset' Once I disabled this for my service url, I received an error similar to the following:
Internal Server Error. The type 'System.Data.Entity.DynamicProxies.myentity_XXXX' is not a complex type or an entity type
Looking up this error led me to this link identifying my core problem. The problem is with POCO Entity Generation for DataServices. In order to fix the problem ProxyCreationEnabled needs to be set to false. I added the following method to my T4 template that generates my ObjectContext.
<#+
private void WriteProxyCreation()
{
#>
this.ContextOptions.ProxyCreationEnabled = false;
<#+
}
#>
I then added a call to my method in each of the constructors similar to the following:
public <#=code.Escape(container)#>()
: base(ConnectionString, ContainerName)
{
<#
WriteLazyLoadingEnabled(container);
WriteProxyCreation();
#>
}
精彩评论