2014-10-13 3 views
1

У меня есть страница, которая в настоящее время передает через Ajax метод контроллера. MVC автоматически преобразует данные запроса в мой тип модели View, и это здорово.Вручную построить модель представления из данных запроса

Теперь я пытаюсь изменить его, вместо сообщения 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()); 
+0

Я надеюсь, что вам не придется вручную десериализации модели с signalR. –

+0

Не могли бы вы разместить свой код модели? – Gjohn

+0

Это не кажется актуальным. Предположим, что у него есть обычные вещи, такие как 'int', даты, строки. Я надеюсь на универсальное решение, которое не потребует ничего знать о модели. – DLeh

ответ

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); 
Смежные вопросы