Posting data to an MVC controller with jQuery

The easiest way to post data from a view to a controller action is by adding a form and submit button and letting most of the hard stuff happen automatically.

Unfortunately this doesn’t really work in cases where data needs to be submitted by a javascript function, in these situations the best option I’ve found is to post a JSON object from the javascript function which is then automatically deserialized by the controller action.

In order to pass a HTML document through to the controller action I used the following.


<script type="text/javascript">
	var token = @Html.Raw(JsonConvert.SerializeObject(Model));
	var config = {
		uid: 'test1-clientside',
		container: 'bee-plugin-container',
		onSend: function (htmlFile) {
			$.ajax({
				type: 'POST',
				url: '@Url.Action("Send", "Template", new { TemplateId = templateDetail.TemplateId })',
				data: { 'html': JSON.stringify(htmlFile) },
				dataType: 'text'
			});
		}
	}

	BeePlugin.create(
		token,
		config,
		function (beePluginInstance) {
			$.ajax({
				url: 'https://rsrc.getbee.io/api/templates/m-bee',
				success: function () {
					beePluginInstance.start(@Html.Raw(templateDetail.Template.JsonBlob.DownloadTextAsync().Result));
				}
			});
		}
	);
</script

This takes a HTML document generated by the BeeFree plugin and pases it to the “Send” action in the “Template” controller. The “JSON.stringify” function is used on the HTML content to escape control characters as otherwise these would cause the passed JSON object to be invalid.

The controller expects a string argument called “html”, this needs to match the name of the string argument passed by the AJAX function or things won’t get mapped correctly and the “html” variable in the controller will be null.

More complicated JSON objects can also be passed through to the controller though care is needed in setting them up to ensure everything matches correctly to the expected model.


[HttpPost]
public IActionResult Send(string html)
{
	// Process html here...

	return View();
}

I also use this for posting editable table data back to the controller as this frequently seems to run into problems when relying on inbuilt methods to do this.


<script type="text/javascript">
	function postTable(data) {
		$.ajax({
			url: '@Url.Action("CreateTable", "Data", new { parentObjectId = Model.ObjectId })',
			type: 'POST',
			dataType: 'text',
			data: data,
			async: false
		});
	}
</script>
<script type="text/javascript">
	function createTableJson() {
		var rows = [];
		$('#TableTableBody > tr').each(function (i, n) {
			var $row = $(n);

			rows.push({
				ColumnName: $row.find('td:eq(0) input[type=text]').val(),
				DataType: $row.find('td:eq(1) :selected').text(),
				Size: $row.find('td:eq(2) input[type=number]').val(),
				PrimaryKey: $row.find('td:eq(3) input[type=checkbox]').prop('checked'),
				Nullable: $row.find('td:eq(4) input[type=checkbox]').prop('checked'),
				IsDeleted: $row.find('td:eq(5) input[type=checkbox]').prop('checked')
			})
		});

		var table = {
			TableName: $('#table_TableName').val(),
			Columns: rows
		};
		postTable('tableJson=' + JSON.stringify(table));
	}
</script>

One thing to note is that if you’re passing a field with HTML special characters in such as &, although the ajax call posts these successfully the MVC controller will truncate the input string as soon as it sees one so you need to use the javascript encodeURI function on any field that could contain HTML control characters.


Leave a Reply

Your email address will not be published. Required fields are marked *