使用MSCRM服务保存数据

时间:2014-12-04 06:02:32

标签: c# dynamics-crm-2011 dynamics-crm crm

我正在开发一个打算使用crmservice的项目,以便在现有数据库上保存数据。数据库由mscrm创建,我必须创建一个使用crmservice在db上存储相关信息的应用程序。

到目前为止,我正在从viewModel接收数据并尝试使用crmservice进行保存。

以下保存方法:

private void Initiate()
        {
            var serverConnect = new CrmConnector();
            CrmConnector.pubpassword = ConfigurationManager.AppSettings["crmpassword"].ToString();
            CrmConnector.pubuserName = ConfigurationManager.AppSettings["username"].ToString();
            CrmConnector.pubdomain = ConfigurationManager.AppSettings["domain"].ToString();
            CrmConnector.serveraddr = ConfigurationManager.AppSettings["server"].ToString();
            serverConfig = serverConnect.GetServerConfiguration();
        }

        public void SaveTimesheetLine(TimesheetViewModel timesheetLineVm)
        {
                string payrollId = Convert.ToString(Session["payroll"]);
                Initiate();
                using (_serviceProxy = CrmConnector.GetOrganizationProxy(serverConfig))
                {
                    // This statement is required to enable early-bound type support.
                    //_serviceProxy.EnableProxyTypes();
                    _service = (IOrganizationService) _serviceProxy;

                    var timesheetLineEntity = new Entity("new_timesheetlineitem");
                    timesheetLineEntity["new_billtoid"] = timesheetLineVm.TimesheetLineViewModels.BillToId;
                    timesheetLineEntity["new_timesheettimesheetlineitemid"] = timesheetLineVm.TimesheetId ;
                    timesheetLineEntity["new_slatimesheetlineitemid"] = timesheetLineVm.TimesheetLineViewModels.SlaId;
                    timesheetLineEntity["new_billratetimesheetlineitemid"] = timesheetLineVm.TimesheetLineViewModels.BillRateId;
                    timesheetLineEntity["new_stream3timesheetlineitemid"] = timesheetLineVm.TimesheetLineViewModels.Stream3Id;
                    timesheetLineEntity["new_contracttypetimesheetlineitemid"] = timesheetLineVm.TimesheetLineViewModels.ContractTypeId;
                    timesheetLineEntity["new_firstname"] = timesheetLineVm.TimesheetLineViewModels.EmployeeFirstName;
                    timesheetLineEntity["new_lastname"] = timesheetLineVm.TimesheetLineViewModels.EmployeeLastName;
                    timesheetLineEntity["new_accounttimesheetlineitemid"] = timesheetLineVm.TimesheetLineViewModels.EmployerId;
                    timesheetLineEntity["new_payrollreference"] = payrollId;
                    timesheetLineEntity["new_timesheetdate"] = timesheetLineVm.TimesheetDate;
                    timesheetLineEntity["new_candidatetimesheetlineitemid"] = timesheetLineVm.TimesheetLineViewModels.CandidateId ;
                    // taken from user input 
                    timesheetLineEntity["new_startdatetime"] = timesheetLineVm.TimesheetLineViewModels.StartDate;
                    timesheetLineEntity["new_enddatetime"] = timesheetLineVm.TimesheetLineViewModels.EndDate;
                    timesheetLineEntity["new_paytypetimesheetlineitemidname"] = Convert.ToString(timesheetLineVm.TimesheetLineViewModels.PayType);
                    //timesheetLineEntity["new_lunchtime"] = 2;
                    timesheetLineEntity["new_submittedhours"] = timesheetLineVm.TimesheetLineViewModels.SubmittedHours;

                    _timesheetlineId = _service.Create(timesheetLineEntity);
                }
        }

我收到的错误:

  

[FaultException`1:System.NullReferenceException:Microsoft Dynamics   CRM遇到了错误。管理员或参考号   支持:#E28869A7]
  System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(即时聊天   reqMsg,IMessage retMsg)+11080899
  System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&安培;   msgData,Int32类型)+336
  Microsoft.Xrm.Sdk.IOrganizationService.Create(实体实体)+0
  Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.CreateCore(实体   实体)+425
  Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.Create(实体   实体)+13

我已经研究过但尚未发现任何类似的问题。有没有人以前经历过这个?

-----------------编辑 我认为这种方法应该采用不同的方式,所以我做了一些小改动。我没有尝试添加新的timesheetLine(与时间表相关 - 一个时间表可以有0个或更多个timesheetLines),而是尝试检索时间表并将时间片列表实例化为id,然后更新。

更新后的代码:

using (_serviceProxy = CrmConnector.GetOrganizationProxy(serverConfig))
                {
                    // This statement is required to enable early-bound type support.
                    _serviceProxy.EnableProxyTypes();
                    _service = (IOrganizationService) _serviceProxy;

                    var context = new CRMService(_serviceProxy);

                    var timesheetLineEntity = new New_timesheetlineitem()
                    {

                        // taken from user input 
                        New_startdatetime = timesheetLineVm.TimesheetLineViewModels.StartDate,
                        New_EndDateTime = timesheetLineVm.TimesheetLineViewModels.EndDate,
                        //new_paytypetimesheetlineitemid = Convert.ToString(timesheetLineVm.TimesheetLineViewModels.PayType),
                        //timesheetLineEntity["new_lunchtime"] = 2;
                        New_SubmittedHours = timesheetLineVm.TimesheetLineViewModels.SubmittedHours

                        //_timesheetlineId = _service.Create(timesheetLineEntity);
                    };


                    var timesheetLineItemList = new List<New_timesheetlineitem>();
                    timesheetLineItemList.Add(timesheetLineEntity);

                    var retrievedTimesheet = _serviceProxy.Retrieve("new_timesheet", new Guid(timesheetLineVm.TimesheetId.ToString()), new ColumnSet(new string[] {"new_firstname", "new_lastname", "new_name", "new_payrollreference", "new_timesheetdate", "new_timesheetid", "new_slatimesheetid", "new_stream3timesheetid", "new_candidatetimesheetid", "new_accounttimesheetid", "new_billtoid", "new_contracttypetimesheetid", "new_billratetimesheetid", "new_status", "new_timesheet_new_approverid", "new_invoiced"})) as New_timesheet;

                    if (retrievedTimesheet != null)
                    {
                        retrievedTimesheet.new_new_timesheet_new_timesheetlineitem = timesheetLineItemList;

                        _serviceProxy.Update(retrievedTimesheet);
                    }
                    //context.AddObject(timesheetLineEntity);
                    // context.SaveChanges();
                }

我现在收到以下错误:

  

System.ServiceModel.FaultException 1 was unhandled by user code
HResult=-2146233087 Message=Entity Id must be specified for Update
Source=mscorlib
Action=http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/UpdateOrganizationServiceFaultFault StackTrace: 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.Update(Entity entity) at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.UpdateCore(Entity entity) at Microsoft.Xrm.Sdk.Client.OrganizationServiceProxy.Update(Entity entity) at TimesheetSample.Controllers.TimesheetController.SaveTimesheetLine(TimesheetViewModel timesheetLineVm) in c:\Users\Demerson.Herculano\Documents\AES Projects\TimesheetSample\TimesheetSample\Controllers\TimesheetController.cs:line 159 at TimesheetSample.Controllers.TimesheetController.New(TimesheetViewModel timesheetVm) in c:\Users\Demerson.Herculano\Documents\AES Projects\TimesheetSample\TimesheetSample\Controllers\TimesheetController.cs:line 110 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary
2个参数)          在System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext   controllerContext,ActionDescriptor actionDescriptor,IDictionary 2 parameters) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8 1.b__7(IAsyncResult)   _)          在System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()          在System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult)   asyncResult)          在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c__DisplayClass37。&lt;&gt; c__DisplayClass39.b__33()          在System.Web.Mvc.Async.AsyncControllerActionInvoker。&lt;&gt; c__DisplayClass4f.b__49()   的InnerException:

提前致谢, DEM

2 个答案:

答案 0 :(得分:3)

问题在于您没有考虑Dynamics CRM的字段类型。

让我们检查这一行:

timesheetLineEntity["new_firstname"] = timesheetLineVm.TimesheetLineViewModels.EmployeeFirstName;
CRM中的new_firstname可能是single line of text字段,因此如果EmployerFistName是字符串,则设置值时没有问题。

现在检查这一行:

timesheetLineEntity["new_billtoid"] = timesheetLineVm.TimesheetLineViewModels.BillToId;

可能在CRM内部的字段new_billtoid是指向名为Lookupnew_billto的实体的new_bill。 C#中的查找字段映射为EntityReference,因此正确的方法(假设实体名称为new_billBillToId为GUID)为:

 timesheetLineEntity["new_billtoid"] =
 new EntityReference("new_bill", timesheetLineVm.TimesheetLineViewModels.BillToId);

底线:您需要检查您需要设置的所有字段的确切类型,并在必要时将它们转换为正确的类型。

答案 1 :(得分:0)

I am not clear about the approach but as it looks like you are using mvc approach or website where you are using CRM service to CRUD crm records.
So I am putting my points on that basis:


 1. First of all you have to check whether you are connected to CRM service or Not (I think you are connected to CRM service thats why are are getting those error message on create or update record but anyway you can check like this below) 

public void SaveTimesheetLine(TimesheetViewModel timesheetLineVm)
{
    string payrollId = Convert.ToString(Session["payroll"]);
    Initiate();
    using (_serviceProxy = CrmConnector.GetOrganizationProxy(serverConfig))
    {
        // This statement is required to enable early-bound type support.
        //_serviceProxy.EnableProxyTypes();
        _service = (IOrganizationService) _serviceProxy;


        WhoAmIRequest request = new WhoAmIRequest();
        WhoAmIResponse response = (WhoAmIResponse)_service.Execute(request);
        Guid userId= response.UserId;

        If(userId==null || userId==Guid.Empty)
            return; // if userid is null or empty then ur crm service is not connected.



 2. SaveTimesheetLine(TimesheetViewModel timesheetLineVm) you are passing timesheetlineVM, this indicates that you you are creating TimeSheetLine for a TimeSheet. I have reviewed you code and found some errors:
This is of EnntityReference (LookUp) Type and you are passing string value 

    timesheetLineEntity["new_payrollreference"] = new EntityReference("entitylogicalname",new Guid(payrollId));

You are not passing the TimeSheet for which this TimeSheetLine will create

    timesheetLineEntity["timesheeetid"]=new EntityReference("timesheet",new Guid(timesheetid));


3. [FaultException`1: System.NullReferenceException: Microsoft Dynamics CRM has experienced an error.
This type of error will come on those case when we are passing null value in CRM. Please check all the values in code and look which is null and required.


4. I have also looked on the Update Code ,this is wrong because in every case you don't have `timesheetLineVm.TimesheetId.ToString()` this will be null or blank.



    var timesheetLineEntity = new New_timesheetlineitem()
                        {

                            // taken from user input 
                            New_startdatetime = timesheetLineVm.TimesheetLineViewModels.StartDate,
                            New_EndDateTime = timesheetLineVm.TimesheetLineViewModels.EndDate,
                            //new_paytypetimesheetlineitemid = Convert.ToString(timesheetLineVm.TimesheetLineViewModels.PayType),
                            //timesheetLineEntity["new_lunchtime"] = 2;
                            New_SubmittedHours = timesheetLineVm.TimesheetLineViewModels.SubmittedHours

                            //_timesheetlineId = _service.Create(timesheetLineEntity);
                        };


                        var timesheetLineItemList = new List<New_timesheetlineitem>();
                        timesheetLineItemList.Add(timesheetLineEntity);

                        var retrievedTimesheet = _serviceProxy.Retrieve("new_timesheet", new Guid(timesheetLineVm.TimesheetId.ToString()), new ColumnSet(new string[] {"new_firstname", "new_lastname", "new_name", "new_payrollreference", "new_timesheetdate", "new_timesheetid", "new_slatimesheetid", "new_stream3timesheetid", "new_candidatetimesheetid", "new_accounttimesheetid", "new_billtoid", "new_contracttypetimesheetid", "new_billratetimesheetid", "new_status", "new_timesheet_new_approverid", "new_invoiced"})) as New_timesheet;

you are declaring `var timesheetLineEntity` and using `timesheetLineVm.TimesheetId.ToString()` in the next line. timesheetLineEntity will only contain these three `New_startdatetime,New_EndDateTime,New_SubmittedHours`


I think you have to review this and in case you need my help I'll glad to support you.

Please ignore if this is not helpful for you.