When overloading a controller that returns a view, how should I load other content based on the ViewBag property?

I have 2 Index

functions,

public ActionResult Index ( )
{
 ...
}

      

and

[HttpPost]
public ActionResult Index (HttpPostedFileBase file, string selectedOrgName, string selectedCatName)
{
 ...
}

      

The second method adds a specific object:

ViewBag.orgcatJSON = PD.mapOrgs2Cats();

      

in ViewBag

, and the first is not. If I call the second method, I need to use Javascript to do something with that object; if i call the first method i won't. So what I do is

var ogmap = @Html.Raw(@ViewBag.orgcatJSON);
$(function() {
    if (ogmap != undefined)
    {
       // do something
    }
});

      

but it looks like a very bad shape. Is there a better way to do this?

+3


source to share


1 answer


If you want to have different content in your view depending on the method, do just that and use two views. Then you can use partial files for linked content to keep DRY .

The main advantage of separating such views is that you have made a lot more dependencies (a ViewBag

in this case). In your example, you will have to dig completely into javascript to discover this detail, which can take a while. As a general rule, I always try to keep my views as silly (as logical as it makes sense to complete the task).

For example:

Controllers /ExampleController.cs

public ActionResult Index ( )
{
    //...
    return View("View1");
}

[HttpPost]
public ActionResult Index (HttpPostedFileBase file, string selectedOrgName, string selectedCatName)
{
    //...
    ViewBag.orgcatJSON = "some json string"; 
    return View("View2");
}

      

Views / Example / View1.cshtml :

<h1>View 1</h1>
<!-- specific content here -->

<!-- now include shared content -->
@Html.Partial("SharedContent")

      

Views / Example / View2.cshtml :

<h1>View 2</h1>
<!-- specific content here -->

<!-- now include shared content -->
@Html.Partial("SharedContent")

<script>
var ogmap = @Html.Raw(ViewBag.orgcatJSON);
$(function() {
      //functionality here
});
</script>

      

Views / Example / SharedContent.cshtml :



<p>Hello World!</p>

      


To expand on the point of clearer dependencies, you can make it even clearer by binding your expected type using ModelBinder

. Then your dependency will be even less hidden and you can replace your usage ViewBag

with your directly linked json.

For more information on what it is ModelBinder

and how it works, I suggest you read this post .

If you choose to go this route, change the second index method and second View to the following:

Controllers /ExampleController.cs

[HttpPost]
public ActionResult Index (HttpPostedFileBase file, string selectedOrgName, string selectedCatName)
{
    //...
    //let pass the json directly to the View and make the dependency 100% clear
    var json = "some json string"; 
    return View("View2", json);
}

      

Views / Example / View2.cshtml :

@model System.String
<!-- in the above line, we are telling the view what type we expect to be bound by the controller -->
<h1>View 2</h1>
<!-- specific content here -->

<!-- now include shared content -->
@Html.Partial("SharedContent")

<script>
var ogmap = @Html.Raw(model);
$(function() {
      //functionality here
});
</script>

      

+3


source







All Articles