In CRM 4.0 we could place dynamic content (aspx) in the ISV-folder in CRM, creating separate applications but with security and relative URLs to CRM, so for example a custom 360 view of account could be linked in an iframe using a relative URL along the lines of
/ISV/CrmMvcApp/Account.aspx/Overview?id=....
In CRM 2011 usage of the ISV folder is deprecated and Microsoft has some guidelines on how to transition into doing this in supported manner (MSDN gg309571: Upgrade Code in the ISV folder to Microsoft Dynamics CRM 2011). They say:
For scenarios that will not be satisfied by the Web resources feature, create your Web application in its own application pool with its own web.config.
The way I am reading this (coupled with the guidelines on supported/unsupported) is that we need a separate web site in IIS with its own binding as you are not allowed to add virtual directories etc. under the standard CRM app. This is unfortunate and does not allow relative paths/URLs in customizations and sitemap. This is troublesome especially when exporting and importing solutions from DEV, TEST and/or PROD.
Are my assumptions wrong?
Can we somehow have relative paths?
Have anyone else found a pragmatic and easy approach to having external content without doing the sitemap and customization changes for each environment?
EDIT: Confirmed with other sources that my understanding of the guidelines are correct, as this is also listed in the list of unsupported changes. Virtual folders and web apps are to be kept totally separated from the default CRM web site.
Creating an Internet Information Services (IIS) application inside the Microsoft Dynamics CRM website for any VDir and specifically within the ISV folder is not supported.
MSDN gg328350: Unsupported Customizations
If you primarily need to access CRM data/records, take a look at using a jScript web resources. You can do "most" CRUD operations using the REST OData services. If you use JQuery to parse the JSON it's very productive.
I have found a solution much like the javascript redirect, without the need for client execution and only configuring the environment details (servername, port) once. Additional logic can easily be added.
The solution creates a dependency into the customizations, but not an environment one like and can be used for unmanaged and managed solutions.
The solution was to place a file Redirect.aspx in the ISV folder. The code does not in any way interact with CRM and falls within the supported guidelines, however the solution is not future proof as the ISV folder is deprecated by Microsoft.
Redirect.aspxwill automatically pass along any parameter passed, so will work with or without the entity identifiers and so on.
Usage:
Place the file in the ISV folder on the CRM app server
Change the server name and port to match the current environment (must be done for each environment)
In customizations, for example for an iframe, use the following as a source:
/ISV/Redirect.aspx?redirect=http://SERVERREPLACE/CustomMvcApp/SomeControllerAction
Here is the content of Redirect.aspx
<%# Page Language="C#" %>
<html>
<script runat="server">
protected override void OnLoad(EventArgs e)
{
// must be customized for each environment
const string ServerBaseName = "appserver1:60001";
const string UrlParameterName = "redirect";
const string ReplacePattern = "SERVERREPLACE";
var parameterUrl = Request.Params[UrlParameterName].Replace(ReplacePattern, ServerBaseName);
var queryStringBuilder = new StringBuilder();
foreach (var key in Request.QueryString.AllKeys)
{
if (key == UrlParameterName)
{
continue;
}
queryStringBuilder.Append(!(queryStringBuilder.Length > 0) ? "?" : "&");
queryStringBuilder.Append(key + "=" + Request.QueryString[key]);
}
var completeRedirectString = parameterUrl + queryStringBuilder;
Response.Redirect(completeRedirectString);
}
</script>
<head>
<title>Redirecting</title>
</head>
</html>
Not quite "relative urls" as per your question, but a solution I use is to store "stub" or "root" urls in a config entity and read those records in JScript at runtime to determine the fully qualified destination for your custom links.
Related
Does anyone know of a managed solution to import into Dynamics 365 that adds functionality for a custom button to copy the Guid of any entity to your clipboard?
In a previous environment we used this one
Of course this can't be imported into the newer Dynamics 365.
I know how to parse out the Guid from the URL, but the button to autocopy it to the clipboard was amazing.
The Chrome Extension Level Up has button for Record Id, or you can use the bookmarklet code. Just add the below code to a bookmark in your browser:
//get record id
javascript: (function () { var form = $("iframe").filter(function () { return $(this).css("visibility") == "visible" })[0].contentWindow; window.prompt("Copy to clipboard: Ctrl+C, Enter", form.Xrm.Page.data.entity.getId().slice(1, -1)) })();
Try Level Up for Dynamics 365 Chrome Extension, it provides a great variaty of common JScript actions and shortcuts to help with extensibility, diagnostics and administration
if what you need is to pulish an option to your user to get the GUID of a record and prevent the execution of other JS logic such as display all hidden attributes, then you will have to create a ribbon button and execute JS logic contained in a webresource, to make it compatible with CRM v9 and forward, past the execution context to your function (PrimaryControl) and call the native Xrm function executionContext.getFormContext().data.entity.getId()
Another extremely useful Chrome called Dynamics Power Pane. Use it together with Level Up for Dynamics 365 will be very powerful.
Is there any difference between updating an entity using a Plugin vs Updating an entity using XrmServiceToolkit?
var entityA= new XrmServiceToolkit.Soap.BusinessEntity("entA", id);
entityA.attributes["attrA"] = { value: attrValue1, type: "OptionSetValue" };
entityA.attributes["attrB"] = { value: attrValue2, type: "Money" };
XrmServiceToolkit.Soap.Update(entityA);
I know plugin can be used to connect to external databases but for a very basic update, is there any difference?
Thank you!
Operations in plugins are seemless integrated with the business logic of your CRM platform. Plugins are invoked in any scenario, regardless if they are triggered by a webpage (Javascript calls, e.g. using XrmServiceToolkit), workflow, external systems, integration tools or even other plugins.
An update done on your web page by Javascript only works on that form. If you only need it there, it's fine. If you need to cover other scenarios as well, you may have to look for another solution.
I have a List defined in a SharePoint Site e.g. Countries list.
In another site, I have a List that needs to have a column with multilookup to the above Countries list. (So these 2 sites are separate sites)
How would that be possible to configure this in SharePoint 2010?
Thanks,
That is possible but requires some programming or scripting, because cross site lookup field can't be configured using web UI.
PowerShell code should be following:
$web1 = Get-SPWeb "http://site/web1" $web2 = Get-SPWeb
"http://site/web2" $list = $web1.Lists["My list"]
$lookupList = $web2.Lists["My lookup list"]
$list.Fields.AddLookup("MyCrosssiteLookup", $lookupList.ID, $web2.ID,
$false) $lookupField =
list.Fields.GetFieldByInternalName(InternalName)
$lookupField.Title = "My cross site lookup"
$lookupField.Update()
Alternatively you can use LookupWithPicker field type, it has web UI control to configure cross-site lookpups: http://ilovesharepoint.codeplex.com/releases/view/44989.
We use TFS to deploy our applications to multiple environments (Dev, QA, Prod). Simple enough, our Dev and QA environments have URLS like dev.domain/APPLICATION and qa.domain/APPLICATION. So we have a single site with each application as a virtual application.
However in production, they want each application to be its own site, such as APPLICATION.domain.com... Grrr! In Visual Studio, the application's properties is configured to be in a "Virtual Path". I"m not sure how I should go about this issue. The appliation contains code such as: <a href='/APPLICATION/File/Download?id=<#= PkFileId #>'><#= Name #></a> which causes problems in production since its not in a virtual application.
I could make a site called application.domain.com with an empty directory. Then add a Virtual Application, but then I would have to put a redirect in the root of the site to go to the virtual application. Or perhaps I can somehow configure the application? Not sure what my options are... Any suggestions are appreciated!
The appliation contains code such as:
<a href='/APPLICATION/File/Download?id=<#= PkFileId #>'><#= Name #></a>
ASP.NET MVC applications should not contain code like that (a code in which urls are hardcoded). In ASP.NET MVC applications you should always use HTML and Url helpers:
#Html.ActionLink(
Model.Name,
"Download",
"File",
new { id = Model.PkFileId },
null
)
This way it is certain that no matter how your routes are configured or under which virtual directory your application is hosted, it should work.
UPDATE:
After your comment it looks like you are using the Telerik Grid. In this case you may try something along the lines to generate proper anchors:
columns
.Bound(x => x.PkFileId)
.ClientTemplate(
Html.ActionLink(
"<#= Name #>",
"Download",
"File",
new { id = "<#= PkFileId #>" },
null
).ToString()
)
.Title("");
I know this is possible via a simple registry change to accomplish this as long as IE/firefox is being used. However, I am wondering if there is a reliable way to do so for other browsers,
I am specifically looking for a way to do this via an installer, so editing a preference inside a specific browser will not cut it.
Here is the best I can come up with:
IE: http://msdn.microsoft.com/en-us/library/aa767914(VS.85).aspx
FireFox: http://kb.mozillazine.org/Register_protocol
Chrome: Since every other browser in seems to support the same convention, I created a bug for chrome.
Opera: I can't find any documentation, but it appears to follow the same method as IE/Firefox (see above links)
Safari: Same thing as opera, it works, but I can't find any documentation on it
Yes. Here is how to do it with FireFox:
http://kb.mozillazine.org/Register_protocol
and Opera:
http://www.opera.com/support/kb/view/535/
If someone looks like a solution for an intranet web site (for all browsers, not only IE), that contains hyperlinks to a shared server folders (like in my case) this is a possible solution:
register protocol (URI scheme) via registry (this can be done for all corporative users i suppose). For example, "myfile:" scheme. (thanks to Greg Dean's answer)
The hyperlink href attribute will then should look like
<a href='myfile:\\mysharedserver\sharedfolder\' target='_self'>Shared server</a>
Write a console application that redirects argument to windows explorer (see step 1 for example of such application)
This is piece of mine test app:
const string prefix = "myfile:";
static string ProcessInput(string s)
{
// TODO Verify and validate the input
// string as appropriate for your application.
if (s.StartsWith(prefix))
s = s.Substring(prefix.Length);
s = System.Net.WebUtility.UrlDecode(s);
Process.Start("explorer", s);
return s;
}
I think this app can be easily installed by your admins for all intranet users :)
I couldn't set up scheme setting to open such links in explorer without this separate app.