I don't have a view called Test. But, there's a method in the Home controller called Test.
Everything works fine, the Test method gets executed and redirected to Index view as given in the code. However, in the browser the URL is ../Home/Test and not ../Home/Index. I don't have a View called Test so why is this getting displayed ? I don't want this URL to be displayed in the browser. How can i solve this ?
View:
#using (Html.BeginForm("Test", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" />
..// Other code
}
C#
public ActionResult Test(HttpPostedFileBase f)
{
var m = new HomeModel();
..// Other code goes here
return View("../Home/Index", m); // Will be returning the Index View
}
In URL
"../Home/Test"
Test is action thus it is working fine.
If you don't want this URL to be displayed, renamed the Action "Test" to "Index" and also update its references
and use (optional)
return View("Index", m)
If you are using the standard setting for MVC, it is not the View, but The Method, that is displayed in the browser. The method then by default returns the View (but that is optional).
So what you need to do is rename you Test Method to Index and place [HttpPost] on top of it.
[HttpPost]
public ActionResult Index(HttpPostedFileBase f)
{
var m = new HomeModel();
..// Other code goes here
return View(m);
}
return View("../Home/Index", m);
This will not redirect you to Index; it will simply display your Index view. If you want browser to automatically change your URL from /Test to /Index you have to instead do this:
return RedirectToAction("Index");
Try this:
public ActionResult Test(HttpPostedFileBase f)
{
var m = new HomeModel();
..// Other code goes here
return RedirectToAction("Index");
}
Related
i am saving data on click button but view when load first time entering to overload method ?
my view code is like,
#using (Html.BeginForm("ManageQuestion", "Questions", FormMethod.Post))
{
<input type="submit" value="Save" />
}
and my Controller is like,
public ActionResult ManageQuestion()
{
//List<SelectListItem> QuestionType = Survey();
//return View(QuestionType);
return View();
}
[HttpPost]
public ActionResult ManageQuestion(Question Objquest)
{
if (ModelState.IsValid)
{
SurveyAppEntities ObjEntity = new SurveyAppEntities();
string strDDLValue = Request.Form["DDlDemo"].ToString();
Objquest.QuestionType = strDDLValue;
ObjEntity.Questions.Add(Objquest);
ObjEntity.SaveChanges();
ViewData["error"] = "Question Saved successfully";
if (Objquest.ID > 0)
{
// ViewBag.Success = "Inserted";
}
ModelState.Clear();
}
return View();
}
}
I am thinking that it must call overload ManageQuestion method on button click but when view load first time it is entering in overload methos resulting in error.
I got one example from net having same scenario but overload method is not calling there on first form load ?
Hopes for your suggestion
Thanks
I have created a page that takes in a string that will search a list of vendors. My goal is to output them to a grid list on an HTML page. Oddly enough, the first page loads, and I can break point the code until the return view of the actual list page. However, it never actually loads. It is even more frustrating because if I don't pass the model to the grid page, it gives me the typical "You can't use a null model", but then it still doesn't load the new page. I have tried several versions. The most current is below.
[HttpPost]
public ActionResult Search(String searchString)
{
this.searchString = searchString;
List<VendorInvoice> v = VendorSearches.publicSearch(searchString);
test = v;
ViewData.Model = v;
TempData.Add("test",v);
return RedirectToAction("Search");
}
[HttpGet]
public ActionResult Search()
{
List<VendorInvoice> v = (List<VendorInvoice>)TempData["test"];
return View("Search",v);
}
So if I take the v out, then I get the error about not passing the model. If it is there, then nothing will happen. The new page won't load.
In your HttpPost search action method, you are setting the result data to show in TempData and doing calling the RedirectToAction method.
RedirectToAction returns an HTTP 302 response to the browser, which causes the browser to make a GET request to the specified action. That means, it will be totally new request coming to your search GET action again. Since Http is stateles, it does not have any idea about what you did in your previous request. The data stored in TempData won't be available to this request.
What you should be doing is, similar to your GET action method, simply
return the result to the view.
[HttpPost]
public ActionResult Search(String searchString)
{
this.searchString = searchString;
List<VendorInvoice> v = VendorSearches.publicSearch(searchString);
return View("Search",v);
}
That should fix your problem. But as Stephen Muecke mentioned, you can keep just your GET action method for your Initial view and search result view
public ActionResult Search(String searchString="")
{
List<VendorInvoice> v = new List<VendorInvoice>();
v = VendorSearches.publicSearch(searchString);
return View("Search",v);
}
And your view
#model List<VendorInvoice>
#using(Html.BeginForm("Search","YourControllerName",FormMethod.GET)
{
<input type="text" name="searchString" />
<input type="submit" />
}
<h2>Results</h2>
#foreach(var item in Model)
{
<p> #item.SomePropertyNameOfYourVendorInvoiceHere </p>
}
I want to return a JSON result. To do this I have a controller method as follows that is called from a Ajax.BeginForm on the View:
#using (Ajax.BeginForm("Update", new AjaxOptions { OnSuccess = "MySuccessMethod()" }))
{
<!-- some form stuff -->
<input type="submit" value="Submit"/>
}
This is the controller that handles it:
[HttpPost]
public JsonResult Update(FormCollection fc)
{
// Process form stuff
return Json (new {success = true });
}
What I want is to process the success response with MySuccessMethod. What I see is that the view on submit goes to the correct controller method above, which then redirects the page to the URL /Home/Update with the following string in the screen:
{"success": true }
Not sure if it is relevant but I am using Mono.
How can I make the framework not switch pages to /Home/Update nor display the JSON string on the view and just process the JSON in the back?
For your first question, check the following:
1) Make sure you have Microsoft.jQuery.Unobtrusive.Ajax included and referenced
2) OnSuccess = "MySuccessMethod()" should be OnSuccess = "MySuccessMethod" (where MySuccessMethod is a JavaScript method, not a C# one)
For your second question, you could have your method return ActionResult instead of JsonResult (see here for more information). JsonResult is a type of ActionResult, which means that updating your action to return ActionResult will allow your method to return multiple types of ActionResult depending on the scenario:
[HttpPost]
public ActionResult SomeThing(int randomParam)
{
if (randomParam == 0)
{
return Json("Zero!");
}
else if (randomParam == 1)
{
return View("Not zero!");
}
else
{
return HttpNotFound("Error: I can only find zeroes and ones");
}
}
As a general rule of thumb (although sometimes rules are meant to be broken), having your action return one type (like your example, JsonResult instead of ActionResult) makes your action less error-prone as, for example, Visual Studio will let you know if you accidentally try to return another type of result - use ActionResult when your action returns more than one type of result.
I'm currently having some problems with the following codesnippets which seems almost identical to me, but behaves differently.
These snippets are from two different projects I've been working on, and they are built the same way but only one of them works correctly.
These are the Forms where I enter the controllers:
Form 1, inside a twitter bootstrap dropdown menu, located in the _Layout file:
#using (Html.BeginForm("EditProfile", "ProfilePage", FormMethod.Post))
{
<li>
<button type="submit" class="dropdownButton">Redigera Profil</button>
</li>
}
Form 2, tried different locations but right now it's in a table in a Block view:
<td>
#using (Html.BeginForm("EditProfile", "ProfilePage", FormMethod.Post))
{
<button type="submit">Redigera profil</button>
}
</td>
Both seems pretty identical, right?
Now here are the controllers
Controller 1:
public ActionResult EditProfile(ProfilePage currentPage)
{
var model = new ProfilePageViewModel(currentPage);
model.CurrentUser = ConnectionHelper.GetUserInformationByEmail(User.Identity.Name);
return View("EditProfile", model);
}
Controller 2:
public ActionResult EditProfile(ProfilePage currentPage)
{
ProfilePageViewModel model = new ProfilePageViewModel(currentPage);
model.currentUser = ConnectionHelper.GetCurrentUserByEmail(User.Identity.Name);
return View("EditProfile", model);
}
Also pretty much identical.
I've added the same routing in both projects:
protected override void RegisterRoutes(RouteCollection routes)
{
base.RegisterRoutes(routes);
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = "" });
}
Now here's the problem:
Form 1 and controller 1 works perfectly and recieves the ProfilePage currentPage without any problems, but form 2 and controller 2 doesn't work and gets null value.
As I stated earlier Form 1 is posted on the _Layout page and Form 2 is posted from a Block which is rendered within an mvc #section. I don't think this is the problem because I've tried to access the controller from different parts of the page, but it's not working anywhere - but in the other project it's working everywhere, which is driving me insane.
Does anyone have any idea why it is like this? I've stepped through both of them while debugging but the only difference is that one works and the other doesn't.
Thanks in advance
deSex
EDIT :
Here I render a section called "content", where almost everything will be rendered.
<div id="content">
#RenderBody()
#RenderSection("content", false)
</div>
My startpage has a ContentArea for blocks, rendered within this section:
#model Intranet.Models.ViewModels.StartPageViewModel
#section content{
#if (User.Identity.IsAuthenticated)
{
<div class="contentArea">
#Html.PropertyFor(x => x.MainContentArea)
</div>
}
}
And here is the controller that inherits from BlockController:
public class ProfileBlockController : BlockController<ProfileBlock>
{
public override ActionResult Index(ProfileBlock currentBlock)
{
ProfileBlockViewModel model;
if (currentBlock != null)
{
model = new ProfileBlockViewModel(currentBlock);
}
else
{
model = (ProfileBlockViewModel)Session["model"];
}
model.CurrentUser = ConnectionHelper.GetCurrentUserByEmail(User.Identity.Name);
var availableStatuses = ConnectionHelper.GetAllOfficeStatuses();
availableStatuses.Remove(model.CurrentUser.OfficeStatus);
model.AvailableStatusChanges = availableStatuses;
Session["model"] = model;
return PartialView(model);
}
}
The "currentPage" route value (i.e. parameter) will only be set by EPiServer's page route. It will always be null in a block controller.
However, you can get the page of the current request in a block controller with:
PageRouteHelper.Page
If the block is being rendered as part of a request for a profile page, you'll be able to get that profile page through PageRouteHelper.
I have this problem:
I go to a page such as:
/Auction/Details/37
and this calls this action method:
public ActionResult Details(int id)
A particular line in this method is:
return View("DetailsLub", auction);
This view contains this line:
#Html.Action("BidOnAuction", new { auctionId = Model.Id })
Which calls this action method:
public PartialViewResult BidOnAuction(int auctionId)
So far so good?
Now, I have a form in the BidOnAuction view, whcih has a button. When I click on this button, this action method is invloked:
[HttpPost]
public ActionResult BidOnAuction(BidOnAuctionViewModel model)
This action method has a catch statement with the following lines:
ModelState.AddModelError(string.Empty, operation + #" Failure: " + message);
return RedirectToAction("Details", new { id = model.AuctionId });
Now, both the DetailsLUB view and the BidOnAction view contain this line:
#Html.ValidationSummary(true)
But, the issue is that nothing ever gets printed to the screen. What am I doing wrong?
InOrder to get the validation Message on the page you need to return view with Model, as model has the Model State within it, something like this:
return View(Model);
This will return the model BidOnAuction with Validation Summary.
This line of code
return RedirectToAction("Details", new { id = model.AuctionId });
Returns instance of RedirectResult class. That is generally used for redirections and does not render view. If you want to render child action into parent view using #Html.Action, you need to return view from that child action, not RedirectResult. And that RedirectResult will not work even when there's no child action. Returning RedirectResult causes browser to issue fresh, all new request to that action. And model state is lost anyways. You should do something like
try
{
//some actions
return RedirectResult("Details", new { id = model.AuctionId });
}
catch
{
ModelState.AddModelError(string.Empty, operation + #" Failure: " + message);
return View("Details", new { id = model.AuctionId });
}
You can't redirect to a new action and expect the modelstate to be there.
If the modelState is invalid just return (with View(model))
else
redirect to details.
If you need the error information in the details view you will have add it to TempData or pass it in as an optional parameter.