We have just upgraded from Microsoft Dynamics CRM 4 to Microsoft Dynamics CRM 2011. Most of the upgrade has gone smoothly, however I have some custom code (written for CRM 4) which was implemented as an ASPX page in the CRM 4 ISV folder. This code has stopped working since the upgrade.
Our Dynamics CRM 2011 server is set up On Premise, as an IFD deployment.
The code connects to the CRM Server as follows:
using (new CrmImpersonator())
{
string crmurl = "https://<server>:444/<org>/mscrmservices/2007/CrmService.asmx";
string orgname = <org>;
CrmAuthenticationToken token = CrmAuthenticationToken.ExtractCrmAuthenticationToken(context, orgname);
token.OrganizationName = orgname;
token.AuthenticationType = 0;
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
service.CrmAuthenticationTokenValue = token;
service.Url = crmurl;
WhoAmIRequest who = new WhoAmIRequest();
WhoAmIResponse whoResponse = (WhoAmIResponse)service.Execute(who);
Upon sending the WhoAmIRequest I receive the following exception:
The request failed with the error message:
--
<html><head><title>Object moved</title></head><body>
<h2>Object moved to here.</h2>
</body></html>
--.
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at Microsoft.Crm.SdkTypeProxy.CrmService.Execute(Request Request)
at ForecastConverterWeb.CashflowForecast.ToCrm(HttpContext context)
at ForecastConverterWeb._Default.submitbtn_click(Object sender, EventArgs e)
It seems that when the code tries to send the request to https://:444//mscrmservices/2007/CrmService.asmx the page returns a link to redirect to, well... itself (https://:444//mscrmservices/2007/CrmService.asmx).
I've tried using the internal address (port 5555), external IFD address (https over port 444) and internal IFD (https over port 444) address all with the same result. I know that in CRM 2011 ISV is being depreciated, but the considering the amount of time it would take to re-develop this software (and the fact that considering it's supported code, I shouldn't have to) I'd rather just get this working as it should (according to this: http://msdn.microsoft.com/en-us/library/gg309571.aspx)
I'm grateful in advance for any help anyone can offer.
Your code makes it look like you put the organization name between the host and the path to the /2007/crmservice.asmx. Don't do that. I know you have to prepend the organization name when on-premise to custom aspx/asmx files in the ISV directory, but as far as I've ever tried it doesn't work for crmservice.asmx.
Related
We have a .Net app using Google Drive api to upload files to a g-drive. And it just stopped working days ago (Nov 29th). But we didn't remember doing anything changes during that time.
During the investigation, we could confirm the service account for calling the Google API are valid, since the same service account is also being used for calling other google APIs, and works fine. We also can confirm it's not a permission issue, since we even set the permission of the gdrive to allow "anyone" who has the link, to have edit permission, but the issue is still there.
Unfortunately, we cannot find any useful log, and the return message of the API call is NULL. No error code or error message returned.The only related info we saw is: on the chart of "Error by API method", it shows "drive.files.create" failed 100%.
One interesting thing is, if we disable the Google Drive API, then enable it again, it will work once, then will stop working again.
private string SaveFileToGoogleDrive(IFormFile file, string claimNumber)
{
try
{
var driveService = GetDriveServiceInstance();
var fileMetadata = new Google.Apis.Drive.v3.Data.File();
var mimeType = file.ContentType;
fileMetadata.Name = CreateFileName(file.FileName, claimNumber);
fileMetadata.MimeType = mimeType;
fileMetadata.Parents = new List { _googleSettings.GoogleDriveFolderId };
FilesResource.CreateMediaUpload request;
using (var stream = new MemoryStream())
{
file.CopyTo(stream);
request = driveService.Files.Create(fileMetadata, stream, mimeType);
request.Fields = "id";
request.Upload();
}
var googleFile = request.ResponseBody; \\The response body is always NULL, after the issue happened. :(
return googleFile.Id;
}
catch(Exception ex)
{
_logger.Error($"Google Drive exception {ex.Message} SACKTRACE: {(ex.StackTrace ?? "")} INNER EXCEPTION: {(ex.InnerException != null ? ex.InnerException.Message + "STACK TRACE:" + ex.InnerException.StackTrace ?? "" : "")}");
return string.Empty;
}
}
We found more details from the progress property in the response object, and saw the error message "The user's Drive storage quota has been exceeded.", but it does not make sense at all, since we are using "Enterprise edition" Google Workspace, which is supposed to have no limit. The service account and the key look good, GCP didn't complain at all. And that's the first thing we checked during troubleshooting.
Do you have any idea on what to do to solve the issue or what too look for when investigating this issue?
We found more details from the progress property in the response object, and saw the error message "The user's Drive storage quota has been exceeded.", but it's not make sense at all, since we are using "Enterprise editions" google workspace, which suppose has no limit. The service account and key look good, GCP didn't complain any thing. And that's the first thing we checked during troubleshooting. Anyway, the fix is: after create a new service account then use the new key of this new service account, the system back to work.
I've been trying to use this interop in my MVC 4 project. I tried to make it simple just to get the idea. but I get an error "Retrieving the COM class factory for component with CLSID {0006F03A-0000-0000-C000-000000000046} failed due to the following error: 80010001 Call was rejected by callee. (Exception from HRESULT: 0x80010001 (RPC_E_CALL_REJECTED))."
Here's my simple code:
using Outlook = Microsoft.Office.Interop.Outlook;
[HttpPost]
public ActionResult SendEmail(SendEmailModel model)
{
if (ModelState.IsValid)
{
Outlook.Application app = new Outlook.Application();
Outlook.NameSpace ns = app.GetNamespace("MAPI");
ns.Logon("", "", Missing.Value, Missing.Value);
Outlook.MailItem mailItem = (Outlook.MailItem)app.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.To = model.To;
mailItem.Subject = model.Subject;
mailItem.Body = model.Message;
((Outlook.MailItem)mailItem).Send();
app = null;
ns = null;
return RedirectToAction("Index", "TechFile");
}
return View(model);
}
Anyway I found Outlook redemption is an alternative way of doing this. but I don't know to get it started.
I resolved this by following this. http://support.microsoft.com/kb/329854
Also I'd recommend reading the Considerations for server-side Automation of Office article which states the following:
Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment.
If you are building a solution that runs in a server-side context, you should try to use components that have been made safe for unattended execution. Or, you should try to find alternatives that allow at least part of the code to run client-side. If you use an Office application from a server-side solution, the application will lack many of the necessary capabilities to run successfully. Additionally, you will be taking risks with the stability of your overall solution.
I am trying to send an email from a client PC (i.e. Windows) with an attachment and have the attachment saved to a local folder on the same client PC. I have looked at a couple of alternatives, such as MailDrop (email to dropbox) and Outlook 2003 Interop library - but want to make sure I am implementing this the best way.
Does anyone have any different ideas on a simple/elegant solution?
As long as you know Outlook will be installed on all the clients the Outlook solution works very well. You can create a file and save it, then in your outlook interop you just attach and send. You didn't specify what tools you are using but here's the basic email creation method I use for Outlook in C# (Where OutlookSetup.OutlookApp is just a static method that returns the currently open instance of the Outlook application or creates a new one if Outlook isn't open). Otherwise there are several examples here on SO of using SmtpClient to achieve similar ends.
public EmailMessage(EmailInfo emailInfo, string filenameToAttach=null)
{
Message = OutlookSetup.OutlookApp.CreateItem(OL.OlItemType.olMailItem);
Message.To = emailInfo.To;
Message.CC = emailInfo.Cc ?? "";
Message.Subject = emailInfo.Subject;
if (filenameToAttach != null)
{
Message.Attachments.Add(filenameToAttach);
}
}
I using in my project BITS - Background Intelligent Transfer Service for send file with larg size. Using SharpBITS.NET in C# code.
I want to upload file from server to client. I now note the sides.
-------------client side---------------
static void Main(string[] args)
{
string local = #"I:\a.mp3";
string destination = "http://192.168.56.128/BitsTest/Home/FileUpload";
string remoteFile = #destination;
string localFile = local;
if (!string.IsNullOrEmpty(localFile) && System.IO.File.Exists(localFile))
{
var bitsManager = new BitsManager();
var job = bitsManager.CreateJob("uploading file", JobType.Upload);
job.NotificationFlags = NotificationFlags.JobErrorOccured | NotificationFlags.JobModified |
NotificationFlags.JobTransferred;
job.AddFile(remoteFile, localFile);
job.Resume();
job.OnJobError += new EventHandler<JobErrorNotificationEventArgs>(job_OnJobError);
}
}
This is a simple console application. the local -- path the file that I want to send, destination -- the path is receiver it is remote server.
When I run program the job.Error take mi follow --- "The server's response was not valid. The server was not following the defined protocol. Resume the job, and then Background Intelligent Transfer Service (BITS) will try again. -- BG_E_HTTP_ERROR_200 .-2145845048, 0x801900C8"
For Client (receiver) i have the follow code: It is Mvs 3 small project and I View only action
where to go by our destination path.
public ActionResult FileUpload()
{
try
{
HttpPostedFileBase file = Request.Files[0];
file.SaveAs(System.IO.Path.Combine(Server.MapPath("/BitsTest/"), file.FileName));
}
catch
{ }
/*System.IO.File.Move(Server.MapPath("/BitsTest/bin/aa.png"), Server.MapPath("/BitsTest/Content/aa.png"));*/
}
But FileUpload action thas not recevie file. I don't know how I can receive file in client Side.
As you can see, I used HttpPostedFileBase for recive file but that is not working.
My host server is Windows server 2008 r2 and I done needed steps for BITS. For more information you can visit the follow site http://technet.microsoft.com/en-us/library/cc431377.aspx ---- How to Configure Windows Server 2008 for Configuration Manager 2007 Site Systems.
So I don't know what doing that I can receive file in host server.You can tell me what you can do.
With a stateless methdology like the one web applications use, there is no connection to the server once the response is completed. You can poll the server from the client side, but the client is not listening for the server to send additional bits.
In "the past" you could set up ActiveX controls, Java applets, etc (Silverlight today?) to continue to listen, but this is not straight web style development.
HTML5 expands your options, if you are willing to use the websocketAPI. As with all parts of HTML5, you have some risk using these bits for implementation as not all browsers have adopted the "standard" yet (adoption expected to be complete in the next 10-12 years:->).
I was encouraged to learn that the Sharepoint 2010 Client Object Model essentially wraps remote calls to the server. So, I copied the Microsoft.Sharepoint.Client.Silverlight.dll and Microsoft.Sharepoint.Client.Silverlight.Runtime.dll from my Sharepoint 2010 server to my development machine (without Sharepoint). I assumed the Silverlight code I tested on the Sharepoint 2010 server would also work on my development machine. Naturally, I don't use the "ApplicationContext.Current.Url" because I am not executing in Sharepoint, so I manually add sharepoint server name as follows (kept anonymous for the post):
//ClientContext context = new ClientContext(ApplicationContext.Current.Url);
ClientContext context = new ClientContext("https://[servername]");
_web = context.Web;
context.Load(_web);
context.Load(_web.Lists);
context.ExecuteQueryAsync(new ClientRequestSucceededEventHandler (OnRequestSucceeded), new ClientRequestFailedEventHandler(OnRequestFailed));
When I execute the code, I am prompted by a Windows Authentication window (Sharepoint is configured to use Windows Authentication), I add my domain/user and password. However, I am getting the following error:
Note: I was able to get Sharepoint 2010 web services working given a similar error by changing the binding security mode="Transport" and including a clientAccessPolicy.xml file on the Sharepoint root website. Do I need to configure another Sharepoint directory for thje Client Object Model endpoint?
Exception {System.Security.SecurityException ---> System.Security.SecurityException: Security error.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.b__0(Object sendState)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryGetResponseAsyncCallback(IAsyncResult asyncResult)} System.Exception {System.Security.SecurityException}
Please look in to the below blog post, you need to add clientaccesspolicy.xml file in your sharepoint website root folder.
http://vangalvenkat.blogspot.com/2011/08/sharepoint-2010-getting-list-item.html
Aha, I found it. You can set the security on the client context to use the default windows authentication like so:
using (Microsoft.Sharepoint.Client.ClientContext ctx = new Microsoft.Sharepoint.Client.ClientContext("http://sharepointserver")){
ctx.AuthenticationMode = Microsoft.Sharepoint.Client.ClientAuthenticationMode.Default
}
This should also prevent any windows authentication pop-ups