In a ASP.NET MVC website; does every view need to have a corresponding/associated Model and Controller?
I am building the bare bones of my website; so I have created all the views but not the Models or Controllers yet. I want to be able to view a page (that contains no content associated with a model or any functionality that a controller should handle - yet). So at this point every view (cshtml page) is a static HTML page.
But when I go to access any view/page I get the error:
The resource cannot be found. Description: HTTP 404. The resource you
are looking for (or one of its dependencies) could have been removed,
had its name changed, or is temporarily unavailable. Please review
the following URL and make sure that it is spelled correctly.
Requested URL: /TeamMember/raiseIssue
raiseIssue.cshtml content:
#{
Layout = "layouts/main.cshtml";
}
<form action="#ViewBag.PostUrl" method="post">
<div class="row feedback-input text-center">
<textarea name="Text"></textarea>
</div>
<div class="row text-center">
<button type="submit" class="btn btn-default btn-standard">Submit</button>
</div>
</form>
MVC do not allows to browse the view directly. What you can do is create empty controller method like below
public ActionResult RaiseIssue()
{
return View();
}
in controller TeamMemberController
One other thing, please make sure that proper route are configured in RouteConfig.cs
I hope using this method you will be able to browser the view with writing much code in controller or model/
Related
I've written a system using ASP.NET MVC that generates various financial reports. Each report is in it's own controller, each controller has its own "Report" Action. The Action Renders a partial view with the report in the ViewBag which it passes to javascript on the front end and puts the rendered element in a JQueryUI dialog.
A user may run a Balance Sheet report then another user may run an Income Statement report, after the first user runs the Balance Sheet Report and instead of seeing the Income Statement, the second user sees the Balance Sheet.
This is the code that returns the report as a JSON object
//Initialize report and add datasources etc.
reportViewer.LocalReport.Refresh();
ViewBag.ReportViewer = reportViewer;
return Json(JsonResponse.Success(RenderRazorViewToString("PrintVoucher", null)));
Here is the Partial View
#using ReportViewerForMvc;
<div class="col-md-12 col-lg-12 col-sm-12 col-xs-12">
#Html.ReportViewer(ViewBag.ReportViewer as Microsoft.Reporting.WebForms.ReportViewer)
</div>
Any advice or guidance would be greatly appreciated!
We ran into the same issue and it seems to be related to a concurrency bug in the ReportViewerForMvc. Stumbled on this old github link which had the information and proposed fix. Hope this helps.
https://github.com/nrifath2009/ReportViewerForMvc/pull/1
Try making your partial view a strongly typed view for "reportViewer" using it in the #Html.ReportViewer() and not the view bag.
After that go to the code that returns that partial view and on return set that as
return Json(JsonResponse.Success(RenderRazorViewToString("PrintVoucher", reportViewer)));
Make sure that your Action have no OutputCache attribute to make
sure the server always calculate new report for each request or Set
VaryByParam on attribute constructor
Use strongly type model instead of ViewBag
Initialize new object of the ReportViewer on each call instead of using a single static object.
Use PartialView on Controller action and pass the report object to the PartialView, Razor engine will process the Partial View with the model and generate an HTML markup as a return for the json call.
Here a working Sample of the controller and the View (I've used Bootbox instead of JqueryUI)
Controller :
[HttpPost, ValidateAntiForgeryToken]
public PartialViewResult Report(/*Pass Optional Parameters If Required*/)
{
var reportViewer = new ReportViewer();
//reportViewerInitialization
return PartialView("PrintVoucher", reportViewer);
}
JavaScript Method for loading Report View
function showReport(reportControllerName)
{
var dialog = bootbox.dialog({
message: '<p><i class="fa fa-spin fa-spinner"></i> Loading...</p>'
});
$.ajax({
type: "POST",
url: '/'+ reportControllerName +'/Report/',
data: {/*DataPassed To The Report Action*/},
success: function (data) {
//data Field will contain an Html markup resulted from razor engine process for PrintVoucher PartialView
dialog.find('.bootbox-body').html(data);
}
});
}
PrintVoucher.cshtml
#using ReportViewerForMvc;
<div class="container">
<div class="row">
<div class="col-md-12 col-lg-12 col-sm-12 col-xs-12">
#Html.ReportViewer(Model as Microsoft.Reporting.WebForms.ReportViewer)
</div>
</div>
</div>
I am using MVC4, C# and visual studio ultimate 2013 in a project.
I am redirecting a user to an index page after submiting a form. However, this webpage has 2 tabs, and I want to redirect the user to the second tab, instead of the first one.
I have a Controller called Material, with an Index action, which sends the user to the Index View.
public ActionResult Index()
{
return View();
}
This View is made of two partial Views, _Materials and _Packages.
#{
ViewBag.Title = "Index";
}
<div class="tabbable">
<ul class="nav nav-tabs">
<li class="active">Materials</li>
<li>Packages</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="Materials">
#Html.Action("Materials", "Material")
</div>
<div class="tab-pane" id="Packages">
#Html.Action("Packages", "Package")
</div>
</div>
</div>
After performing a serie of actions in another section of the application, I which to redirect the user to the /Material page, to the second tab, but I have no idea how to do it !
Currently I am using this code, which always redirects to the first tab:
return RedirectToAction("Index", "Material");
How can I fix my problem?
You can't use something like RedirectToAction because it does not have any capability of appending a URL fragment. What you can do is use something like Redirect which just takes a URL string, and then use the URL helper to still dynamically generate the action URL for you:
return Redirect(Url.Action("Index", "Material") + "#Package");
In other words, Url.Action will generate the main URL for you and return it as a string. You can then append the fragment to this string before finally redirecting.
You'll want to use the
Redirect method
Redirect("www.sitename.com/material/index#Package");
or
string fragment = "Package";
Redirect("www.sitename.com/material/index#" + fragment);
The #Package is what is called a Fragment Identifier, that will focus your browser on the part of the page with the id of Package.
You can simply write an Ajax call to pass to the controller and in case of success, append #tab to the url parameter. for example use this:
I want this:
#using (Html.BeginForm("bgcTest", "CompaniesController"))
{
<p>
Ange BolagsID: <br />
<input type="text" name="BolagsID" />
<input type="submit" value="bgc test" />
</p>
}
To fire this event:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult bgcTest(string BolagsID)
{
...
}
But I get the error:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its
dependencies) could have been removed, had its name changed, or is
temporarily unavailable. Please review the following URL and make
sure that it is spelled correctly.
Requested URL: /CompaniesController/bgcTest
I can't for the life of me figure it out. If I just make an actionlink I get my method to fire, but I need an user inputted variable to go along with the fireing.
What am I doing wrong?
(This is my first time with MVC and I have to implement some functionality into an already existing project. For work.)
The name of your controller class (.cs file) is CompaniesController.cs.
That's a convention (default behavior) where MVC will automatically identify it as a controller.
When referencing this controller in your view, use Companies only.
If you use CompaniesController MVC will try to find a CS file named CompaniesControllerController.
Correct code:
#using (Html.BeginForm("bgcTest", "Companies"))
I have a simple MVC application that retrieves DB Server, database, username and password from the user to store in an XML file. I want to add a "Test Connection" button to the screen and have it execute a method on the controller called TestConnection. The problem is the TestConnection method resets all the information on the screen when clicked since the View is being returned with no model. (because a GET operation is occurring). Here is my code:
From the Controller (named FrameworkConfigurationController.cs)
public ActionResult TestConnection()
{
return View("Index");
}
[HttpPost]
public ActionResult TestConnection(FrameworkConfigurationViewModel viewModel)
{
// TODO: Test will occur here
viewModel.DbConnectionMessage = string.IsNullOrEmpty(viewModel.DatabaseName) ? "Connection unsuccessful" : "Connection successful";
return View("Index", viewModel);
}
From my View (FrameworkConfiguration/Index):
#model Framework.ViewModels.FrameworkConfigurationViewModel
#{
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>FrameworkConfigurationViewModel</legend>
<div class="editor-label">
#Html.LabelFor(model => model.ServerName)
</div>
#* Edited for brevity *#
<button type="submit" onclick="location.href='#Url.Action("TestConnection")'">
Test Connection</button>
#Html.ValueFor(model => model.DbConnectionMessage)
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to Dashboard", "Index", "Home")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Admittedly, I am new to MVC programming. I'm coming from a Silverlight/MVVM background so the concept is not foreign to me...the disconnected nature of web programming is. I've followed some tutorials out there, but none of them seem to cover this type of thing - every example is contrived. I know how to do this with webforms and code-behind, but I would like to accomplish this with MVC.
Is there some way to "force" the POST operation instead of GET? I was under the impression that
<button type="submit">
accomplished that. Perhaps the implementation of the onclick I have written isn't correct. I am sure this is HTML 101 stuff, but I can't seem to find a simple answer to this.
Thanks for any help you can offer,
Jason
Why not have the Test Connection button trigger an Ajax action to call the controller, and display the result?
That way you avoid submitting your entire page.
In case you're not familiar with the details, here's a good overview on getting started with Ajax and MVC 4
http://ofps.oreilly.com/titles/9781449320317/ch_AJAX.html
I have a shared view in my _Layout.cshtml for my header named "_Header.cshtml".
I would like to display text and image from the database, so I need my controller to go in the database and return it to the _Header.cshtml.
How can I do that because the controller called is always different each page the user goes. Is there a way to have controller with Shared View?
Here is the _Layout.cshtml
<div id="header">
<div id="title">
#Html.Partial("_Header")
</div>
<div id="logindisplay">
#Html.Partial("_CultureChooser")
<br />
#Html.Partial("_LogOnPartial")
</div>
<div id="menucontainer">
#Html.Partial( "_MenuPartial")
</div>
</div>
<div id="main">
#RenderBody()
<div id="footer">
</div>
</div>
</div>
In your contoller action you could specify the name of the view:
public class MenuController : Controller
{
[ChildActionOnly]
public ActionResult Header()
{
var model = ... // go to the database and fetch a model
return View("~/Views/Shared/_Header.cshtml", model);
}
}
Now in your _Layout.cshtml instead of #Html.Partial("_Header") do this:
#Html.Action("Header", "Menu")
... 1 year later would just like to add one thing to Dimitrov answer. You can make the controller a little cleaner:
public class MenuController : Controller
{
[ChildActionOnly]
public ActionResult Header()
{
var model = ... // go to the database and fetch a model
return Partial("_Header", model);
}
}
Create an action in one of your controllers to render the header view, then simply call #Html.RenderAction("Header") within the _Layout.cshtml.
You can also pass a model into the RenderAction method if required.
While the RenderAction approach that WDuffy provided works well, I recently blogged about this very topic using another approach using IoC:
http://crazorsharp.blogspot.com/2011/03/master-page-model-in-aspnet-mvc-3-using.html
I hope the question you have asked is Like....
Can we have a controller for a Shared Layout View.
Simple answer is No.
To achieve this goal you have to create a partial view for the Same purpose and put it into you shared Layout. By that means you can achieve you Goal