Read htmlAttribute in controller - asp.net-mvc

I have Ajax.ActionLink with htmlAttribute param
<%= Ajax.ActionLink("cool", "ViewCategory", new { id = elem.ID }, new AjaxOptions { UpdateTargetId = "score_" + elem.ID.ToString() }, new { myAttr = 123 } )%>
How can I read this attribute in controller method?

You can't.
All the htmlAttribute param does is instruct the generation of additional attributes to be added to the anchor html with it is sent to the client. These attributes are not included in the request when the anchor is clicked.
Place the attribute along side the id new {id = elem.ID, UpdateTargetID = ...} this should be included in the URL.

Related

ASP Route Data attribute in HTML Actionlink

I have a href attribute using anchor tag helper asp-all-route-data. I want to change this to use HTML.ActionLink that has a onclick popup message but not sure how to do it.
I have tried this so far:
#Html.ActionLink("Set as Draft", "SetAsDraft", "Item", new {
FromRouteAttribute = "setAsDraftParams" },
new { onclick = "return
confirm('Are sure you want to set this Item as a draft?');" })
Current a href:
<a asp-area="Admin" title="Set as Draft DOR" asp-controller="Dor" asp-
action="SetAsDraft" asp-all-route-data="setAsDraftParams">Set as Draft
DOR</a>
Variable set in the View:
var setAsDraftParams = new Dictionary<string, string>
{
{ "id", Model.DraftToView.ItemId.ToString() },
{ "returnViewName",
nameof(Web.Areas.Admin.Controllers.ItemController.Index)
}
};
I expect the HTML.ActionLink to return to the viewname set in the setASDraftParams variable
Since you are using dictionary, you need to use the right key to get the value. DictionaryVariable[key]
Try with:
#Html.ActionLink("AQUI", "Index", "Home", new { FromRouteAttribute = setAsDraftParams["returnViewName"] },
new { onclick = "return confirm('Are sure you want to set this Item as a draft?');" })

Correctly using quote marks in MVC view Razor

I am having some difficulties using quote marks in ASP.Net Razer view as I keep ending up with them replaced with '
If I for example type:
#{string test = "String 'with' quotes"}
#test
I end up with:
String 'with' quotes
In the above example this is desirable.
However, take this second example:
#{string myJSFunction = myJSFunction('myString')"}
#myJSFunction
I end up with:
myJSFunction('myString')
Which results in a broken javascript function.
I have tried excaping the quote marks with \, but they don't seem to be having any effect.
Here is the actual problem I am faced with:
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = #myJSFunction
}))
Any advice?
The # operator always HTML-encodes strings. If you want the raw string value, use #Html.Raw(myJSFunction).
In razor, # will encode and render. Try Html.Raw method. This method returns markup that is not HTML encoded.
#Html.Raw(myJSFunction)
So if you want to execute the function in a script block, you can do it like
#{string myJSFunction = "alert('Rise and Shine')";}
<script type="text/javascript">
#Html.Raw(myJSFunction)
</script>
The solution to your issue is already mentioned (Html.Raw()) but I'm not sure why you're using # in your code sample given. From the looks of it you're already in code block when you try to assign it, so why use the razor.
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = #myJSFunction
}))
should be
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = myJSFunction
}))
# is what tells the StreamWriter for the page to write the result to the response, and as such is intended to be injected into the page after HtmlEncoding. Using Html.Raw bypasses the Html encoding aspect but in your case you're not writing it the page directly yourself, you're letting Html.BeginForm handle that, so you don't need the # in the assignment of your OnComplete function.
UPDATE: Ok, another thing I forgot to mention is that the methods passed to the AjaxOptions are Javascript functions only, no parameters by the looks of it. Parameters are passed in automatically by the Unobtrusive scripts that handle all the wiring. So your form should look like this...
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = "myJSFunction"
}))
And it will handle the rest. If you need to pass additional parameters in the myJSFunction function, you're probably going to have to expose them via other means. Either as a javascript variable or by associating it with some other element and access it using $("elementselector").data("dataAttributeName") (this is my preferred and suggested method). One of the common requested modifications made to the unobtrusive ajax JavaScript libraries (I wish Microsoft would just adopt this change and be done with it) is to set the context of this to the element that triggered the ajax event. So for in this case it would make this equal to the form element. With all this in mind, here's my recommendation.
First:
Modify your Unobtrusive Ajax script file so that the source element gets assigned to the this keyword so that's it's available in your JavaScript handling the unobtrusive events.
This question outlines what it involves (one line added to the file)
Second:
Add your string to one of the data attributes on your form
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new {id = ViewBag.InputResourceID},
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = "myJSFunction"
},
new { data_parameter_name = "myString" }))
Third:
Access your parameter from inside of the javascriptfunction handling your event.
<script>
function myJSFunction(data, textStatus, jqXHR)
{
//data, textStatus and jqXHR are set for you by the unobtrusive ajax script file automatically, feel free to use them
var parameter = $(this).data("parameterName");
alert(parameter);
}
</script>

How can I put data attributes within an Ajax.BeginForm?

Because I am using Knockout in my view, I have set my form tag accordingly;
<form class="employeeListEditor" data-bind="submit: save">
However when I click the submit button, I want to do a partial page refresh. So how do I set the data-bind attribute in the Ajax.BeginForm?
This syntax does not work;
<% using (Ajax.BeginForm("GetCalendar", new AjaxOptions { UpdateTargetId = "siteRows" }, new { data-bind="submit: save", class="employeeListEditor" }))
{%>
You need to use unserscore (_) in your attribute name and the Ajax.BeginForm helper (in fact all the HTML helpers replaces unserscore with dashes in the given htmlAttributes object parameters) will be automatically replace it with a dash (-)
new { data_bind="submit: save", #class="employeeListEditor" }
And you need use an Ajax.BeginForm overload which accepts htmlAttributes like this one:
<% using (Ajax.BeginForm(
"GetCalendar", // actionName
null, // routeValues
new AjaxOptions { UpdateTargetId = "siteRows" }, // ajaxOptions
new { data_bind="submit: save", #class="employeeListEditor" } // htmlAttributes
))
{%>

URL parameters not appearing in ASP.MVC when using variant of Html.BeginForm

I've got a view that defines a form as
<% using (Html.BeginForm( "Update", "CcisCase", FormMethod.Post, new { id = "ccisEditForm" } ))
with a submit button:
In the RegisterRoutes method (in the HttpApplication-derived class in global.asax.cs), I've got:
routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" );
routes.MapRoute(
"CcisCase",
"CcisCase/{action}/{cmDatabaseId}/{caseId}",
new { Controller = "CcisCase", Action = "CcisCaseEdit", caseId = "" } );
The url generated by MVC ends with "/Update" but there are no parameters. What am I doing wrong?
Thanks,
Bob
What parameters are you expecting to see? A post does not append parameters to the querystring, a FormMethod.Get would. And, that overload with the id is the collection of HTML attributes to render for the tag (which I'm assuming you knew, but just in case).
HTH.
Your route contains a parameter {caseId} but your BeginForm only defines an id value.
new {id = "cssEditForm"}
You need something like this to include the caseId value
using (Html.BeginForm( "Update", "CcisCase", FormMethod.Post, new { caseId = 1, id = "ccisEditForm" }
If your action isn't using the id="ccisEditForm" value then you can remove that for less code clutter.
I figured out what my problem was. I had to pass the existing route data as follows:
using (Html.BeginForm( "Update", "CcisCase", ViewContext.RouteData.Values, FormMethod.Post, new Dictionary<string, object> { { "id", "ccisEditForm" } } ))

Append row to <TABLE> using Ajax.BeginForm()

I have an HTML <TABLE> displaying a list of items in the rows of the table. To add a new item to the list of items I have a form which submits the data to my controller via AJAX using Ajax.BeginForm. Once the action on the controller has finished it returns a partial view containing the markup for a new row to append to my table (eg. <TR><TD>.......</TD></TR>). My question is how do I add the new row my existing table?
I have create an at the top of the as my header with the id "userrightsgridheader" and specified my Ajax.BeginForm as follows:
<% using (Ajax.BeginForm(
"CreateUserRight",
new { workstationId = Model.Id },
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "userrightsgridheader"
}
))
{ %>
The problem is that this does not work. Does anyone have any ideas on how to achieve this?
Thanks!
You can add the following AjaxOption, this executes 'jsfunction' when the Ajax functionality executed successfully:
new AjaxOptions { OnSuccess = "jsfunction" };
You can add the tablerow in the jsfunction.
update
you can define jsfunction as follows:
function jsfunction(ajaxContext) {
//ajaxContext contains the responseText
}
AjaxContext is defined as follows:
AjaxContext ajaxContext = new AjaxContext(request, updateElement, loadingElement, ajaxOptions.InsertionMode);

Resources