MVC控制器将整个模型发布到远程api操作

本文关键字:api 操作 控制器 模型 MVC | 更新日期: 2023-09-27 18:29:11

我有一个API,我想从我的前端MVC站点调用它。这两个应用程序在同一网络上的不同服务器上运行。

API控制器的功能类似于:

[AllowCrossSiteJson]
public class VerifyMyModelController : ApiController
{
    [HttpPost]
    public MyResponse Post(MyModel model)
    {
        return MyHelper.VerifyMyModel(model);
    }
    [HttpPost]
    public async Task<MyResponse> PostAsync(MyModel model)
    {
        return await MyHelper.VerifyMyModel(model);
    }
// ... Gets below as well
}

其中MyHelper执行模型验证、数据库查找等…并返回一个带有响应代码、数据库id等的公共响应对象

我的前端MVC站点有一个用户填写的表单,这些数据被发布到本地控制器,我想将其转发到API。API应用程序对公众是不可访问的,所以我不能使用AJAX等直接发布到它。它必须来自网站控制器。

我尝试了以下操作,但得到了一个500 internal server error作为响应

[HttpPost]
public async Task<MyResponse> VerifyAsync(MyModel model)
{
    var MyServer = ConfigurationManager.AppSettings["MyServer"];
    var json = Newtonsoft.Json.JsonConvert.SerializeObject(model);
    var requestUri = string.Format(@"http://{0}/api/VerifyMyModel/", MyServer);
    using (var c = new HttpClient())
    {
        var response = await c.PostAsJsonAsync(requestUri, json);
    }
    ...
}

CCD_ 3包含错误消息响应500。

我还尝试过使用一个查询字符串:

public string GetQueryString(object obj)
{
    var properties = from p in obj.GetType().GetProperties()
                        where p.GetValue(obj, null) != null
                        select p.Name + "=" + HttpUtility.UrlEncode(p.GetValue(obj, null).ToString());
    return String.Join("&", properties.ToArray());
}
[HttpPost]
public async Task<MyResponse> VerifyAsync(MyModel model)
{
    var MyServer = ConfigurationManager.AppSettings["MyServer"];
    string queryString = GetQueryString(model);
    var requestUri = string.Format(@"http://{0}/api/VerifyMyModel/?{1}", MyServer, queryString);
    using (var c = new HttpClient()){
        var response = await c.GetAsync(requestUri); // API Also has GET methods
    }
}

但是querystring方法返回405 method not allowed响应。

MyModel是具有公共模型的共享类库的一部分,并且包含在两个应用程序中。

有没有更好的方法将整个模型发布到远程api操作?

谢谢。

*编辑

API路由配置:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

我将以下内容添加到API MVC站点的HomeController中,对其进行测试,并收到预期的结果,没有错误:

public async Task<ActionResult> TestVerifyMyModel(MyModel model)
{
        var api = new VerifyMyModelController();
        var res = await api.PostAsync(model);
        return Json(res, JsonRequestBehavior.AllowGet);
}

所以我知道控制器的PostAsync动作是有效的。。远程呼叫时我无法让它工作。

我还在服务器上启用了Failed Request Tracing,并上传了生成的XML文件。这对我来说没有任何意义,但我认为它可能会有所帮助。

MVC控制器将整个模型发布到远程api操作

发布的路由配置看起来更像MVC路由配置,而不是WebApi路由配置。但是,如果是Web Api配置,那么您不应该将ActionName添加到您的url中吗。

[HttpPost]
    public async Task<MyResponse> VerifyAsync(MyModel model)
    {
        var MyServer = ConfigurationManager.AppSettings["MyServer"];
        var json = Newtonsoft.Json.JsonConvert.SerializeObject(model);
        var requestUri = string.Format(@"http://{0}/api/VerifyMyModel/PostAsync", MyServer);
        using (var c = new HttpClient())
        {
            var response = await c.PostAsJsonAsync(requestUri, json);
        }
        ...
    }

更新:从HttpClient响应检索模型的示例代码

using (var client = new HttpClient())
{
    client.BaseAddress = new Uri(ConfigurationManager.AppSettings["MyServer"]);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    HttpResponseMessage response = await client.GetAsync("api/VerifyMyModel/PostAsync");
    if (response.IsSuccessStatusCode)
    {
        var myResponseModel = await response.Content.ReadAsAsync<MyResponseModel>();
    }
}