A Form is posted to a SurfaceController 'Submit' action. After saving to the database, it redirects to another action 'LeadContact', in the same controller (using RedirectToAction()), passing in 'Id' as a paramter. The model is then populated and passed to the 'LeadContact' view.
Not sure if I'm doing this correctly, but when 'LeadContact' renders in the browser, the URL shows as
http://localhost:50656/umbraco/Surface/HealthInsurance/LeadContact?leadOptionId=70`
while I'm expecting it to be
http://localhost:50656/HealthInsurance/LeadContact?leadOptionId=70
In short it adds /umbraco/SurfaceContact' into url.
Can you please advise how I can correct it and what I'm doing wrong ?
public ActionResult Submit(FormCollection form)
{
//Some logic and later redirect to another action 'LeadContact'
return RedirectToAction("LeadContact", new { leadOptionId = _id});
}
public ActionResult LeadContact(int leadOptionId)
{
MyViewModel model = new MyViewModel();
//Lines of code to populate data into model
return View("LeadContact", model);
}
Thanks for your help and sharing.
Check your project properties, under Web you most likely have a virtual path specified.
Related
Afternoon Folks,
I have a question in reference to how to redirect to another model within my mvc project.
I have a controller with CRUD operations, and i have a [HttpPost] action on Create. The system saves the data to the database as required but instead of me sending the user back to the "Index" page i want to sent them to another model.
I know how to use the redirect option...
// POST: CarerDetailsNew/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CarerViewModel carerViewModel)
{
if (ModelState.IsValid)
{
db.CarerDetails.Add(carerViewModel.carer);
db.SaveChanges();
return RedirectToAction("Edit", carerViewModel.carer);
//return RedirectToRoute("ClientRecordsController");
}
return View(carerViewModel);
}
However i have read that i may be able to use the "RedirectToRoute" option to get back to another model.
The model that i am in is my "Carer" model but i want to get back to my "Client" model and specifically the "Edit".
I have tried to replace my RedirectToAction to one of the following but this fails to see the "Client" model.
return RedirectToRoute("Edit", clientViewRecord.client);
Or
return RedirectToRoute(ClientRecordsController, "Edit", clientViewRecord.client);
Any suggestions are more than welcome as i am struggling to get this to work.
Regards
Betty
I am quite new to MVC 3.
I know how to send a strongly typed object from a Controller to a View. What I have now, is a View which contains a table/form which consists of that data.
The user can change that data whilst they're are in that View (html page).
When they click on "Save", how do I send the data from the View back to the Controller so that I can update my database.
Do I overload the Controller method so that it accepts a parameter of the model type? Can you please provide some source code.
(Please do not show code of persisting data to a database, I know how to do that part).
Thank you very much for helping me.
I would also prefer using #Html.BeginForm()
I like creating an action method made for my post data. So let's say you have a UserViewModel:
public class UserViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
Then a UserController:
public class UserController
{
[HttpGet]
public ActionResult Edit(int id)
{
// Create your UserViewModel with the passed in Id. Get stuff from the db, etc...
var userViewModel = new UserViewModel();
// ...
return View(userViewModel);
}
[HttpPost]
public ActionResult Edit(UserViewModel userViewModel)
{
// This is the post method. MVC will bind the data from your
// view's form and put that data in the UserViewModel that is sent
// to this method.
// Validate the data and save to the database.
// Redirect to where the user needs to be.
}
}
I'm assuming you have a form in your view already. You'll want to make sure that the form posts the data to the correct action method. In my example, you'd create the form like so:
#model UserViewModel
#using (Html.BeginForm("Edit", "User", FormMethod.Post))
{
#Html.TextBoxFor(m => m.Name)
#Html.HiddenFor(m => m.Id)
}
The key to all this is the model binding that MVC does. Make use of the HTML helpers, like the Html.TextBoxFor I used. Also, you'll notice the top line of the view code I added. The #model tells the view you'll be sending it a UserViewModel. Let the engine do work for you.
Edit: Good call, did that all in Notepad, forgot a HiddenFor for the Id!
In MVC, the act of scraping out data from POST or GET HttpRequests is referred to as Model Binding - there are plenty of SO questions relating to this.
Out of the box, MVC will bind your Get and Post variables based on convention, e.g. a form field with the name 'FormName' will be bound back to a parameter on your controller with the same name.
Model binding also works for objects - MVC will instantiate an object for your controller, and set the properties with the same name as your form.
I am trying to insert a custom header (held in a database) on my master page. The custom header changes on a user by user basis.
I'm slightly confused on how to attach a controller to a partial (if I even can do this). What I'm hoping to accomplish is to render a block of code from a specific controller called with some events.
public ActionResult GetHeader(Guid clientID)
{
string szHeader = GetTheme(ThemeType.Portal, JoloTheme.ThemeArea.Header, clientID);
return Content(szHeader, "text/html");
}
Is the controller I have created, but I'm not sure how to get this onto a subsection of a page I am currently writing (not in the same Controller).
Apologies if this is completely nonsense here, still learning MVC I'm afraid.
You should use Html.Action() helper in your _Layout.cshtml. I think you should use a Nullable Guid as a parameter because you won't be able to provide a valid clientID always.
public ActionResult GetHeader(Guid? clientID)
{
string szHeader = GetTheme(ThemeType.Portal, JoloTheme.ThemeArea.Header, clientID);
return Content(szHeader, "text/html");
}
Here's how you should call Html.Action helper in your _Layout.cshtml
#Html.Action("GetHeader",
"SomeController",
new { clientID = IsLoggedIn ? ClientID : (Guid?)null } )
I'm using MVC3 razor, and I'm trying to pass an object to a partial view, and it's not working.
This works fine without sending the object model to the partial view:
Html.RenderAction("Index", "ViewName");
Trying this doesn't sent the model object, i'm getting nulls instead (the object has data, and the view expects it):'
Html.RenderAction("Index", "ViewName", objectModel);
Is this even possible using RenderAction?
Thanks!
Edit: I found the error, there was an error with the controller's action that didn't pick up the sent object. Thanks for all your help!
You can actually pass an object to a controller method using Action. This can be done on any avaialble view, for instance I have one in a shared library that gets built to project bin folders that reference my shared project (properties - Copy if newer on the view file, in Visual Studio). It is done like so:
Controller:
public class GroovyController : Controller
{
public ActionResult MyTestView(MyModel m)
{
var viewPath = #"~\bin\CommonViews\MyTestView";
return View(viewPath, m);
}
}
MVC page (using Razor syntax):
#Html.Action("MyTestView", "Groovy", new { m = Model })
or using RenderAction method:
#{ Html.RenderAction("MyTestAction", "MyTestController", new { area = "area", m = Model }); }
Note: in the #Html.Action(), the Model object must be of type MyModel and that 3rd parameter must be set to the controller variable name, of which mine is MyModel m. The m is what you must assign to, so I do m = Model.
say you want to pass foo as model, make it first
public class Foo {
public string Name { get; set; }
public int Age { get; set; }
}
now make an ActionResult
public ActionResult FooBar(Foo _foo){
return PartialView(_foo);
}
call it
#Html.RenderAction("FooBar", "Controller", new { Name = "John", Age=20 });
Usually if I have a model already available it makes more sense to use Html.Partial than trying to render an action.
#Html.Partial("Foo", Model.FooModel)
Where Foo.cshtml is a view file (perhaps in your Shared folder) strongly typed with with #model FooProject.Models.FooModel or whatever your model is called. This can be as complex a model as you need it to be. Model is your page's main model into which you must set FooModel - or just omit this parameter if the Foo view uses the same model as the parent page.
RenderAction is generally better when you have just simple parameters, because you're just simulating a request to a regular action which has routing/query string parameters - and then dumping that response into your page. It works well if you need to put something in a Layout that isn't available in your page's model such as an element in a side bar.
I am using ASP.NET MVC 3.
I have an action method called New. When form validation succeeds then I want Create to handle the request.
public ActionResult New()
{
// Code
}
[HttpPost]
public ActionResult Create()
{
// Code
}
I have 2 questions regarding this. Firstly, how do I modify my Html.BeginForm to handle the above? I tried the following but I get an error, it is looking for the physical file Create (News is my controller name):
#using (Html.BeginForm("Create", "News"))
{
<!-- Code -->
}
Secondly, how do I prevent a user from typing in /News/Create in the URL. Create should handle only my post requests coming from New.
UPDATE:
I managed to get something working. The original URL looks like this:
http://localhost:33947/News/New
After I click the submit button and validation fails then the URL looks like:
http://localhost:33947/News/Create
Why does it do this? I want it to stay:
http://localhost:33947/News/New
Here is my action method code:
public ActionResult New()
{
return View();
}
[HttpPost]
public ActionResult Create(NewsViewModel newsViewModel)
{
if (!ModelState.IsValid)
{
return View("New", newsViewModel);
}
return View("Index");
}
#using (Html.BeginForm("Create", "News", FormMethod.Post))
You cannot prevent user from typing address manually, but you can add another Create action marked with [HttpGet] attribute which will show user the error page. Anyway, your current Create action method will not handle such requests. Probably user will get standard File not found error in this case.
UPDATE: Html.BeginForm("Create", "News") means to submit the form to action "Create" of the controller "News", so it works as it should. If you want to submit to /News/New, replace it with Html.BeginForm("New", "News").
Regarding your second question, instead of:
if (!ModelState.IsValid)
{
return View("New", newsViewModel);
}
you should use :
if (!ModelState.IsValid)
{
return RedirectToAction("new");
}
Now this has the undesired side affect that your Modelstate is lost. (no validation errors are shown in your form.
To fix this add the ModelStateToTempData attribute to both your new and create action.
This attribute come as part of http://mvccontrib.codeplex.com/ .