有几个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"。但是我无法指定任何查询字符串参数(例如"/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”中,但是这些值从未绑定到方法参数。
有人知道如何从http请求将QueryString值用于绑定MVC控制器操作吗?
似乎处理QueryString值比我预期的要复杂。我对MVC请求管道的内部了解有限。
我一直在尝试研究内部情况,并将继续这样做。如果我找到任何信息,我会适当地更新此帖子。
我还创建了一个非常简单的Web表单项目,仅包含生成此问题所需的代码,并通过Dropbox共享:https://www.dropbox.com/s/vi6erzw24813zq1/StackMvcGetQuestion.zip 该项目只包含一个Default.aspx页面、一个Controller以及用于呈现MVC路径结果的MvcWrapper类。如果您查看Default.aspx.cs,您将看到传入了一个包含查询字符串参数的路由路径,但它从未绑定到操作上的参数。
以下是该Web项目的一些摘录:
控制器:
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);
}
我已经苦苦挣扎了相当一段时间,因此希望能得到任何形式的建议。