asp.net - QueryString 参数如何绑定(bind)到 Action 方法参数?

标签 asp.net asp.net-mvc c1-cms

我有一个 webforms 项目,正在尝试运行一些代码,允许我调用 MVC 路由,然后在 web 表单页面的正文中呈现结果。

我使用几个 HttpResponse/Request/Context 包装器来执行对 MVC 路由的调用,例如:

private static string RenderInternal(string path)
{
  var responseWriter = new StringWriter();

  var mvcResponse = new MvcPlayerHttpResponseWrapper(responseWriter, PageRenderer.CurrentPageId);
  var mvcRequest = new MvcPlayerHttpRequestWrapper(Request, path);
  var mvcContext = new MvcPlayerHttpContextWrapper(Context, mvcResponse, mvcRequest);

  lock (HttpContext.Current)
  {
    new MvcHttpHandlerWrapper().PublicProcessRequest(mvcContext);
  }

  ...

该代码适用于执行简单的 MVC 路由,例如“/首页/索引”。但是我不能指定任何查询字符串参数(例如“/Home/Index?foo=bar”),因为它们只是被忽略了。我试图直接在 RequestWrapper 实例中设置 QueryString,如下所示:
public class MvcPlayerHttpRequestWrapper : HttpRequestWrapper
{
  private readonly string _path;
  private readonly NameValueCollection query = new NameValueCollection();

  public MvcPlayerHttpRequestWrapper(HttpRequest httpRequest, string path)
    : base(httpRequest)
  {
    var parts = path.Split('?');

    if (parts.Length > 1)
    {
      query = ExtractQueryString(parts[1]);
    }

    _path = parts[0];
  }

  public override string Path
  {
    get
    {
      return _path;
    }
  }

  public override NameValueCollection QueryString
  {
    get
    {
      return query;
    }
  }

  ...

调试时,我可以看到正确的值在“request.QueryString”中,但这些值永远不会绑定(bind)到方法参数。

有谁知道如何使用 QueryString 值并将其从 http 请求绑定(bind)到 MVC Controller 操作?

QueryString 值的处理似乎比我预期的要复杂。我对 MVC 请求管道的内部了解有限。

我一直在尝试自己研究内部结构,并将继续这样做。如果我发现任何东西,我会适本地更新这篇文章。

我还创建了一个非常简单的 Web 表单项目,其中仅包含产生此问题所需的代码,并通过 Dropbox 共享它:https://www.dropbox.com/s/vi6erzw24813zq1/StackMvcGetQuestion.zip
该项目只包含一个 Default.aspx 页面、一个 Controller 和用于呈现 MVC 路径结果的 MvcWrapper 类。如果您查看 Default.aspx.cs,您将看到一个包含查询字符串参数的路由路径被传入,但它永远不会绑定(bind)到操作上的参数。

作为快速引用,以下是该 Web 项目的一些摘录。

Controller :
public class HomeController : Controller
{
  public ActionResult Index(string foo)
  {
    return Content(string.Format("<p>foo = {0}</p>", foo));
  }
}

Default.aspx 页面:
protected void Page_Load(object sender, EventArgs e)
{
  string path = "/Home/Index?foo=baz";

  divMvcOutput.InnerHtml = MvcWrapper.MvcPlayerFunctions.Render(path);
}

我已经为此苦苦挣扎了很长一段时间,因此不胜感激任何形式的建议。 :)

最佳答案

MVC 框架将尝试从查询字符串(以及其他可用数据,如发布的表单字段等)中填充操作方法的参数值,这部分你做对了。您错过的部分是它通过将参数名称与传入的值名称匹配来实现。因此,如果您在 Controller MyController 中有一个带有签名的 MyMethod 方法:

public ActionResult MyMethod(string Path)
{
    //Some code goes here
}

查询字符串(或其他变量来源之一)必须包含一个名为“Path”的变量,以便框架能够检测到它。查询字符串应该是/MyController/MyMethod?Path=Baz

关于asp.net - QueryString 参数如何绑定(bind)到 Action 方法参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16667901/

相关文章:

asp.net - MVC 6 asp-validation-summary 省略属性名称以验证隐藏输入

javascript - 获取子属性包含值的对象

javascript - MVC 等效于通过 javascript 的 @Html.ActionLink

webdeploy - Composite C1 - 在本地开发,同步到实时站点

c1-cms - 在 Composite C1 中使用非严格 XHTML 的 .cshtml 页面

content-management-system - 从 Common Composite C1 CMS 运行多个站点

ASP.Net UpdatePanel 导致 Dojo 按钮丢失 Dojo 属性

asp.net - Google map 上的多个标记

asp.net - 在ASP.NET MVC项目中启用错误页面时查看未找到的错误

c# - Html.CheckBoxFor 所需的复选框验证工作相反