Какая официальная MS или лучшая архитектура для проектирования веб-API, который принимает сложный тип и возвращает сложный тип?Веб-API, который принимает сложный тип и возвращает сложный тип?
Сложность: Передача сложных типов по HTTP без ссылки на центральный тип данных во время пребывания RESTful.
В настоящее время: Я делаю это успешно, но спорю с моим начальником о лучшей практике, и если я сделал это правильно. Microsoft утверждает, что вы можете передать сложный тип, как параметр с атрибутом [FromBody], но мне не повезло с этим (рабочий пример со сложным типом был бы замечательным).
Тип Знание модели: Клиентское приложение и веб-API имеют ссылку на центральную библиотеку, содержащую класс. Моему боссу это не нравится, так как у нас будут разные компиляции библиотеки DLL (от одного клиентского приложения к следующему), единственный способ, которым я могу это видеть, - использовать WSDL для передачи информации о типе по каждому запросу (не идеально для мобильных устройств в удаленных местах, следовательно, 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;
}
Routing
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, так и в приложении для клиентов.