Thursday, 30 January 2014

CRM 2011: How do I validate that a text field is numeric?

I need to change the format of an ID field in CRM 2011. The system settings were inserting commas as thousands separators and this looks strange for an ID (ID 123,456 is just not right).

I recreated the field as a text field, but I needed to validate the input.I therefore created the following functions that I added to the 'onSave' list of my CRM form:

When configuring the script, ensure that 'pass context as the first parameter' is set and then pass in the name of the field to search (in double quotes).

Here is the script:

validateIDOnSave = function(executionObj, IDField)
{
    var IDFieldValue = Xrm.Page.getAttribute(IDField).getValue();

    if(IDFieldValue != null)
    {
      var IDFieldObject = Xrm.Page.ui.controls.get(IDField);

      if (isNumber(IDFieldValue ) == false)
       {
                executionObj.getEventArgs().preventDefault();
                alert("The ID must be a number");
                IDFieldObject.setFocus();
        }
    }
    else
    {
        // ID Field is null. Don't validate
    }
}

function isNumber(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}

Thursday, 16 January 2014

MVC 4: How do I download a list as a CSV?

I added a simple link in my view

@Html.ActionLink("Export Data", "ExportData")

and a simple method in my controller to take care of the download

public ActionResult ExportData()
{
return DownloadCSV();
}

public FileContentResult DownloadCSV()
{
string csv = string.Concat(from x in db.MyData
  select x.ID + ","
  + x.Name + "\n");

return File(new System.Text.UTF8Encoding().GetBytes(csv), "text/csv",  string.Format("Export.{0}.csv", DateTime.Now.ToString("yyyy-MM-dd_HHmmss")));
}

Sunday, 12 January 2014

MVC 4: How do I line-wrap my text in an editor?

The solution is to add an annotation to the field in the model class:

[DataType(DataType.MultilineText)]

Then, to display the item in the view, use Html.Raw.

@Html.Raw("<pre>"+ Html.Encode(@Model.MyField) + "</pre>"

Thursday, 9 January 2014

MVC 4: How do I generate a pdf file from a view?

I looked at several possible solutions (including itextsharp) but there were always issues rendering the CSS correctly.

Fortunately, I found the following gem in codeplex: http://pdfgenerator.codeplex.com/

I used the following code to generate the HTML from the view (sourced from here):

 public string RenderViewToString(Controller controller, string viewName, object viewData)
        {
            var renderedView = new StringBuilder();
            using (var responseWriter = new StringWriter(renderedView))
            {
                var fakeResponse = new HttpResponse(responseWriter);
                var fakeContext = new HttpContext(HttpContext.Current.Request, fakeResponse);
                var fakeControllerContext = new ControllerContext(new HttpContextWrapper(fakeContext), controller.ControllerContext.RouteData, controller.ControllerContext.Controller);

                var oldContext = HttpContext.Current;
                HttpContext.Current = fakeContext;

                using (var viewPage = new ViewPage())
                {
                    var html = new HtmlHelper(CreateViewContext(responseWriter, fakeControllerContext), viewPage);
                    html.RenderPartial(viewName, viewData);
                    HttpContext.Current = oldContext;
                }
            }

            return renderedView.ToString();
        }

and this to generate the byte array:

byte[] buffer = (new HtmlToPdfConverter()).GeneratePdf(htmlText);

and finally, this to generate the file:

 public class BinaryContentResult : ActionResult
    {
        private readonly string contentType;
        private readonly byte[] contentBytes;

        public BinaryContentResult(byte[] contentBytes, string contentType)
        {
            this.contentBytes = contentBytes;
            this.contentType = contentType;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            var response = context.HttpContext.Response;
            response.Clear();
            response.Cache.SetCacheability(HttpCacheability.Public);
            response.ContentType = this.contentType;

            using (var stream = new MemoryStream(this.contentBytes))
            {
                stream.WriteTo(response.OutputStream);
                stream.Flush();
            }
        }
    }