2

I am having trouble getting my custom controllers to behave properly in an Umbraco MVC site. I can't work out how to pass custom models and use custom ActionResults. When I try to send a form the method is not being called. So a method like this

public ActionResult Home(string username, string password)
{
    Debug.WriteLine("form");

    var company = new Company();
    return CurrentTemplate(company);
}

that should be called from a form like this but nothing happens.

@using (Html.BeginForm("Home","Login", FormMethod.Post, new {name = "logon"}))
{
    <label>User name </label><input type="text" id="username"/><br/>
    <label>Password </label><input type="password" id="password"/><br/>
    <input type="submit" value="Here"/>
}

I know it is possible to override the default controller but is there any point in doing so?

4

3 回答 3

2

旧帖子,但我想我会从我正在从事的当前项目中添加我的发现。

对于帖子,正如您在表单中所指的那样,正如@Digbyswift 所说,大多数情况下您都需要 SurfaceController 。

但是-这是我遇到最大麻烦的地方。我有一个发布到另一个页面的表单,该页面显示结果,然后在视图上显示该数据。我想摆脱使用query strings和放入数据session等,因为我们正在使用MVC. 这也允许我返回一个也使用过的自定义视图,CurrentPage您需要将其RenderModel作为model. 我们需要设置一些东西:

1) 创建您的控制器、视图和文档类型。在这种情况下,我与“成员”打交道,所以我创建了一个Member文档类型MemberController,等等。

2) 在发布到表单的视图上:

        <form method="post" action="member">
            <div class="form-group">
                <input type="text" id="query" name="query" class="form-control" placeholder="Member Company or State" />
            </div>
            <input type="submit" value="Search" class="button button-green" />
        </form>

您还可以在继承自该类的类中定义自定义路由ApplicationEventHandler并在事件中注册该路由ApplicationStarted,但这样我们将只覆盖该Index操作。

3)在控制器上,MemberController

public class MemberController : RenderMvcController
{
     [EnsurePublishedContentRequest(2303)]  // 2303 is your node ID
     public ActionResult Index(string query)
     {
         // your code - assign to ViewBag

         return View("~/Views/Member.cshtml", this.CreateRenderModel(Umbraco.TypedContent(2303)));
     }
}

private RenderModel CreateRenderModel(IPublishedContent content)
{
    var model = new RenderModel(content, CultureInfo.CurrentUICulture);

    //add an umbraco data token so the umbraco view engine executes
    RouteData.DataTokens["umbraco-doc-request"] = model;

    return model;
}

如果您没有任何需要渲染的内容,则不必这样做。macros在我的情况下,我有这个继承了_layout的视图。

Umbraco 中的自定义 MVC 路由

我们必须在这里做(2)件事。一是确保我们得到PublishedContentRequest.

第二部分是获取RenderModel对象。我阅读了很多文章,其中您的基本模型应该继承自RenderModel,并添加了一些默认的 Umbraco 构造函数,但我对此并不十分幸运。

希望这可以帮助某人。

于 2015-02-09T23:00:26.297 回答
1

在 Umbraco 中,每个请求都通过 路由,Umbraco.Web.Mvc.RenderMvcController但您可以覆盖它,文档在此处

但是,我建议如果您觉得需要这样做,那么您的实现可能过于复杂。您仍然可以使用您的方法来呈现 ChildActions,它可以被赋予一个独立于 Umbraco 页面模型的模型。见这里。这对于渲染分页搜索结果、文档列表和您希望能够在控制器中控制的内容非常有用。我经常使用这种方法,但总是尝试传回以IPublishedContent界面为中心的模型(例如IEnumerable<IPublishedContent>,用于页面列表),这样在视图中,您仍然可以从视图访问 Umbraco 内容和 API,而不必在模型中实现太多自己的属性。

在发布表单时,它有点棘手,因为您有两个选择:

  1. 正如 Dan Diplo 所说,您可以使用该Html.BeginUmbracoForm()方法;或者
  2. 您可以以标准 MVC 方式回发到[HttpPost]操作,即Html.BeginForm().

(2) 的挑战在于,因为所有请求都通过了Umbraco.Web.Mvc.RenderMvcController,所以您无法告诉表单要发布到哪个页面。您只能发布到自身或非 Umbraco 控制的操作。例如,您可以让表单回传到同一页面,并有第二个 ChildAction 专门用于[HttpPost]. 这样做的问题是它会捕获所有帖子,而不管发布的表格是什么。

就个人而言,我在大多数需要直接与 Umbraco 交互的标准形式中使用方法 (1),例如查询、上传等,当我需要更多控制时我使用方法 (2)。但这通常需要更多的思考。

于 2013-07-03T08:43:22.493 回答
1

你真的是说你想要一个自定义控制器,还是你真的只是想在 Umbraco 中使用 MVC 创建一个表单?如果是后者,那么您需要使用表面控制器,即。确保您的控制器继承自Umbraco.Web.Mvc.SurfaceController并具有后缀“SurfaceController”。

public class MySurfaceController : Umbraco.Web.Mvc.SurfaceController
{
    public ActionResult Index() 
    {
        return Content("hello world");
    }
}

然后您需要使用自定义 Umbraco Html 帮助器来创建您的表单标签:

@using(Html.BeginUmbracoForm("CreateComment", "BlogPostSurface"))
{
 //
}

请参阅http://our.umbraco.org/documentation/Reference/Mvc/forms

于 2013-07-02T21:52:42.593 回答