【问题标题】:Passing a large HTML string from View to Controller将大型 HTML 字符串从 View 传递到 Controller
【发布时间】:2014-12-17 21:28:28
【问题描述】:

注意:我现在是一名前端开发人员,戴着 .Net 开发人员的帽子。可笑,我知道,但我是如何落入这个烂摊子的并不是这个问题的重点。排除了免责声明,这就是正在发生的事情。

正如标题所示,我需要将一个相当长的 HTML 字符串(如在多页文本中)从视图传递给控制器​​。我花了最近几天研究实现这一目标的各种方法。 TBH,有些事情是有道理的,而有些事情没有。

这是我在查看中的代码片段:

var html =
    "<form id='htmlContent' action='" + customUrl + "' method='post'>" +
        "<input type='hidden' name='content' id='contentStr'>" +
    "</form>";

// string literal html gets appended to some element...

$("#htmlContent").submit();

我想在这里指出几点:

  • 我在这里使用字符串文字来构造表单,因为此 DOM 需要在某些时候动态附加到其他元素。
  • 我是否使用有效的 HTML 字符串是不可能的。我已经单独测试了它的有效性,一切看起来都很好。
  • 我有意使用 jQuery 的 submit() 方法而不是使用 Ajax 调用。

控制器:

[HttpPost]
public ActionResult ParseHtml(FormCollection form)
{
    string htmlStr = form["content"].ToString();
    ....
    // some code in between, but the first line appears to be causing an error or
    // the value is not being retrieved.
    ....
    return new EmptyResult();
}

我知道我是在 MVC 框架的上下文中工作的,并且我有点理解它的概念。但是,以我非常有限的知识知道如何实现它是另一回事(尤其是当你从一个早已离开你的项目的人那里继承了一个糟糕的代码库时!)

我想这很简单,也很容易做到,但我转动轮子的时间比我想要的要长得多。任何指向正确方向的指针将不胜感激。

【问题讨论】:

  • “一切看起来都很好”是一些非常好的遗言!在这种情况下,您的模型是什么?
  • @CBauer - 更不用说,“但它可以在我的机器上运行!”顺便说一句,我没有为此特定代码创建的任何模型。
  • 对于输入类型,你有值吗?如果没有输入值,我不确定这将如何工作。
  • 是否必须将其附加到 DOM 中,还是可以隐藏在其中并在程序执行期间使其可见?
  • @SurgeonofDeath - 不确定我是否理解正确,但我确实有一个正确分配给输入字段的值(html 字符串)。

标签: c# forms model-view-controller


【解决方案1】:

在这个最小的可重现答案中,我将向您展示如何使其正常工作,您可以从这里运行它:

索引.cshtml

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
    $(document).ready(function () {
        var url = '@Url.Action("Create","Stack")';
        var html = $("<form id='htmlContent' action='"+url+"' method='post'><input type='hidden' name='content' id='contentStr' value='oranges'/></form>");
        $(body).append(html);

        $("#htmlContent").submit();
    });
</script>

@{
    ViewBag.Title = "title";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>title</h2>

Controller.cs

using System.Web.Mvc;

namespace MvcPlayground.Controllers
{
    public class StackController : Controller
    {
        //
        // GET: /Stack/

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Create(FormCollection form)
        {
            string htmlStr = form["content"].ToString();

            return View("Index");
        }
    }
}

如果您在return View("Index"); 上放置断点,您将看到 htmlStr 为“oranges”,即附加文本框的值。

【讨论】:

    【解决方案2】:

    由于我不确定所有细节,因此无法回答您问题的主要部分,抱歉。我并不是说你在做任何事情都“错误”,因为我不确定是什么外围可能使它看起来像是必要的,但你可能正在创造一种情况,你将有一个严重的头痛在后端解析和什么不是。很可能其中很多都是错误的,因为我不确定要求,所以我很抱歉。

    "I'm using a string literal to construct the form here because this 
     DOM needs to be dynamically attached to other element at some point."
    

    您想在另一个组件中重新渲染相同的元素?听起来您正在寻找局部视图。这样,您可以在 View1 中渲染它并在 View2 中使用相同的数据。如果您正在尝试动态创建元素,我想您正在使用某种类型的模式(即,我正在开展一个项目,我正在迭代一个集合并执行

    <input type='text' id='attribute_@(item.Id)' name='attribute_@(item.Id)' />
    

    然后遍历 FormCollections AllKeys 元素来获取它们(解析出属性_和你喜欢什么:

    foreach(var key in form.AllKeys)
    {
      var id = Convert.ToInt32(key.Replace("attribute_", "")); // may want to TryParse
      var item = Item.GetItemById(id);
      item.Value = form[key];
      item.Update();
    }
    

    在视图中的某处,您正在使用 javascript 设置 document.getElementById("contentStr") (不确定是否有意,但您的 id 和 name 不同。本身不是一件坏事,但可能会导致 oops )?再说一次,不确定这里使用了什么 var html = 。 Razor 视图,您可以只执行 [form] ... [/form] 的常规 html。在提交操作之前您是否正在做类似的事情?

    $('#content').val(html);
    

    【讨论】:

    • Robert - 回答您的一些问题:变量 html 被附加到现有的
      元素中,该元素是由我们正在使用的某些 CMS 应用程序动态生成的。这就是为什么我必须在渲染完所有 DOM 后将它附加到其他元素。至于实际的 html 字符串,它通过 $("#contentStr").val(htmlStr); 分配给输入字段
    猜你喜欢
    • 2019-06-15
    • 2021-10-16
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 2019-09-30
    • 1970-01-01
    • 2023-01-24
    相关资源
    最近更新 更多