if no route added form action is is not created why? - asp.net-mvc

I Have this in a view in an area
<form action='#Url.Action("/DeleteCoverage")'></form>
but this gives only the following html
<form action=''></form>
but the following code
#using (Html.BeginForm("DeleteCoverage", "Coverage", new { area = "Coverage" }, FormMethod.Post, new { id = "delform" }))
gives html
<form action="/Coverage/DeleteCoverage/af361feb-1818-430b-803c-e332a162b0e2" id="delform" method="post">
I get this HTML only if i add a route for this method. Other wise it just becomes action=""
Why i am not getting proper HTML if I don't add route?

You are incorrectly using the Url.Action helper. This helper has several overloads and expects you to pass action, controller, route values, ... Currently you are passing /DeleteCoverage which is invalid action name (action names cannot start with /).
So pick one of the overloads and use it correctly:
<form action="#Url.Action("DeleteCoverage", "Coverage", new { area = "Coverage" })"></form>
Oh and by the way you should probably use Html.BeginForm to generate your form tags instead of hardcoding them.

Related

MVC Core form tag helper that inherit the current view URL for its action attribute

With MVC5 (and older MVC frameworks), I was able to write my form without specifying the controller/action method:
#using (Html.BeginForm())
{
}
This way, I was able to reuse the form with different URL. If the form was called from the route "/books/2/edit", the HTML generated would be:
<form action="/books/2/edit"></form>
And if I call the form using the URL "/books/add", the HTML generated would be:
<form action="/books/add"></form>
How can I do the same with the tag helper syntax? I have tried all kind of syntaxes but it always generate an empty action attribute:
<form></form>
<form asp-route=""></form>
<form asp-controller="" asp-action=""></form>
Result:
<form></form>
<form action></form>
<form action></form>
When using HTML helpers, values that are not supplied explicitly default to the route values that are in the current request. That is the reason why you can specify BeginForm with no parameters.
When using tag helpers, this default logic no longer applies - the values must be provided explicitly. There are no defaults.
Option 1 - form tag
The simplest way to mimic what the HTML helper does with a form tag is:
<form action="#Url.RouteUrl(this.ViewContext.RouteData.Values)" method="post">
</form>
Option 2 - Html.BeginForm
Note that your current syntax is also still valid in ASP.NET Core MVC:
#using (Html.BeginForm())
{
}
But since you had to ask this question, I would say that it is absolutely not clear how the URL is being generated when using this syntax, which means you should probably change to using Url.RouteUrl to make it more readable despite being a bit more to write.
Option 3 - Tag Helper
Here is an example of how you could use a tag helper to achieve this, although it is a bit ugly.
There is a form tag helper attribute asp-all-route-values that allows you to pass all of the route values in a single parameter. However, according to asp-all-route-data must be IDictionary<string,object> or RouteValueDictionary, it is not possible to pass a RouteValueDictionary to this attribute, you would need to convert it to an IDictionary<string, string>. One way to do that is to build an extension method to make the conversion.
public static class RouteValueDictionaryExtensions
{
public static IDictionary<string, string> ToTagHelperValues(this RouteValueDictionary routeValueDictionary)
{
var result = new Dictionary<string, string>();
foreach (var kvp in routeValueDictionary)
{
result.Add(kvp.Key, kvp.Value as string);
}
return result;
}
}
You can then use a tag helper to generate the current URL as follows:
<form asp-all-route-data="#this.ViewContext.RouteData.Values.ToTagHelperValues()">
</form>
Option 4 - No action attribute
It is also possible to use a form tag with no action attribute. If you omit the action attribute, the default behavior in most (if not all) browsers is to use the current URL.
<form method="post">
</form>
WARNING: It is not standards compliant to use this option and technically the behavior of browsers do not have to default to the expected behavior of using the current URL if it is not supplied.
In the end, which method you use is a matter of preference.

how can I understand where this "submit" button/actionlink leads in ASP MVC 4?

I am new to ASP.NET MVC 4 and learning my way around an existing MVC 4 code base. I am trying to find the code that processes the the form corresponding to this submit button. I understand that the action link probably says how to process the "submit" button -- but I don't see any constructors that take three strings for an actionlink in the microsoft documentation.
I am confused because there is no action field in the input tag.
How do I find out what happens once the person hits submit?
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data", #class = "disableSubmit" }))
{
...
<div class="buttons">
<input type="submit" value="Upload" /> | #Html.ActionLink("Back to List", "Index", "Admin")
</div>
}
Update When I go to "view source" to see the raw HTML I see
<form action="/Lab/Upload" ...
So that means it goes to the lab/upload controller?
The Javascript for the disable submit looks like this:
// Disable submit button after click
$(function () {
$('.disableSubmit').submit(function () {
if ($(this).valid()) {
$('input[type="submit"]').attr('disabled', 'disabled');
}
});
});
If the submit button performs a regular form submit, then it will be inside of a <form> tag or #Html.BeginForm using block.
BeginForm will submit the form to the action that matches the name of the view, unless there is a parameter being passed that specifies the action name and/or controller name.
IF it is a form tag, then the action="something" attribute of the form tag will indicate the URL being submitted to, which is usually controllerName/ActionName` but could be different depending on what routing is setup.
The ActionLink you see is not related to the form or the submit, it is a regular link which is in effect a way for the user to go back to the previous page instead of submitting the form.
There is also the possibility that there is javascript attached to the submit button. That's harder to find unfortunately due to the many ways that javascript can be wired up to a button.
Edit: Based on your update, I would strongly suspect there's javascript that supports this form. I imagine the submit button is disabled until you meet some conditions that allow it to be displayed. Maybe permissions, maybe filling the form out completely, it's hard to say. Search the javascript for disableSubmit, as I suspect somewhere there is code that removes that class under certain conditions.
Edit 2: What is happening there is it disables the submit button after the first click so that you can't accidentally submit the for twice and cause problems with a duplicate submit(if this is Create form it avoids duplicate records). As far as I can tell there should be an action of the same name as the *.cshtml file that it submits to. Possibly with a [Post] or [HttpPost] attribute on the action.
Check whether the submit buttons in inside a form tag. If yes, what is the action attribute value of that ? That is the place the form will be submitted to.
You may see an HTML helper method called Html.Beginform in the view. This method render a form tag. You can go to the page and check the view source of the page to see what is the form tag looks like and what is the action method attribute value.
Ususally your controller will have an action method marked with HttpPost attribute to handle the form submit. Lets say your mark up is like this
<form action="User/EditUser">
<input type="text" name=Name" />
<input type="submit" />
</form>
Now in your UserController, there may be an action method like this
[HttpPost]
public ActionResult EditUser(SomeModelIfExist model)
{
// TO DO : save and redirect
}
the Html.ActionLink helper method renders an anchor tag. It has nothing to do with the form submit. So your action link helper will return the below markup
Back

Html Partial MVC passing a Model

I am trying to pass this Model in the Partial Method
#Html.Partial("_RefillModal",new Refill()
{
PatientId=Model.Id
})
Now in the _RefillModal, I am trying to Read the PatientId by doing Model.PatientId. However, I am not getting a Value.
I can get the Value of the ID by doing this
#Html.Partial("_RefillModal",new Refill(),new ViewDataDictionary(){{"PatientId",Model.Id}})
Here is what I am trying to do in the Partial View
#Html.Hidden("Refill.PatientId",Model.PatientId)
Here is the Html Markup that happens
<input id="PatientId" name="PatientId" type="hidden" value="">
However when I do #Modal.PatientId anywhere on the page I do get the Value
So it looks like, if I put anything inside the Form it gets Overriden. Is there a work around?
#using (Html.BeginForm())
{
//any custom input here gets overriden
}
It's hard to see where the issue is since you didn't post your Partial View but I'll offer a few suggestions. Make sure that you've declared the actual Model to be of type Refill in your _RefillModal.
#model Refill
The next step is to make sure that you're actually passing in a value in this line of code:
#Html.Partial("_RefillModal", new Refill()
{
/** Make sure that Model.Id actually
contains some value. */
PatientId = Model.Id
})

Using Custom paths or absolute URI with Html.BeginForm() [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Html.BeginForm() with an absolute URL?
How to put and absolute URI in the action attribute of the <form> tag generated by the Html.BeginForm() MVC3 Html helper. I am using MVC3 validation and do not want to lose it by writing my own Form tags.
I tried out both Html.BeginForm(new { action ="http://absolute.com"}) and Html.BeginForm(new { #action ="http://absolute.com"}) and the rendered html was <form action="/Pro/Contact/http%3a/absolute.com/">. As you can see it is being appended instead of replaced.
BeginForm method with single parameter is used to generate a relative path from routedata that is provided within parameter variable. Which means, that you are setting URI parameter with name action and giving it and value http://absolute.com, therefor value is going to be encoded.
What you want to use is overload where it asks you for htmlAttributes.
This will not encode value for action attribute:
#using (Html.BeginForm(
null, null, FormMethod.Post,
new {#action="http://absolute.com/submit/example"}
)){}
// the result is:
<form action="http://absolute.com/submit/example" method="post">
</form>
UPDATE: method show below will not utilize JavaScript client-side validation.
since, you don't really need the helper to figure out the path of the form. You can use the html and set action of the form manually.
Validation will still work, if you are using helpers for the input fields.
<form action="http://absolute.com/submit/example" method="post">
#Html.LabelFor(model => model.Example)
#Html.ValidationMessageFor(model => model.Example, "*")
#Html.TextAreaFor(model => model.Example, 8, 60, null)
</form>
One way is..we can use RedirectResult("http://absolute.com"); in the controller action method.
If you are redirecting from your controller (or action filter, etc.) you can use the RedirectResult as your ActionResult type.

asp.net mvc actionlink shows address in FF, cannot get button to function

I'm currently in the process of learning ASP MVC and am running into a few issues.
First, when I use
<%=Http.ActionLink("Add / Modify", "AddModify" %>
it will show as Add / Modify (/Home/AddModify) in Firefox and Add / Modify in IE. It is doing that to all links in FF and none in IE. Anyone know what reasoning is for that?
Edit: What is displayed in the browser (FF in this case) is "Add / Modify (/Home/AddModify)" while in IE shows just "Add / Modify".
Here is a screenshot of what I see on my site in FireFox: http://img6.imageshack.us/img6/1331/19748435.png
You can see how it shows the text and the appropriate link afterwards (only populated in Database with /).
Also, I am trying to have buttons (both standard and image) on my site which will link to new pages, while also performing hidden tasks (saving data, etc...). Anyways, When I do the following:
<form method="post" action="/Home">
<input type="submit" value="AddModify">
</form>
and the controller has a simple
[ActionVerbs(HttpVerbs.Post)]
public ActionResult AddModify()
{
return View();
}
And I still cannot get that function to call, yet when I do http://localhost:port/Home/AddModify, the function calls and I can get to that page. I am doing it this way because there may be code that has to execute before redirecting to that page, rather than just a direct link to that page. I have tried with and without the ActionVerbs line, I have tried this form of the Html Form:
<% using (Html.BeginForm()) { %> ... <%}%>
and still nothing. I have also tried no form and still nothing, but here's something that may affect this...I am using a master page with everything inside a content place holder inside a form that uses runat="server". Would that matter? So its Master Page -> form (masterform runat server) -> ContentPlaceHolder -> form (for postback and action) -> submit button. Any help would be greatly appreciated.
If I am thinking correctly, your form action should be calling the name of the action method:
<form method="post" action="/Home/AddModify">
<input type="submit" value="AddModify">
</form>
The ActionLink would be the same way.
Otherwise you will need to modify your routes to go to that action method by default.
Let's do this in two parts
1 I think your ActionLink should be:
<%=Http.ActionLink("Add / Modify", "AddModify", "Home")
...to force routes.
First parameter: text shown
Second parameter: action name
Third parameter: controller name
2 Change your submit button to: (I assume we're currently looking at your "index" action from your "Home" controller)
<form method="post" action="/Home">
<input type="submit" value="AddModify" name="ModifyBtn" >
</form>
Then in your Home controller:
edit:
//GET
public ActionResult Index()
{
return View();
}
/edit
[ActionVerbs(HttpVerbs.Post)]
public ActionResult Index(FormCollection form, string ModifyBtn, string OtherBtn)
{
if (ModifyBtn!=null)
{
//do stuff
return RedirectToAction("AddModify");
}
if (OtherBtn!=null)
{
//do stuff
return RedirectToAction("OtherAction");
}
return View();
}
edit:
I think you're trying to submit directly to another Action. The best way is to handle the POST method inside your code then redirect to another action. That way, you can use
<% using (Html.BeginForm()) { %>
without trouble.
<form method="post" action="/Home">
Will create a form with a href of /Home, this will only call the AddModify action if the AddModify action is default on that route.

Resources