从请求数据手动构建视图模型

时间:2014-10-13 20:25:18

标签: ajax asp.net-mvc signalr

我有一个页面,目前通过Ajax提交给控制器方法。 MVC会自动将请求数据转换为我的View Model类型,这很棒。

现在我正在尝试更改它而不是Ajax帖子,而是进行SignalR调用。我想通过SignalR(通过$('form').serialize())提交相同的数据,然后将数据解析为我的视图模型类型。

示例:

//controller
public ActionResult MyMethod(MyViewModel vm){
     //vm is automatically created from form data
}

//SignalR Hub
public void MyMethodViaSignalR(string formData){
    //how can I turn formData or Context.Request into a MyViewModel?
}

//Make the SignalR call
myHub($('form').serialize());

1 个答案:

答案 0 :(得分:0)

我找到了一个通用解决方案。我将此代码放在我的基本控制器中(您可以将其复制到任何一个控制器),它将构建您需要的任何视图模型。

    protected class SignalRRequestJSon
    {
        public string H { get; set; }
        public string M { get; set; }
        public List<string> A { get; set; }
        public int I { get; set; }
    }
    public T GetModel<T>(HttpRequest req) where T : class, new()
    {
        var obj = JsonConvert.DeserializeObject<SignalRRequestJSon>(req["data"]);
        var stringWriter = new System.IO.StringWriter();
        var httpResponse = new HttpResponse(stringWriter);

        var url = req.UrlReferrer.ToString(); // this value doesn't matter, but needs to be a valid url.
        var queryStringData = obj.A[0];
        var httpRequest = new HttpRequest("", url, queryStringData);
        var httpContext = new HttpContext(httpRequest, httpResponse);

        var routeData = new RouteData();
        routeData.Values.Add("controller", this.GetType().Name.ToLower().Replace("controller", ""));
        routeData.Values.Add("action", "Arbitrary");

        this.ControllerContext = new ControllerContext(new HttpContextWrapper(httpContext), routeData, this);
        var valueProvider = new QueryStringValueProvider(this.ControllerContext);
        this.ValueProvider = valueProvider;

        var vm = new T();
        UpdateModel(vm, valueProvider);
        return vm;
    }
    public ActionResult Arbitrary<T>(T model)
    {
        return View();
    }

从我的SignalR中心这样调用:

var controller = DependencyResolver.Current.GetService<MyController>();
var vm = controller.GetModel<MyViewModel>(HttpContext.Current.Request);