Link to .cshtml view from javascript

All we need is an easy explanation of the problem, so here it is.

How can you point directly to a .cshtml view from javascript file?
For example why can’t I use a .cshtml view with angular.js?
like in this example:

 .directive('encoder', ($timeout) => {
        return {
            restrict: 'E',
            transclude: true,
            scope: 'isolate',
            locals: { service: 'bind' },
            templateUrl: 'encoderTemplate.cshtml' // <-- that's not possible?
        }
    });

It’s of course possible to have an action method that returns whatever you want, but I’m curious if it’s possible to reference directly to the razor view.

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

As mentioned in a comment, you can’t serve up .cshtml files directly, However, you can use a controller to render the content if you so choose:

public class TemplateController : Controller
{
    // create a ~/Views/Template/Encoder.cshtml file
    public PartialViewResult Encoder()
    {
        return PartialView();
    }
}

Then reference it like you would with @Url.Action:

{
    ....
    templateUrl: '@Url.Action("Encoder", "Template")'
}

From Comment

If you have most of the JavaScript code outside of something that has Razor access (e.g. external .js file) you can still take advantage of the Url builder, just have to do so a little differently. For instance, I may do something like:

public class TemplateController : Controller
{
    // Add a child method to the templates controller that outputs default
    // configuration settings (and, since it's a child action, we can re-use it)
    [ChildActionOnly]
    public PartialViewResult Index()
    {
        // You could build a dynamic IEnumerable<ConfigRef> model
        // here and pass it off, but I'm just going to stick with a static view
        return PartialView();
    }
}

~/Views/Template/Index.cshtml

<script type="text/javascript">
  if (typeof window.App === 'undefined'){
    window.App = {};
  }
  App.Templates = {
    Encoder: '@Url.Action("Encoder", "Template")',
    Template1: '@Url.Action("Template1", "Template")',
    Template2: '@Url.Action("Template2", "Template")'
  };
</script>
@*
   the template files would then reference `App.Templates.Encoder`
   when they need access to that template.
*@
@Scripts.Render("~/js/templating")

Index.cshtml (or whatever is any view)

@* ... *@
@{ Html.RenderAction("Index", "Template"); }
@* ... *@

Method 2

Another option is:

1.Add TemplatesController with EncoderTemplate view

public class TemplatesController : Controller
{

     public ActionResult EncoderTemplate()
     {

           return View();
     }

}

2.Add Layout = null to EncoderTemplate.schtml view

@{
    Layout = null;
}

<div>Your html goes here</div>

3.Point to the EncoderTemplate.schtml as shown below

.directive('encoder', ($timeout) => {
    return {
        restrict: 'E',
        transclude: true,
        scope: 'isolate',
        locals: { service: 'bind' },
        templateUrl: '/Templates/EncoderTemplate' // you should not add .schtml
    }
});

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply