无法在布局剃刀视图文件中使用@ Html.React

时间:2018-09-16 21:17:13

标签: c# asp.net-mvc reactjs reactjs.net

看来,在解决了我以前的CSS问题之后,我遇到了另一个障碍。我试图从reactjs.net网站进行“优化:服务器端渲染”练习。不幸的是,问题-我无法在剃刀视图中使用“ @ Html.React”方法来传递注释框模型。我已经尝试了几种可能不必要的导入,并确保更新了ReactConfig文件,以便可以使用该代码。谁能告诉我我在这里想念的东西吗?

ReactConfig.cs:

using React;

[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(ReactExamplePractice.ReactConfig), "Configure")]

namespace ReactExamplePractice
{
    using React;
    public static class ReactConfig
    {
        public static void Configure()
        {
            // If you want to use server-side rendering of React components, 
            // add all the necessary JavaScript files here. This includes 
            // your components as well as all of their dependencies.
            // See http://reactjs.net/ for more information. Example:
            //ReactSiteConfiguration.Configuration
            //  .AddScript("~/Scripts/First.jsx")
            //  .AddScript("~/Scripts/Second.jsx");
            ReactSiteConfiguration.Configuration = new ReactSiteConfiguration()
                .AddScript("~/Scripts/react/Tutorial.jsx");
            //ReactSiteConfiguration.Configuration
            //    //.AddScript("~/js/remarkable.min.js")
            //    .AddScript("~/Scripts/react/Tutorial.jsx");
            // If you use an external build too (for example, Babel, Webpack,
            // Browserify or Gulp), you can improve performance by disabling 
            // ReactJS.NET's version of Babel and loading the pre-transpiled 
            // scripts. Example:
            //ReactSiteConfiguration.Configuration
            //  .SetLoadBabel(false)
            //  .AddScriptWithoutTransform("~/Scripts/bundle.server.js")
        }
    }
}

BundleConfig.cs:

using System.Web;
using System.Web.Optimization;
using System.Web.Optimization.React;

namespace ReactExamplePractice
{
    public class BundleConfig
    {
        // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862
        public static void RegisterBundles(BundleCollection bundles)
        {
            bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                        "~/Scripts/jquery-{version}.js"));

            bundles.Add(new BabelBundle("~/bundles/main").Include(
                "~/Scripts/react/Tutorial.jsx"
            ));

            // Forces files to be combined and minified in debug mode
            // Only used here to demonstrate how combination/minification works
            // Normally you would use unminified versions in debug mode.
            BundleTable.EnableOptimizations = true;

            bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                        "~/Scripts/jquery.validate*"));

            // Use the development version of Modernizr to develop with and learn from. Then, when you're
            // ready for production, use the build tool at https://modernizr.com to pick only the tests you need.
            bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
                        "~/Scripts/modernizr-*"));

            bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
                      "~/Scripts/bootstrap.js"));

            bundles.Add(new StyleBundle("~/Content/css").Include(
                      "~/Content/bootstrap.css",
                      "~/Content/site.css"));
        }
    }
}

_Layout.cshtml:

@using System.Web.Optimization.React;
@using React;
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    @*<environment exclude="Development">
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" integrity="sha384-WskhaSGFgHYWDcbwN70/dfYBj47jz9qbsMId/iRN3ewGhXQFZCSftd1LZCfmhktB" crossorigin="anonymous">
    </environment>*@

    <environment exclude="Development">
        <link href="~/Content/bootstrap.min.css" rel="stylesheet" />
    </environment>

    <title>@ViewData["Title"] - ASP.NET Core Pages Webpack</title>
    @model IEnumerable<ReactExamplePractice.Models.CommentModel>
        @{ 
            Layout = null;
        }
</head>
<body>
    <div class="container">
        <nav class="bg-dark mb-4 navbar navbar-dark navbar-expand-md">
            <a asp-page="/Index" class="navbar-brand">
                <em>ASP.NET Core Pages Webpack</em>
            </a>
            <button aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler" data-target="#topNavbarCollapse" data-toggle="collapse" type="button">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="topNavbarCollapse">
                <ul class="mr-auto navbar-nav">
                    <li class="nav-item">
                        @Html.ActionLink("Application Name", "Index", "Default", new { area = "" }, new { @class = "navbar-brand" })
                    </li>
                    <li class="nav-item">
                        <a asp-page="/About" class="nav-link">About</a>
                    </li>
                    <li class="nav-item">
                        <a asp-page="/Contact" class="nav-link">Contact</a>
                    </li>
                </ul>
                <ul class="navbar-nav">
                    <li class="nav-item">
                        <a class="nav-link" href="https://twitter.com/damien_bod">
                            <img height="30" src="assets/damienbod.jpg" />
                        </a>
                    </li>
                </ul>
            </div>
        </nav>

    </div>

    <partial name="_CookieConsentPartial" />

    <div class="container body-content">
        @RenderBody()

        <hr />
        <footer>
            <p>&copy; 2018 - ASP.NET Core Pages Webpack Bootstrap 4</p>
        </footer>
    </div>

    <environment exclude="Development">
        <!-- Optional JavaScript -->
        <!-- jQuery first, then Popper.js, then Bootstrap JS -->
        @*<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js" integrity="sha384-smHYKdLADwkXOn1EmN1qk/HfnUcbVRZyYmZ4qpPea6sjB/pTJ0euyQp0Mk8ck+5T" crossorigin="anonymous"></script>*@
        <script src="~/Scripts/jquery-3.3.1.slim.min.js"></script>
        <script src="~/Scripts/popper.min.js"></script>
        <script src="~/Scripts/bootstrap.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.0/umd/react.development.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.0/umd/react-dom.development.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/remarkable/1.7.1/remarkable.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.0/prop-types.js"></script>
        @Scripts.Render("~/bundles/main");
        @*<script src="@Url.Content("~/Scripts/react/Tutorial.jsx")"></script>*@
    </environment>

    @RenderSection("Scripts", required: false)
</body>
</html>

DefaultController.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using ReactExamplePractice.Models;
using System.Web.Optimization.React;
using React;

namespace ReactExamplePractice.Controllers
{
    public class DefaultController : Controller
    {
        private static readonly IList<CommentModel> _comments;

        static DefaultController()
        {
            _comments = new List<CommentModel>
            {
                new CommentModel
                {
                    Id = 1,
                    Author = "Daniel Lo Nigro",
                    Text = "Hello ReactJS.NET World!"
                },
                new CommentModel
                {
                    Id = 2,
                    Author = "Pete Hunt",
                    Text = "This is one comment"
                },
                new CommentModel
                {
                    Id = 3,
                    Author = "Jordan Walke",
                    Text = "This is *another* comment"
                },
            };
        }

        [OutputCache(Location = OutputCacheLocation.None)]
        public ActionResult Comments()
        {
            return Json(_comments, JsonRequestBehavior.AllowGet);
        }

        [HttpPost]
        public ActionResult AddComment(CommentModel comment)
        {
            //Create a fake ID for this comment or something
            comment.Id = _comments.Count + 1;
            _comments.Add(comment);
            return Content("Success :)");
        }

        // GET: Default
        public ActionResult Index()
        {
            return View();
        }
    }
}

Tutorial.jsx:

class CommentBox extends React.Component {
    constructor(props) {
        super(props);
        this.state = { data: this.props.initialData };
        this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
    }

    loadCommentsFromServer() {
        const xhr = new XMLHttpRequest();
        xhr.open('get', this.props.url, true);
        xhr.onload = () => {
            const data = JSON.parse(xhr.responseText);
            this.setState({ data: data });
        };
        xhr.send();
    }

    handleCommentSubmit(comment) {
        const comments = this.state.data;
        // Optimistically set an id on the new comment. It will be replaced by an
        // use a more robust system for ID generation.
        // id generated by the server. In a production application you would likely
        comment.Id = comments.length + 1;
        const newComments = comments.concat([comment]);
        this.setState({data: newComments});

        const data = new FormData();
        data.append('Author', comment.Author);
        data.append('Text', comment.Text);

        const xhr = new XMLHttpRequest();
        xhr.open('post', this.props.submitUrl, true);
        xhr.onload = () => this.loadCommentsFromServer();
        xhr.send(data);
    }

    componentDidMount() {
        window.setInterval(() => this.loadCommentsFromServer(), this.props.pollInterval);
    }

    render() {
        return (
            <div className="commentBox">
                <h1>Comments</h1>
                <CommentList data={this.state.data} />
                <CommentForm onCommentSubmit={this.handleCommentSubmit} />
            </div>
        );
    }
}

class CommentList extends React.Component {
    render() {
        const commentNodes = this.props.data.map(comment => (
            <Comment author={comment.Author} key={comment.Id}>
                {comment.Text}
            </Comment>
            ));
        return (
            <div className="commentList">
                {commentNodes}
      </div>
        );
    }
}

class CommentForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = { author: '', text: '' };
        this.handleAuthorChange = this.handleAuthorChange.bind(this);
        this.handleTextChange = this.handleTextChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleAuthorChange(e) {
        this.setState({author: e.target.value});
    }

    handleTextChange(e) {
        this.setState({ text: e.target.value });
    }

    handleSubmit(e) {
        e.preventDefault();
        const author = this.state.author.trim();
        const text = this.state.text.trim();
        if (!text || !author) {
            return;
        }
        this.props.onCommentSubmit({Author: author, Text: text});
        this.setState({ author: '', text: '' });
    }

    render() {
        return (
            <form className="commentForm" onSubmit={this.handleSubmit} >
                <input type="text" placeholder="Your name" value={this.state.author} onChange={this.handleAuthorChange} />
                <input type="text" placeholder="Post something here!" value={this.state.text} onChange={this.handleTextChange} />
                <input type="submit" value="Post" />
      </form>
        );
    }
}

class Comment extends React.Component {
    rawMarkup() {
        const md = new (global.Remarkable || window.Remarkable)();
        const rawMarkup = md.render(this.props.children.toString());
        return { __html: rawMarkup };
    }
    render() {
        return (
            <div className="comment">
                <h2 className="commentAuthor">
                    {this.props.author}
                </h2>
                <span dangerouslySetInnerHTML={this.rawMarkup()} />
            </div>
        );
    }
}

class HelloWorld extends React.Component {
    render() {
        return (
            <div>
                <h1> Hello World React JS! </h1>
    </div>)  
                    }  
                }

//ReactDOM.render(
//    <CommentBox url="/comments" submitUrl="/comments/new"  pollInterval={2000} />,
//    document.getElementById('content')
//);

任何帮助/见解将不胜感激。在此先感谢一吨!

1 个答案:

答案 0 :(得分:0)

所以,我来发现一些奇怪的东西,也许只是我的Visual Studio环境或其他东西,但是当使用NuGet包中的Html.React库时,它首先不会加载方法-但是然后,一旦我保存了该项目,退出并重新打开,这种智能错误就消失了!

我也想快速提及一下,在线ASP.NET教程的Remarkable库中存在一个错误。请参阅以下帖子:

https://github.com/reactjs/React.NET/issues/349

我相信,无论谁需要它,都可以在该错误中找到解决方法。

这种情况很奇怪。我希望这篇文章可以帮助其他人。