设计Web API的官方MS或最佳体系结构实践是什么?它采用复杂类型并返回复杂类型?接受复杂类型并返回复杂类型的Web API?
难度: 传递复杂类型通过HTTP没有参考到中央数据类型,同时保持RESTful的。
目前: 我成功地这样做,但我的老板介绍最佳做法争论,如果我有正确的做到了这一点。微软声称你可以传入一个复杂的类型,就像一个[FromBody]属性的参数,但我没有任何运气(一个复杂类型的工作示例将会很棒)。
类型模型的知识: 客户端应用程序和Web API都必须包含类的中央库的引用。围绕这是使用WSDL来传递每个请求的类型信息,我的老板不喜欢这样,因为我们将有库DLL的不同汇编(从一个客户端应用程序到下),我可以看到的唯一途径(不理想在远程位置移动,因此REST),任何建议。
目前代码(工作):
控制器调用API
[Authorize]
public async Task<ActionResult> Index()
{
InstallerPinModel currentInstaller = new InstallerPinModel();
currentInstaller.userName = "from Controller";
Task<WebResponse> response = checkPinTime(currentInstaller);//checkPinTime calls API
//I found the following two lines are very helpful for debugging
//while(response.IsCompleted == false)
//Thread.Sleep(100);
Stream responseResultsStream = response.Result.GetResponseStream();
int responseResultContentLength = (int)response.Result.ContentLength;
byte[] responseResultContentAsBytes = new byte[responseResultContentLength];
responseResultsStream.Read(responseResultContentAsBytes, 0, responseResultContentLength);//Pull Data Stream into Byte[] responseResultContentAsBytes
string responseResultsAsString = System.Text.Encoding.UTF8.GetString(responseResultContentAsBytes);
JavaScriptSerializer serializesJS = new JavaScriptSerializer();
currentInstaller = serializesJS.Deserialize<InstallerPinModel>(responseResultsAsString);
if(currentInstaller.userName == "from API")
returnView = GoalView;
else
returnView = TimedOutView;
}
return View();
}
public Task<WebResponse> checkPinTime(InstallerPinModel incomingUser)//Function to call Post Web API
{
string requestData = new JavaScriptSerializer().Serialize(incomingUser);//Just slightly different syntax
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] requestDataAsBytes = encoding.GetBytes(requestData);
WebRequest request = WebRequest.Create("http://localhost:51366/api/InstallerPin");
request.Method = "POST";
request.ContentLength = requestDataAsBytes.Length;
request.ContentType = "application/x-www-form-urlencoded";
Stream requestDataStream = request.GetRequestStream();
requestDataStream.Write(requestDataAsBytes, 0, requestDataAsBytes.Length);
requestDataStream.Close();
Task<WebResponse> response = request.GetResponseAsync();
return response;
}
的Web API
public async Task<HttpResponseMessage> Post()
{
//ReadIncoming
InstallerPinModel incomingInstallerPIN = new InstallerPinModel();
Task<byte[]> requestContentByteArray = Request.Content.ReadAsByteArrayAsync();
ASCIIEncoding encoding = new ASCIIEncoding();
string requestContentAsString = encoding.GetString(await requestContentByteArray);
JavaScriptSerializer serializesJS = new JavaScriptSerializer();
incomingInstallerPIN = serializesJS.Deserialize<InstallerPinModel>(requestContentAsString);
//This is where the post would take place
//Send Responspe Object
InstallerPinModel outgoingInstallerPIN = new InstallerPinModel();
outgoingInstallerPIN = incomingInstallerPIN;
outgoingInstallerPIN.userName = "from API";
//BuildOutgoing
string responseAsString = serializesJS.Serialize(outgoingInstallerPIN);
StringContent responseContent = new StringContent(responseAsString);
await responseContent.LoadIntoBufferAsync();
HttpResponseMessage returnableResponseMessage = new HttpResponseMessage();
returnableResponseMessage.Content = responseContent;
return returnableResponseMessage;
}
路由
config.Routes.MapHttpRoute(
name: "noParamsInURL",
routeTemplate: "api/{controller}",
defaults: new { }
);//Route for InstallerPinController
//(Default) Route for standard API Controllers
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{application}",
defaults: new { id = RouteParameter.Optional, application = RouteParameter.Optional });
类型型号
public class InstallerPinModel
{
public string userName {get; set;}
public int pin {get; set;}
public int newPin { get; set; }
}
请确保在API和客户端应用程序中都包含对类型模型的引用。