/// <summary> /// Erstellen eines einfachen HREF Links für window.location.href /// </summary> public string BuildHrefLink(ProxyMethodInfos methodInfo, ProxyBuilder proxyBuilder) { //z.B.: window.location.href = window.siteRoot + 'Auftragsabrechnung/ExportData' + '?allEntries=' + encodeURIComponent(allEntries) + '&' + jQuery.param($scope.FilterData); //Wir bauen hier aber nur den Link Teil zusammen: 'Auftragsabrechnung/ExportData' + '?allEntries=' + encodeURIComponent(allEntries) + '&' + jQuery.param($scope.FilterData); StringBuilder builder = new StringBuilder(); builder.Append(string.Format("'{0}/{1}'", ProxyBuilderHelper.GetClearControllerName(methodInfo.Controller), methodInfo.MethodInfo.Name)); builder.Append(ProxyBuilderHelper.BuildUrlParameterId(methodInfo.ProxyMethodParameterInfos)); //Da wir die Komplexen Parameter nicht als Post mit übergeben können bei einem Link, müssen wird diese entsprechend in Url Parametern abbilden. builder.Append(ProxyBuilderHelper.BuildComplexUrlParameter(methodInfo.ProxyMethodParameterInfos)); return builder.ToString(); }
public void BuildGet_NoComplexType_WithId() { //Arrange var methodInfos = new ProxyMethodInfos(); //Die MethodenInfos laden - können wir nicht Mocken! methodInfos.MethodInfo = TestClassType.GetMethod("OneParam"); methodInfos.ProxyMethodParameterInfos.Add(new ProxyMethodParameterInfo() { IsComplexeType = false, ParameterName = "id"}); //Mocken der passenden Infos MockBuildHelper.Setup(p => p.GetClearControllerName(It.IsAny<Type>())).Returns("Home"); MockBuildHelper.Setup(p => p.BuildUrlParameterId(It.IsAny<List<ProxyMethodParameterInfo>>())).Returns(" + '/' + id "); MockBuildHelper.Setup(p => p.BuildUrlParameter(It.IsAny<List<ProxyMethodParameterInfo>>())).Returns(" + '?name='+encodeURIComponent(name)"); //Act var getParams = ProxyBuilderHttpCall.BuildHttpCall(methodInfos, ProxyBuilder.AngularJavaScript); //Assert Assert.AreEqual(getParams, "get('Home/OneParam' + '/' + id + '?name='+encodeURIComponent(name))"); }
/// <summary> /// Laden der Methodeninformationen für die übergebene Klasse (Controller) /// </summary> public List<ProxyMethodInfos> LoadMethodInfos(Type controller, Type proxyTypeAttribute) { List<ProxyMethodInfos> proxyMethodInfos = new List<ProxyMethodInfos>(); //Alle Methoden des Controllers durchgehen und nur die Methoden ermitteln in denen auch das übergebene ProxyAttribut enthalten ist. foreach (MethodInfo methodInfo in controller.GetMethods().Where(p => p.GetCustomAttributes(true).Any(attr => attr.GetType() == proxyTypeAttribute))) { if (proxyMethodInfos.Any(p => p.MethodInfo.Name == methodInfo.Name)) { throw new Exception(string.Format("ERROR, JavaScript doesn't supports function/method overload, please rename one of those functions/methods '{0}'", methodInfo.Name)); } ProxyMethodInfos proxyMethodInfo = new ProxyMethodInfos(); //Laden der Paramterinformationen zu unserer Methode. proxyMethodInfo.ProxyMethodParameterInfos = Factory.CreateMethodParameterManager().LoadParameterInfos(methodInfo); proxyMethodInfo.MethodInfo = methodInfo; proxyMethodInfo.Controller = controller; proxyMethodInfo.ReturnType = GetProxyReturnType(methodInfo); proxyMethodInfo.CreateWindowLocationHrefLink = GetCreateWindowLocationHrefLink(methodInfo); //Wenn ein Href Link erstellt werden soll, dann kann es keinen ReturnType geben! if (proxyMethodInfo.CreateWindowLocationHrefLink) { proxyMethodInfo.ReturnType = null; } if (methodInfo.DeclaringType != null) { proxyMethodInfo.Namespace = methodInfo.DeclaringType.FullName; proxyMethodInfo.MethodNameWithNamespace = string.Format("{0}.{1}", proxyMethodInfo.Namespace, methodInfo.Name); } proxyMethodInfos.Add(proxyMethodInfo); } return proxyMethodInfos; }
/// <summary> /// Den passenden HttpCall zusammenbauen und prüfen ob Post oder Get verwendet werden soll /// Erstellt wird: post("/Home/LoadAll", data) oder get("/Home/LoadAll?userId=" + id) /// </summary> public string BuildHttpCall(ProxyMethodInfos methodInfo, ProxyBuilder proxyBuilder) { //Wie genau das Post oder Geht aussieht, hängt von den gewünschten Parametern ab. //Aktuell gehen wir von einer StandardRoute aus und wenn ein "id" in den Parametern ist, dann //Handelt es sich z.B. um den Letzten Parameter in der StandardRoute. //Beispiele: //.post("/Home/GetAutosByHerstellerId/" + id, message) //.post("/ControllerName/GetAutosByHerstellerId/", message) //get("/Home/GetSuccessMessage") //get("/Home/GetSuccessMessage/" + id + "?name=" + urlencodestring + "&test=2") //Prüfen ob ein complexer Typ verwendet wird. if (methodInfo.ProxyMethodParameterInfos.Count(p => p.IsComplexeType) == 0) { //Wenn über der Controller Action Post angegeben wurde, dann auch Post verwenden //obwohl kein komplexer Typ enthalten ist. if (ProxyBuilderHelper.HasAttribute(typeof(HttpPostAttribute), methodInfo.MethodInfo)) { if (proxyBuilder == ProxyBuilder.jQueryTypeScript || proxyBuilder == ProxyBuilder.jQueryJavaScript) { return BuildPostjQuery(methodInfo); } return BuildPostAngular(methodInfo, proxyBuilder); } //Kein Komplexer Typ also Get verwenden. return BuildGet(methodInfo); } if (proxyBuilder == ProxyBuilder.jQueryTypeScript || proxyBuilder == ProxyBuilder.jQueryJavaScript) { return BuildPostjQuery(methodInfo); } return BuildPostAngular(methodInfo, proxyBuilder); }
/// <summary> /// Das passende HREF Template laden und die passenden TemplateString ersetzten. /// </summary> private string BuildHrefTemplate(ProxyMethodInfos methodInfos, ProxyControllerInfo controllerInfo, string suffix) { var functionTemplate = Factory.GetProxySettings().Templates.First(p => p.TemplateType == TemplateTypes.AngularJsWindowLocationHref).Template; //Den Methodennamen ersetzen - Der Servicename der aufgerufen werden soll. string functionCall = functionTemplate.Replace(ConstValuesTemplates.ControllerFunctionName, ProxyBuilderHelper.GetProxyFunctionName(methodInfos.MethodInfo.Name)); //Parameter des Funktionsaufrufs ersetzen. functionCall = functionCall.Replace(ConstValuesTemplates.ServiceParamters, ProxyBuilderHelper.GetFunctionParameters(methodInfos.MethodInfo)); //Href Call zusammenbauen und Parameter ersetzen functionCall = functionCall.Replace(ConstValuesTemplates.ServiceCallAndParameters, ProxyBuilderHttpCall.BuildHrefLink(methodInfos, ProxyBuilder.AngularJavaScript)); //Den Servicenamen vor dem Prototype ersetzen. functionCall = functionCall.Replace(ConstValuesTemplates.ServiceName, ProxyBuilderHelper.GetServiceName(controllerInfo.ControllerNameWithoutSuffix, suffix, Factory.GetProxySettings().LowerFirstCharInFunctionName)); return functionCall; }
/// <summary> /// Rückgabe für Post erstellen für jQuery Calls /// </summary> /// <returns>Gibt den passenden POST Aufruf zurück</returns> private string BuildPostjQuery(ProxyMethodInfos infos) { StringBuilder builder = new StringBuilder(); builder.Append(string.Format("ajax( {{ url : '{0}/{1}'", ProxyBuilderHelper.GetClearControllerName(infos.Controller), infos.MethodInfo.Name)); builder.Append(ProxyBuilderHelper.BuildUrlParameterId(infos.ProxyMethodParameterInfos)); builder.Append(ProxyBuilderHelper.BuildUrlParameter(infos.ProxyMethodParameterInfos)); //Da auch ein Post ohne komplexen Typ aufgerufen werden kann über das "HttpPost" Attribut hier prüfen //ob ein komplexer Typ enthalten ist. if (infos.ProxyMethodParameterInfos.Any(p => p.IsComplexeType)) { //Da es nur einen Complexen Typ geben darf pro Methodenaufruf, hier prüfen ob ein FileUpload dabei ist. if (infos.ProxyMethodParameterInfos.Any(p => p.IsFileUpload)) { //Achtung die "formData" Variable wird bei "#FunctionContent#" eingefügt builder.Append(", data : formData, processData : false, contentType: false, type : \"POST\" })"); } else { //Standard Post builder.Append(string.Format(", data : JSON.stringify({0}), type : \"POST\", contentType: \"application/json; charset=utf-8\" }})", infos.ProxyMethodParameterInfos.First(p => p.IsComplexeType).ParameterName)); } } else { builder.Append("})"); } return builder.ToString(); }
/// <summary> /// Rückgabe für Post erstellen für Angular Calls /// </summary> /// <returns>Gibt den passenden POST Aufruf zurück</returns> private string BuildPostAngular(ProxyMethodInfos infos, ProxyBuilder proxyBuilder) { StringBuilder builder = new StringBuilder(); builder.Append(string.Format("post('{0}/{1}'", ProxyBuilderHelper.GetClearControllerName(infos.Controller), infos.MethodInfo.Name)); builder.Append(ProxyBuilderHelper.BuildUrlParameterId(infos.ProxyMethodParameterInfos)); builder.Append(ProxyBuilderHelper.BuildUrlParameter(infos.ProxyMethodParameterInfos)); //Da auch ein Post ohne komplexen Typ aufgerufen werden kann über das "HttpPost" Attribut hier prüfen //ob ein komplexer Typ enthalten ist. if (infos.ProxyMethodParameterInfos.Any(p => p.IsComplexeType)) { //Da es nur einen Complexen Typ geben darf pro Methodenaufruf, hier prüfen ob ein FileUpload dabei ist. if (infos.ProxyMethodParameterInfos.Any(p => p.IsFileUpload)) { if (proxyBuilder != ProxyBuilder.Angular2TypeScript) { //Achtung die "formData" Variable wird bei "#FunctionContent#" eingefügt builder.Append(",formData, { transformRequest: angular.identity, headers: { 'Content-Type': undefined }})"); } else { //für angular 2 muss hier nur FormData übergeben werden. builder.Append(",formData)"); } } else { //Standard Post builder.Append(string.Format(",{0})", infos.ProxyMethodParameterInfos.First(p => p.IsComplexeType).ParameterName)); } } else { builder.Append(")"); } return builder.ToString(); }
/// <summary> /// Rückgabe für Get erstellen /// </summary> /// <returns>Gibt den passenden GET Aufruf in JavaScript zurück</returns> private string BuildGet(ProxyMethodInfos infos) { StringBuilder builder = new StringBuilder(); //Keine Komplexen Typen, einfacher Get Aufruf. builder.Append(string.Format("get('{0}/{1}'", ProxyBuilderHelper.GetClearControllerName(infos.Controller), infos.MethodInfo.Name)); builder.Append(ProxyBuilderHelper.BuildUrlParameterId(infos.ProxyMethodParameterInfos)); builder.Append(ProxyBuilderHelper.BuildUrlParameter(infos.ProxyMethodParameterInfos)); builder.Append(")"); return builder.ToString(); }
public void BuildPost_IsComplexeType_False() { //Arrange var methodInfos = new ProxyMethodInfos(); //Die MethodenInfos laden - können wir nicht Mocken! methodInfos.MethodInfo = TestClassType.GetMethod("OneComplexParamHttpPost"); methodInfos.ProxyMethodParameterInfos.Add(new ProxyMethodParameterInfo() { IsComplexeType = false, ParameterName = "person" }); //Mocken der passenden Infos MockBuildHelper.Setup(p => p.GetClearControllerName(It.IsAny<Type>())).Returns("Home"); MockBuildHelper.Setup(p => p.BuildUrlParameterId(It.IsAny<List<ProxyMethodParameterInfo>>())).Returns(String.Empty); MockBuildHelper.Setup(p => p.BuildUrlParameter(It.IsAny<List<ProxyMethodParameterInfo>>())).Returns(" + '?name='+encodeURIComponent(name)"); MockBuildHelper.Setup(p => p.HasAttribute(It.IsAny<Type>(), It.IsAny<MethodInfo>())).Returns(true); //Act var getParams = ProxyBuilderHttpCall.BuildHttpCall(methodInfos, ProxyBuilder.AngularTypeScript); //Assert Assert.AreEqual(getParams, "post('Home/OneComplexParamHttpPost' + '?name='+encodeURIComponent(name))"); }
/// <summary> /// Prüft ob ein FileUpload Parameter enthalten ist und wenn ja werden die passenden Formdaten erstellt /// Falls nicht wird einfach ein Leerstring zurückgegeben. /// </summary> public string GetFileUploadFormData(ProxyMethodInfos methodInfo) { if (methodInfo.ProxyMethodParameterInfos.Any(p => p.IsFileUpload)) { var fileUploadParamName = methodInfo.ProxyMethodParameterInfos.First(p => p.IsFileUpload).ParameterName; string formData = string.Format("var formData = new FormData(); \r\n formData.append('{0}', {0}); \r\n", fileUploadParamName); return formData; } return String.Empty; }
/// <summary> /// Das passende HREF Template laden und die passenden TemplateString ersetzten. /// </summary> private string BuildHrefTemplate(ProxyMethodInfos methodInfos) { var functionTemplate = Factory.GetProxySettings().Templates.First(p => p.TemplateType == TemplateTypes.Angular2TsWindowLocationHref).Template; //Den Methodennamen ersetzen - Der Servicename der aufgerufen werden soll. string functionCall = functionTemplate.Replace(ConstValuesTemplates.ControllerFunctionName, ProxyBuilderHelper.GetProxyFunctionName(methodInfos.MethodInfo.Name)); //Parameter des Funktionsaufrufs ersetzen. functionCall = functionCall.Replace(ConstValuesTemplates.ServiceParamters, ProxyBuilderTypeHelper.GetFunctionParametersWithType(methodInfos.MethodInfo)); //Href Call zusammenbauen und Parameter ersetzen functionCall = functionCall.Replace(ConstValuesTemplates.ServiceCallAndParameters, ProxyBuilderHttpCall.BuildHrefLink(methodInfos, ProxyBuilder.Angular2TypeScript)); return functionCall; }