The CrmEntityFormView is an custom server control that renders a managed form in an Adxstudio Portal based on a particular form or view customization defined on an entity within CRM (See Managed Forms). The form can edit, insert or display readonly records depending on the mode property assigned to the control.

Adding CrmEntityFormView to a Page Template

The following control declaration can be added to an ASP.NET page template in the Visual Studio Web Application project.

<adx:CrmEntityFormView runat="server" ID="FormView" EntityName="lead" FormName="Web Form" DataSourceID="FormViewDataSource"></adx:CrmEntityFormView>

The control also requires a seperate declaration for a CrmDataSource control that is used for databinding. For complete details see CrmDataSource.

<adx:CrmDataSource ID="FormViewDataSource" runat="server" />

Dependencies

For the Datepicker to be rendered you will need to include a script reference to the yahoo script and stylesheet file that is providing the calendar interface. For more details please refer to the Datepicker.

Properties

The CrmEntityFormView control has several properties that can be specified to modify the behavior.

Name Description
EntityName The logical name of the entity in CRM that contains the form or saved query view used to render the form.
Mode

One of the following:

  • Insert Default
  • Edit
  • ReadOnly
If Edit or ReadOnly is specified, the CrmDataSource control will require data or a databinding error will occur during runtime. See CrmDataSource.
FormName

The name of the form on an entity to be loaded.

TabName The name of a tab on a form on an entity to be loaded.
SavedQueryName The name of a saved query view for an entity in CRM to be loaded as a form.
DataSourceID The ID of the CrmDataSource control used for databinding.
LanguageCode

An integer value of the language code or Locale ID of a language pack installed and provisioned in the CRM organization used to localize labels. See Microsoft Locale ID Values. Example: LanguageCode="1036".

This is only required if you wish to display localized labels for a language other than the CRM organization's base language.
This should be assigned during the page's Init method.
ToolTipEnabled

The description of the attribute in the entity metadata will be used as the text for the field's tooltip if enabled. Default is false.

RecommendedFieldsRequired

Set to "true", indicates that fields with the requirement level set to 'Busines Recommended' should be made required. Default is false.

RenderWebResourcesInline

CRM wraps Web Resources in an iframe by default. Set to "true", indicates that Web Resources should be rendered without an iframe.

ValidationText

The text to be assigned to the validator control that displays next to the control's label when validation fails. The default is '*".

ValidationGroup The group name assigned to input controls for evaluating valid input of named groups.
AutoGenerateSteps Set to "false" indicates that the entire form should be rendered. Set to "true" indicates that the tabs on the form should be rendered as ordered steps like a wizard. The default is "true".
ForceAllFieldsRequired Set to "true" indicates that all fields should be made mandatory. The default is "false".
EnableValidationSummaryLinks Set to "true" indicates that the validation summary should render anchor links next to the validation error message to allow scrolling to the field in position on the form. Set to "false" results in ommission of the anchor links. Default is "true".
ValidationSummaryLinkText The text of the links displayed in the validation summary. Requires EnableValidationSummaryLinks="true". Default is "Click here"
ConfirmOnExit Set to "true" indicates a message should be displayed when the user attempts to close the browser or refresh the page while changes have not been saved. Default is "false".
ConfirmOnExitMessage The message to be displayed when the user attempts to close the browser or refresh the page while changes have not been saved. Requires ConfirmOnExit="true"
PreviousButtonCssClass CSS Class name assigned to the previous button. Default is 'button'
PreviousButtonText Label on the previous button. Default is 'Previous'
NextButtonCssClass CSS Class name assigned to the next button. Default is 'button'
NextButtonText Label on the next button. Default is 'Next'
SubmitButtonCssClass CSS Class name assigned to the submit button. Default is 'button'
SubmitButtonText Label on the submit button. Default is 'Submit'
DataBindOnPostBack

Allows rebinding of data on postback. Default is "false".

On PostBack The CrmEntityFormView will not re-databind if this value is false. If a user has selected values from option set dropdown fields and a control in the page causes a PostBack, re-databinding will clear the user selected value and load the values and select the default option according to the data and metadata in CRM. If you are changing the underlying datasource data programatically then set this value to "true" to allow the CrmEntityFormView to rebind accordingly.

ShowUnsupportedFields Value of "true" or "false". All fields are currently supported. This is reserved for potential changes CRM may make to field types. 
ContextName The portal context configuration name that the control binds to.  Default value is unassigned.
You should ensure the content placeholder that contains the CrmEntityFormView control has ViewStateMode="Enabled" or the control may not bind property on postback.

Events

There are several events that can be consumed or raised to allow for custom behavior.

Name Description
UpdateItem The event that can be raised to update the record.
OnItemUpdating The event that occurs immediately prior to updating the record.
OnItemUpdated  The event that occurs when the record has been updated.
InsertItem The event that can be raised to insert the record.
OnItemInserting  The event that occurs immediately prior to inserting the record.
OnItemInserted The event that occurs when the record has been inserted.

Raising UpdateItem

Manually raising the event to update the record can be done by calling the UpdateItem method on the control. The following example assumes the CrmEntityFormView's ID property has been set to "FormView". This is useful if you need to combine multiple CrmEntityFormView controls on one page or if you need to add additional controls to the page and would like to persist all data across all controls with one button click.

FormView.UpdateItem();

Consuming OnItemUpdating

The following is an example of an OnItemUpdating event handler. This allows you to add values to the attribute collection that is to be updated on the entity.

protected void OnItemUpdating(object sender, CrmEntityFormViewUpdatingEventArgs e)
{
	e.Values["adx_publisheddate"] = DateTime.UtcNow;
}

Consuming OnItemUpdated

The following is an example of an OnItemUpdated event handler.

protected void OnItemUpdated(object sender, CrmEntityFormViewUpdatedEventArgs e)
{
	// display success message
	SuccessMessage.Visible = true;
}

Raising InsertItem

Manually raising the event to insert the record can be done by calling the InsertItem method on the control. The following example assumes the CrmEntityFormView's ID property has been set to "FormView". This is useful if you need to combine multiple CrmEntityFormView controls on one page or if you need to add additional controls to the page and would like to persist all data across all controls with one button click.

FormView.InsertItem();

Consuming OnItemInserting

The following is an example of an OnItemInserting event handler. This allows you to modify or add values to the attribute collection that is to be set on the entity during insert.

protected void OnItemInserting(object sender, CrmEntityFormViewInsertingEventArgs e)
{
	e.Values["adx_applicantid"] = Contact.ToEntityReference();
	e.Values["adx_name"] = string.Format("Job application by {0} for {1}", Contact.Fullname, CurrentJobPosting.Adx_name);
}

Consuming OnItemInserted

The following is an example of an OnItemInserted event handler. Now that the item is created, we can use the Guid value of the newly created record's Unique Identifier that passed into the event args EntityId property. The event handler is commonly used to associate additional records and/or hide the form and display a success message.

protected void OnItemInserted(object sender, CrmEntityFormViewInsertedEventArgs e)
{
	var jobApplication = XrmContext.Adx_jobapplicationSet.Where(i => i.GetAttributeValue<Guid>("adx_jobapplicationid") == e.EntityId).FirstOrDefault();
	var attachment = (FileUpload)ApplicationForm.FindControl("FormView").FindControl("Attachment");
	var noteSubject = "Note created on " + DateTime.Now + " by " + Contact.FirstName + " " + Contact.LastName;
	XrmContext.AddNoteAndSave(jobApplication, noteSubject, "*WEB* ", attachment.PostedFile);
	ApplicationForm.Visible = false;
	ConfirmationMessage.Visible = true;
}

Item Templates

The CrmEntityFormView control is a templated control that allows for custom HTML and server controls to be appended to the form through the declaration of item templates.

The data for the controls added to the templates must be manually persisted by specifying event handlers when declaring the CrmEntityFormView control that will contain the logic necessary that will leverage the sdk to save the data. See Events above.
Name Description
InsertItemTemplate Template that can be declared when the Mode="Insert"
UpdateItemTemplate  Template that can be declared when Mode="Edit" 
ReadOnlyItemTemplate  Template that can be declared when Mode="ReadOnly" 

InsertItemTemplate Example

The following example adds a captcha to the form.

<adx:CrmEntityFormView runat="server" ID="FormView"
	EntityName="lead" FormName="Web Form" DataSourceID="FormViewDataSource">
	<InsertItemTemplate>
		<asp:CustomValidator ID="RecaptchaValidator" runat="server"
			ValidationGroup="ContactUs" 
			ErrorMessage="reCAPTCHA is invalid. Please try again."
			OnServerValidate="RecaptchaValidator_ServerValidate" Display="None" />
		<recaptcha:RecaptchaControl ID="RecaptchaImage" runat="server"
			PublicKey='<%$ SiteSetting: Recaptcha/PublicKey, null %>'
			PrivateKey='<%$ SiteSetting: Recaptcha/PrivateKey, null %>' />
		<div class="actions">
			<asp:Button ID="SubmitButton" Text='<%$ Snippet: ContactUs/Submit, Submit %>'
				CssClass="button" CommandName="Insert"
				ValidationGroup="ContactUs" runat="server" />
		</div>
	</InsertItemTemplate>
</adx:CrmEntityFormView>

Adding Custom Validators

There are times when CRM's native field validation is not adequate. The CrmEntityFormView provides a field templating that allows for additional ASP.NET Validator controls to be bound to fields on a form in addition to the existing validators specified by attribute metadata. 

<adx:CrmEntityFormView runat="server" ID="FormView"
	EntityName="lead" FormName="Web Form" DataSourceID="FormViewDataSource">
	<Fields>
        	<adx:CrmEntityFormViewField runat="server" AttributeName="lastname">
                	<CustomValidatorsTemplate>
                        	<asp:CustomValidator ID="lastname_customvalidator"  runat="server"
                                	ErrorMessage="Custom Validator Error" 
                                        ValidationGroup="ContactUs"
                                        OnServerValidate="OnServerValidateLastName">
                                </asp:CustomValidator>
                        </CustomValidatorsTemplate>
                </adx:CrmEntityFormViewField>
	</Fields>
</adx:CrmEntityFormView>

The following is an example of the method signature for the custom validator's OnServerValidate event handler. Although this is a arbitrary and trivial example it provides the necessary details for constructing your own event handler.

protected void OnServerValidateLastName(object sender, ServerValidateEventArgs e)
{
	if (e.Value != null && e.Value.Length >= 2)
	{
		e.IsValid = true;
	}
	else
	{
		e.IsValid = false;
	}
}

For more details regarding ASP.NET CustomValidator please refer to msdn http://msdn.microsoft.com/en-us/library/303z9x0x.aspx

Providing Custom Message Format Strings 

The default message strings used by the CrmEntityFormView control can be customized by specifying format strings in the Messages template. The example shown also retrieves the strings from Site Settings to allow for customization from within CRM.

<adx:CrmEntityFormView runat="server" DataSourceID="WebFormDataSource">
  <Messages>
    <adx:CrmEntityFormViewMessage MessageType="required" FormatString="<%$ SiteSetting: FormView/Messages/Validation/Required, {0} is a required field. %>" />
    <adx:CrmEntityFormViewMessage MessageType="integer" FormatString="<%$ SiteSetting: FormView/Messages/Validation/Integer, {0} is not a valid integer value. %>" />
    <adx:CrmEntityFormViewMessage MessageType="range" FormatString="<%$ SiteSetting: FormView/Messages/Validation/Range, {0} must have a value between {1} and {2}. %>" />
    <adx:CrmEntityFormViewMessage MessageType="float" FormatString="<%$ SiteSetting: FormView/Messages/Validation/Float, {0} is not a valid floating-point value. %>" />
    <adx:CrmEntityFormViewMessage MessageType="decimal" FormatString="<%$ SiteSetting: FormView/Messages/Validation/Decimal, {0} is not a valid decimal value. %>" />
    <adx:CrmEntityFormViewMessage MessageType="email" FormatString="<%$ SiteSetting: FormView/Messages/Validation/Email, {0} is not a valid e-mail address. %>" />
    <adx:CrmEntityFormViewMessage MessageType="date" FormatString="<%$ SiteSetting: FormView/Messages/Validation/Date, {0} is not a valid date format. %>" />
    <adx:CrmEntityFormViewMessage MessageType="boolean" FormatString="<%$ SiteSetting: FormView/Messages/Validation/Boolean, Please check the box labeled '{0}' to continue. %>" />
  </Messages>
</adx:CrmEntityFormView>

Field Rendering

The subject field will be rendered as a dropdown. Dashes will be injected into the option labels to represent the hierarchy. Example:

Parent A
– Child A1
– Child A2
– – Grandchild A21
– – Grandchild A22
Parent B
– Child B1
– – Grandchild B11
– Child B2

Handling Exceptions

If a CRM business process or plugin throws an error you can intercept that exception and do something by inspecting the exception object on the event args of the OnItemUpdated or OnItemInserted event handlers.

protected void OnItemUpdated(object sender, CrmEntityFormViewUpdatedEventArgs e)
{
if (e == null)
{
return;
}
if (e.Exception != null)
{
Response.Write("<div class='container' role='alert'><div class='alert alert-block alert-danger'> <p class='text-danger'><span class='fa fa-exclamation-triangle' aria-hidden='true'></span> " + Server.HtmlEncode(e.Exception.InnerException == null ? e.Exception.Message : e.Exception.InnerException.Message) + "</p></div></div>");
e.ExceptionHandled = true;
}
}
protected void OnItemInserted(object sender, CrmEntityFormViewInsertedEventArgs e)
{
if (e == null)
{
return;
}
if (e.Exception != null)
{
Response.Write("<div class='container' role='alert'><div class='alert alert-block alert-danger'> <p class='text-danger'><span class='fa fa-exclamation-triangle' aria-hidden='true'></span> " + Server.HtmlEncode(e.Exception.InnerException == null ? e.Exception.Message : e.Exception.InnerException.Message) + "</p></div></div>");
e.ExceptionHandled = true;
}
}