Microsoft.Xrm.Sdk.SaveChangesException in CRM 2011 - dynamics-crm-2011

I recently started working with plugins in CRM 2011 and I am facing issues with plugins registered on the Create message as a Post-operation.
When I register the create as a post-operation, I would expect that when I hit the plugin code, the entity has already been created in the database and I should be able to create a related entity(related to the newly created entity by a foreign key) in the plugin. But when I create the related entity and update it, and say SaveChanges(), it gives me a Microsoft.Xrm.SaveChangesException "An error occurred while processing this request"
And if I drill down to the inner exception, it just points to the OrganizationServiceFault. The stack trace it shows is:
Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at Microsoft.Xrm.Sdk.IOrganizationService.Execute(OrganizationRequest request)
at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.ExecuteCore(OrganizationRequest request)
at Microsoft.Xrm.Sdk.Client.OrganizationServiceContext.Execute(OrganizationRequest request)
at Microsoft.Xrm.Sdk.Client.OrganizationServiceContext.SaveChange(OrganizationRequest request, IList`1 results
I face this issue only on the create message, if I do the same operation on an update or delete, it works fine. Has anybody faced this issue? Please provide some inputs on the what I can try to resolve this issue. Thanks in advance!
Also, here is my plugin code.
The plugin gets fired when the ct_repcode entity is created and then in my plugin I create a ct_repcodeMember entity which has a ct_repcodeid field which links to the actual ct_repcode entity.
Entity repcodeEntity = _context.InputParameters["Target"] as Entity;
Guid repcodeId = repcodeEntity.Id;
//Create a new Ct_repcodemember object
Ct_repcodemember repcodeMember = new Ct_repcodemember();
Guid repCodeMemberId = _service.Create(repcodeMember);
repcodeMember = _serviceContext.Ct_repcodememberSet.Where(a => a.Id == repCodeMemberId).FirstOrDefault();
repcodeMember.ct_repcodeid = new EntityReference { Id = repcodeId };
//Update the object and save the changes in crm
_serviceContext.UpdateObject(repcodeMember);
_serviceContext.SaveChanges(); // --- The timeout error happens here

I've encountered this problem before as well. I believe the problem is that in CRM 2011, both the Pre and Post operations occur while you're still inside the database transaction.
The way we got around this was to flip the plugin to run asynchronously as a synchronous result was not necessary.
I'm not sure if there is another way around this with your current code structure. I haven't tried this either, but considering you can create the entity just fine, can you create the repcodeMember entity with the lookup populated? Is there a real need to do the create, retrieve, and then update? If you have some code that is running on create of the related entity, you may be able to share that with this plugin such that you can just do a straight create since it is the update that is giving you problems.

Give credit to #rocksolid and #patricgh, I just took their suggestions, combined them, and put a code example around it.
You should drop the use of the Service Context for this operation and use CRM's default CRUD functionality. Your EntityReference is incorrect because you must have a logical name, but since you already have an Entity you should just use EntityReference to set the value.
Entity repcodeEntity = _context.InputParameters["Target"] as Entity;
Ct_repcodemember repcodeMember = new Ct_repcodemember();
repcodeMember.ct_repcodeid = repcodeEntity.ToEntityReference();
_service.Create(repcodeMember);

I think what you have done: creating, finding and updating an entity via context is not a good way. You can just create an entity I mean the object update and then create it it via service. I have put the code as below.
Entity repcodeEntity = _context.InputParameters["Target"] as Entity;
Guid repcodeId = repcodeEntity.Id;
Ct_repcodemember repcodeMember = new Ct_repcodemember();
repcodeMember.ct_repcodeid = new EntityReference { Id = repcodeId };
_service.Create(repcodeMember);

You could try also setting the Logical Name for the ct_repcodeid Entity Reference, it looks like you are only setting the Id.

Related

Resource does not exist while calling `GetMemberGroupsAsync`

I am using Microsoft.Azure.ActiveDirectory.GraphClient;.
I am calling GetMemberGroupsAsync as follows:
IEnumerable<string> memberships = client.Groups.GetByObjectId(userObjectId).GetMemberGroupsAsync(true).GetAwaiter().GetResult();
I get the following exception:
System.Data.Services.Client.DataServiceClientException: {"odata.error":{"code":"Request_ResourceNotFound","message":{"lang":"en","value":"Resource 'c92da223-a37f-4194-9bbf-74669885a0f0' does not exist or one of its queried reference-property objects are not present."}}}
at System.Data.Services.Client.BaseAsyncResult.EndExecute[T](Object source, String method, IAsyncResult asyncResult)
at System.Data.Services.Client.QueryResult.EndExecuteQuery[TElement](Object source, String method, IAsyncResult asyncResult)
Any idea on why does this exception occur and how to solve it?
The error indicates the group you were requesting does not exist.
Based on the code, you were able to acquire the groups with userObjectId. Ensure that is a valid group id instead of user id.
It should be rather used as
var securityGroupMemberships = client.DirectoryObjects.GetByObjectId(userObjectId).GetMemberGroupsAsync(true).GetAwaiter().GetResult();
This gives all the security groups which a user is part of.

Property 'stageid' is of an unrecognized EdmPropertyKind. Entity new_test has duplicate navigation property names

I am using CRM2016
I created a test entity to replicate the issue
I did not do any customization on it. I created a new record with default fields and form. Then I tried to access the webapi for it
http://localhost/CRMDataBase/api/data/v8.0/new_test(bgcs0249-0a06-e611-941a-003002djlnc)
It worked fine and brought the record. Then I deleted the records and created a business process flow for it, with just one stage and one step
I activated it and added a new test record and tried to access the webapi url and it threw the below error
{ "error":{
"code":"","message":"Property 'stageid' is of an unrecognized EdmPropertyKind. Entity new_test has duplicate navigation property
names. All property names (Navigation and Structural property) must be
unique in an Entity ","innererror":{
"message":"Property 'stageid' is of an unrecognized EdmPropertyKind. Entity new_test has duplicate navigation property
names. All property names (Navigation and Structural property) must be
unique in an Entity
","type":"Microsoft.Crm.CrmHttpException","stacktrace":" at
Microsoft.Crm.Extensibility.OData.CrmODataEntityTypeSerializer.CreateSelectExpandNode(EntityInstanceContext
entityInstanceContext)\r\n at
System.Web.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteEntry(Object
graph, ODataWriter writer, ODataSerializerContext writeContext)\r\n
at
System.Web.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(IEnumerable
enumerable, IEdmTypeReference feedType, ODataWriter writer,
ODataSerializerContext writeContext)\r\n at
Microsoft.Crm.Extensibility.OData.CrmODataFeedSerializer.WriteObject(Object
graph, Type type, ODataMessageWriter messageWriter,
ODataSerializerContext writeContext)\r\n at
System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type
type, Object value, Stream writeStream, HttpContent content,
HttpContentHeaders contentHeaders)\r\n at
System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type
type, Object value, Stream writeStream, HttpContent content,
TransportContext transportContext, CancellationToken
cancellationToken)\r\n--- End of stack trace from previous location
where exception was thrown ---\r\n at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task)\r\n at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task)\r\n at
System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()","internalexception":{
"message":"Property 'stageid' is of an unrecognized EdmPropertyKind.","type":"Microsoft.OData.Core.ODataException","stacktrace":"
at
Microsoft.OData.Core.UriParser.Parsers.SelectPathSegmentTokenBinder.ConvertNonTypeTokenToSegment(PathSegmentToken
tokenIn, IEdmModel model, IEdmStructuredType edmType, ODataUriResolver
resolver)\r\n at
Microsoft.OData.Core.UriParser.Visitors.SelectPropertyVisitor.ProcessTokenAsPath(NonSystemToken
tokenIn)\r\n at
Microsoft.OData.Core.UriParser.Visitors.SelectPropertyVisitor.Visit(NonSystemToken
tokenIn)\r\n at
Microsoft.OData.Core.UriParser.Parsers.SelectBinder.Bind(SelectToken
tokenIn)\r\n at
Microsoft.OData.Core.UriParser.Parsers.SelectExpandBinder.Bind(ExpandToken
tokenIn)\r\n at
Microsoft.OData.Core.UriParser.Parsers.SelectExpandSemanticBinder.Bind(IEdmStructuredType
elementType, IEdmNavigationSource navigationSource, ExpandToken
expandToken, SelectToken selectToken, ODataUriParserConfiguration
configuration)\r\n at
Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseSelectAndExpand()\r\n
at
Microsoft.Crm.Extensibility.OData.CrmODataEntityTypeSerializer.CreateSelectExpandNode(EntityInstanceContext
entityInstanceContext)"
}
} } }
If I delete all the records-> deactivate business process -> add new data and then check the webapi, it is working fine. But when I activate the business process and add new data I am getting the above error
P.S: I have not done any coding/customization to business process flow and the entity. But I am still getting this error
What can be done to resolve this?
Looks like a bug in Web API endpoint. Community forums also reference the same issue...
The Web API endpoint still has some limitations and it doesn't fully mimic the OrganizationService behavior so, which will be for the next version (9.x.x) so if you are stuck maybe try applying an update (and then use v8.1 in the url) as, or raise a MS Support case.
If you are still stuck, just try the same using OData / OrganizationService maybe.

Updated Table Returning Error When Query with ASP.NET Web API2 Service

I'm working on a WindowsPhone 8.1 app, and I have a SQL database connected to a Web API server hosted on an Azure website. Recently, the database person updated the database, added a new table, and added sample data to the tables that didn't already have any. When managing the database through Azure, I can see that all the tables have data in them, but when I try to retrieve them with the /api/entityname url, it returns an error message.
A few things to note, the database the server connects to has changed since I originally published it. I tried to run the enable migrations and update database commands again, but I don't know how to select the new database it's now connected to. Do I need to republish the server? Run the migrations commands for the new database? I'm hesitant try things involving the database connection on my own since I don't know much about it and don't want to mess up any configurations. I have a .NET backend. Thanks in advance for the help.
Update:
I went into the Web.Config file of my Services project and changed catalog value in the connection string to the name of my new database. Now I get the following error when I try to get the games values using the /api/teams extention:
An error has occurred.The
'ObjectContent1' type failed to serialize the response body for
content type 'application/xml;
charset=utf-8'.</ExceptionMessage><ExceptionType>System.InvalidOperationException</ExceptionType><StackTrace/><InnerException><Message>An
error has occurred.</Message><ExceptionMessage>The 'GameTime' property
on 'Game' could not be set to a 'System.TimeSpan' value. You must set
this property to a non-null value of type 'System.Byte[]'.
</ExceptionMessage><ExceptionType>System.InvalidOperationException</ExceptionType><StackTrace>
at
System.Data.Entity.Core.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader1.GetValue(DbDataReader
reader, Int32 ordinal) at
System.Data.Entity.Core.Common.Internal.Materialization.Shaper.GetPropertyValueWithErrorHandling[TProperty](Int32
ordinal, String propertyName, String typeName) at
lambda_method(Closure , Shaper ) at
System.Data.Entity.Core.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func2
constructEntityDelegate, EntityKey entityKey, EntitySet entitySet)
at lambda_method(Closure , Shaper ) at
System.Data.Entity.Core.Common.Internal.Materialization.Coordinator1.ReadNextElement(Shaper
shaper) at
System.Data.Entity.Core.Common.Internal.Materialization.Shaper1.SimpleEnumerator.MoveNext()
at System.Data.Entity.Internal.LazyEnumerator1.MoveNext() at
WriteArrayOfGameToXml(XmlWriterDelegator , Object ,
XmlObjectSerializerWriteContext , CollectionDataContract ) at
System.Runtime.Serialization.CollectionDataContract.WriteXmlValue(XmlWriterDelegator
xmlWriter, Object obj, XmlObjectSerializerWriteContext context) at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.WriteDataContractValue(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj,
RuntimeTypeHandle declaredTypeHandle) at
System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(DataContract
dataContract, XmlWriterDelegator xmlWriter, Object obj,
RuntimeTypeHandle declaredTypeHandle) at
System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(XmlWriterDelegator
writer, Object graph, DataContractResolver dataContractResolver) at
System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(XmlWriterDelegator
writer, Object graph, DataContractResolver dataContractResolver) at
System.Runtime.Serialization.XmlObjectSerializer.WriteObjectHandleExceptions(XmlWriterDelegator
writer, Object graph, DataContractResolver dataContractResolver) at
System.Runtime.Serialization.DataContractSerializer.WriteObject(XmlWriter
writer, Object graph) at
System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStream(Type
type, Object value, Stream writeStream, HttpContent content) at
System.Net.Http.Formatting.XmlMediaTypeFormatter.WriteToStreamAsync(Type
type, Object value, Stream writeStream, HttpContent content,
TransportContext transportContext, CancellationToken
cancellationToken)
--- End of stack trace from previous location where exception was thrown --- at
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task
task) at
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at
System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()
I think I'm making some progress, but I'm not very experienced with connecting apps to databases, so I'm hesitant to poke around. Thanks in advance for the help. I am using data-first migration (EF Designer from database). Also, the above error message is only displayed when I run the service locally via localhost. When I run it through it's hosted azurewebsites url, I get the following:
An error has occurred.
I assume this is due to my database updates not being published to the hosted site, correct? I'm using Firefox as my browser. If I use IE, I can't download or open the JSON file for the new entities.
With the help of a friend, I managed to fix this problem. In case anyone comes across this post down the line, the problem was due to conflicting data types between the database and the server's data objects. A list of data type mappings between C# and SQL Server can be found at https://msdn.microsoft.com/en-us/library/cc716729%28v=vs.110%29.aspx. Match the data types according to the linked chart, and ensure that any other database constraints (ie: required, etc) are included in annotations. Also, make sure that you update any code in your server's context file to match the data type changes. For instance, I had the following code in my OnModelCreating method:
modelBuilder.Entity<Game>()
.Property(e => e.GameTime)
.IsFixedLength();
Once I changed GameTime to a DateTime property,.IsFixedLength(); no longer applied to it, so I had to comment it out. As you make these changes, you can test them out by debugging your server locally, but you'll have to publish it back to the url it's hosted on in order see the changes take place on your remote server. In my case, I had to republish my azurewebsites.net site. I hope this helps anyone down the line that has a similar issue.

Web API throws exception after installing AttributeRouting

I developed a simple VB .NET Web API project using .NET 4.5
This project was working perfectly fine, but I decided to install the AttributeRouting nuget package. After installing this package every function seems to raise the following exception:
The constraint entry 'inboundHttpMethod' on the route with route
template 'Company' must have a string value or be of a type which
implements 'IHttpRouteConstraint'.
In this message 'Company' is the route name to a simple GET method that simple returns one object. Every route results in this error message. The stacktrace is:
[InvalidOperationException: The constraint entry 'inboundHttpMethod'
on the route with route template 'Company/{Id}' must have a string
value or be of a type which implements 'IHttpRouteConstraint'.]
System.Web.Http.Routing.HttpRoute.ProcessConstraint(HttpRequestMessage
request, Object constraint, String parameterName,
HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
+346 System.Web.Http.Routing.HttpRoute.ProcessConstraints(HttpRequestMessage
request, HttpRouteValueDictionary values, HttpRouteDirection
routeDirection) +201
System.Web.Http.Routing.HttpRoute.GetRouteData(String virtualPathRoot,
HttpRequestMessage request) +430
AttributeRouting.Web.Http.Framework.HttpAttributeRoute.GetRouteData(String
virtualPathRoot, HttpRequestMessage request) +250
System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase
httpContext) +191
System.Web.Routing.RouteCollection.GetRouteData(HttpContextBase
httpContext) +233
System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase
context) +60
System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object
sender, EventArgs e) +82
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
+136 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +69
I found the following thread which describes my problem: https://github.com/mccalltd/AttributeRouting/issues/191
Unfortunately, this fix does not seem to help: https://github.com/mccalltd/AttributeRouting/issues/191#issuecomment-13814025
Any ideas on how to fix this?
In your case, I definitely feel like this issue is related with in memory hosting and do have a solution in the link that you mention above.
After updating to MVC 5 I came across this issue and following the workout in this link which ultimately helped me out.
Here is how I did it.
In global.ascx page, I have the following:
AttributeRoutingHttpConfig.RegisterRoutes(GlobalConfiguration.Configuration.Routes);
In AttributeRoutingHttpConfig class, I replaced the code
routes.MapHttpAttributeRoutes();
with
routes.MapHttpAttributeRoutes(cfg =>
{
cfg.InMemory = true;
cfg.AutoGenerateRouteNames = true;
cfg.AddRoutesFromAssemblyOf<Your_API_Controller>();
});
You can overwrite Your_API_Controller with any of your ApiController class. (Yes, don't know why but any api controller you want works ;) )
Hope this helps,

null reference exceptions when adding

I discovered SubSonic this evening, and after a little bit of playing with it and MySQL Connector versions, I finally got it to accept my connection string setting up a simple repository.
So I created a simple class, and went to town adding some data to the class then creating a repo, and trying to save the record.
All I can seem to get out of it is null exception errors when I call:
repo.Add(user);
No idea what's null though, and the error isn't very clear.
At one point, I changed the type of my ID field in my User class to a long and got another error out of SubSonic (saying it couldn't tell what field was my ID field, telling me to name it ID or put a tag on it, but it was already named ID)
I've put data in every field in the class, even those that are not required per the database, but nothing.
I spent the rest of the evening googling for information on my error, but no luck, and the documentation on the site didn't get me anywhere either.
Any idea what I'm doing wrong, or how I could possibly diagnose this?
Thanks in advance for any help...
Here's the exception details
System.NullReferenceException was unhandled
Message=Object reference not set to an instance of an object.
Source=MySql.Data
StackTrace:
at MySql.Data.MySqlClient.MySqlConnection.get_ServerThread()
at MySql.Data.MySqlClient.MySqlConnection.Abort()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at SubSonic.DataProviders.DbDataProvider.ExecuteReader(QueryCommand qry)
at SubSonic.Query.Insert.ExecuteReader()
at SubSonic.Repository.SimpleRepository.Add[T](T item)
at gc_ss.Program.Main(String[] args) in C:\Users\Michaelm\Desktop\Subsonic_Demo\gc_ss\gc_ss\Program.cs:line 27
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Another Update
I'm noticing that if I change the class (User) and modify one of the properties, that the property changes get reflected in the database. Also if I drop the table, it gets constructed based on my Class. So the migrations part is working, it's something happening after that.
Final Update
Okay, I deleted the table, and changed the class to use a long as the ID field. Set to RunMigrations, and ran again, and it failed because of no default value for ID. I set the column in MySQL to AutoIncrement and all is working fine now. Not sure how it's different than setting it to long yesterday (unless changes weren't getting applied like I thought they were).
Anyway, so I guess this question is closed...
This is a issue with the mysql.data provider. Normally the connector would throw a meaningful exception but has an internal nullreference exception itself before that happens.
Look at my answer here: Subsonic 3.0.0.4 ActiveRecord Template for MySQL error on inserting new record
That explains how to work around that.

Resources