Attribute routing number of parameters with 404 not found - asp.net-mvc

I use AttributeRouting to set specific route for my ActionResult. I got an 404 page not found when I have this configuration:
[GET("Tender/SubmitBid/{id}/{bidId}")]
public ActionResult SubmitBid(string id, string bidId)
{
...
return View(model);
}
#using ("SubmitBid", "Tender", new { id = Model.TenderId, bidId = Model.BidId }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
...
<button type="submit">Save</button>
}
// 404 not found
[HttpPost]
public ActionResult SubmitBid(BidViewModel model)
{
...
}
I installed a url sniffer to see the url trigger the 404 page not found and I got this: http.../Tender/SubmitBid/1/0
It supposed to be working... but I have to remove the latest parameters to reach the ActionResult and I don't know why.
Thank you for your help,
Karine
Edit
If I remove the attribute [GET("Tender/SubmitBid/{id}/{bidId}")] the page is accessible for the POST request. But the url is like http...//Tender/SubmitBid/1?bidId=0

You should not need the query string parameters since they exist in the BidViewModel you post. The point of a POST request is that you don't have query string parameters.
I think you have to use this overload of the Html.BeginForm method:
#using (Html.BeginForm("SubmitBid", "Tender", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.HiddenFor(model => model.Id)
#Html.HiddenFor(model => model.BidId)
// Other properties..
<button type="submit">Save</button>
}
Now it will post to http:localhost/Tender/SubmitBid with the properties of BidViewModel as post values, which contain Id and BidId. The signature of the POST action can stay the same:
[HttpPost]
public ActionResult SubmitBid(BidViewModel model)
{
string id = model.Id;
string bidId = model.bidId;
// ...
}
It's also possible that AttributeRouting causes this issue. Can you try this with native ASP.NET MVC routing? You could use this specific route for submitting bids:
routes.MapRoute(
name: "SubmitBid",
url: "Tender/SubmitBid/{id}/{bidId}/",
defaults: new
{
controller = "Tender",
action = "SubmitBid",
id = UrlParameter.Optional,
bidId = UrlParameter.Optional
});

Related

Why won't my ASP.NET MVC Form post back to my controller

I am certain this question has been asked before and this is NOT my only form in this project, but for some reason I cannot get my Form.Post to work when the "submit" button is pressed on this particular form. Any assistance will be greatly appreciated.
Note: I checked the model Contract and there are no [Required Fields]. Also, I did get it to post back using $.ajax POST {}, which I may need to resort to
Here is the frame for the Form
#using (Html.BeginForm("Add_Contract", "Contract", FormMethod.Post, new { #id = "contractForm", role="form" }))
{
<div class=content>
... Content goes here
</div>
<input type="submit" value="Save Contract" />
}
Here is my Controller:
// Add a Contract
public ActionResult Add_Contract()
{
var returned = new Contract();
return View(returned);
}
[HttpPost]
public ActionResult Add_Contract(Contract data)
{
return View(data);
}
Here is my route.config
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
}
So, as I dug deeper into this issue, I figured out the issue was that I did not have any front-end validation on the data I was inputting yet, and even though I did not have any required fields in the model, I was inputting characters in a field that was set up as an integer. I discovered the issue when I created a dummy view and let the system create the scaffolding and when I tried to enter the same character data in that int field, an error popped up stating that the field must be integer. Once I added an integer in the text box, the post worked. Thanks for anyone who reviewed this post.

BeginForm Always calling Index when submitting

I'm using MVC BeginForm to submit form data to my ActionMethod in Controller. The problem is that when every I click on submit button it keeps calling Index method instead of Actual method defined in BeginForm.
Here is my View
#model HRMS.DBModel.department
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm("save", "Department", FormMethod.Post))
{
#Html.TextAreaFor(model => model.Name, new { #class = "form-control" })
<input type="submit" value="submit" />
}
and here is the Department Controller
public class DepartmentController : Controller
{
// GET: Department
public ActionResult Index()
{
return View();
}
[HttpPost]
[AllowAnonymous]
public ActionResult save()
{
return View();
}
}
and RouteConfig.cs
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Location", action = "Index", id = UrlParameter.Optional }
);
}
I searched on google even found solutions but still my problem is still there.
Any help will be appreciated.
Thanks
Issue Resolved there was a form tag inside my Master page due to which it was calling Index Method, I removed that form tag and now its working fine

MVC ActionLink 404 Error

Hi Guys' I am getting HTTP 404 in my MVC project and I am not sure where it is coming from.
On the _NavBar I have an ActionLink control that is calling to CreateSite
<li>
#Html.ActionLink("Create Location","CreateSite", "SiteRegistration", routeValues: null, htmlAttributes: new { id = "registerLink" })
</li>
I have an Controller name SiteRegistrationController
public class SiteRegistrationController : Controller
{
SiteInfoManager manager = new SiteInfoManager();
//
// GET: /SiteRegistration/
public ActionResult UserSiteResult()
{
return View();
}
}
The views I have are Folder SiteRegistration and CreateSite.cshtml.
The Error is coming from the SiteInfoManager line in the Controller.
Any help would be great.
You need to update your #Html.ActionLink to:
#Html.ActionLink("Create Location","UserSiteResult", "SiteRegistration", new { id = "registerLink" }, null)
And update your Controller:
public ActionResult UserSiteResult(string id)
{
// you can use id now, as it will be regirsterLink
return View();
}

Upload a File with MVC HttpPostedFileBase == null

My Controller
public ActionResult Edit(int id)
{
return this.EditDefault(id);
}
[HttpPost]
public ActionResult Edit(int id, Models.Company model)
{
return this.EditDefault(id, model);
}
My Model
pulbic class Company
{
... Many other Propeties
public HttpPostedFileBase File { get; set; }
}
My View
#using (Html.BeginForm(new { enctype = "multipart/form-data" }))
{
... Many other Properties
#Html.TextBoxFor(m => m.File, new
{
type = "file", style = "display:none"
})
... Submit
}
So my problem now is when I submit the page the infos in the model are right, but the File Property is still null.
I found some solutions where people added HttpPostedFileBase as parmeter in the controller (tried it doesn't work too), but I would like to avoid that anyway because the model and the controller are generated with T4. So has someone an idea why the File Property is always null?
Would be really happy about some help :)
Update: Found the solution thx to Matt Tabor.
For me the solution looks like this because I use a shared Edit page.
The javascript part is to hide the actual file upload element and use a span instead, because the file upload isn't style able.
//Shared Part
#{
RouteData routeData = this.ViewContext.RouteData;
string currentController = routeData.GetRequiredString("controller");
}
#using (Html.BeginForm("Edit", currentController, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
//Special Part
... Many other Properties
//File upload which is hidden
#Html.TextBoxFor(m => m.File, new
{
type = "file", style = "display:none"
})
//Span which forwards the clicks to the file upload
<span id="fake-file-name">Kein Bild</span>
... Submit
}
<script type="text/javascript">
$(function () {
//forward the click from the span to the file upload
$("#fake-file-name").click(function () {
$("#File").click();
});
//display the chosen file name to the user with the styled span
$("#File").bind('change', function () {
//we don't want the C:\fakepath to show
var displayFileName = this.value.replace("C:\\fakepath\\", "");
$("#fake-file-name").text(displayFileName);
});
});
</script>
you need to specify your form method as post
#using (Html.BeginForm("Edit", "CONTROLLER", null,FormMethod.Post, new { enctype = "multipart/form-data" }))
#Html.TextBoxFor(m => m.File, new
{
type = "file", style = "display:none"
})
Instead have a Input type file as shown below -
<input type="file" name="File" id="File"/>
PS: Name should match to Model property name.
UPDATE
Remove display:none from your code and it should work fine.

ReturnUrl QueryString always is null in MVC 4

i have a action method for login with get method:
public virtual ActionResult LogIn()
{
return View();
}
and an action method for Post method which post in Ajax call with Ajax.BeginForm(),like:
[HttpPost]
[AjaxOnly]
[ValidateAntiForgeryToken]
public virtual ActionResult LogIn(LogInViewModel loginInfo, string returnUrl)
{
...
}
But returnUrl always is null!!!
i use MVC 4.
what is cause of this problem?
You have to send the returnUrl back to the server. For example your login form should take returnUrl as a parameter:
#using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
....
<input type="submit" value="Log in" />
}
which was previously saved at the server side in your login action, invoked as a result of usage AuthorizeAttribute with ReturnUrl passed in the query string:
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
Not sure what your view looks like, but if you have something like:
#using (Html.BeginForm())
{
}
...then returnUrl should have a populated value, that's if it came from another url.
In my scenario it was always null, and I am assuming it was probably the same way that you did it. I had it like this:
#using (Html.BeginForm("LogOn", "Account", FormMethod.Post, new { role = "form" }))
{
}
All that I did was change it to look like this:
#using (Html.BeginForm("LogOn", "Account", new { returnUrl = Request.QueryString["ReturnUrl"] }, FormMethod.Post, new { role = "form" }))
{
}
returnUrl now has a value that I can work with.
in continue for Completion good answer of #Jaroslaw Waliszko,cause of this problem is:
because we use a ajax request for submit form,unobtrusive ajax use
$("form").serialize();
for this form and at this case(use ajax) ReturnUrl(and any other parameter) not send to server and only form input element send to server,So MVC Auto ModelBinding not bind ReturnUrl and we must use #Jaroslaw Waliszko solution at this state.
serialize
Encode a set of form elements as a string for submission.

Resources