3

在我的代码中,我有一个基类 Foo 并且我的所有对象都继承自 Foo 对象。所以假设我有这样的课程

public class Bar : Foo {
    public string Heading { get;set; }
}

我尝试使用动态的 ApiControllers put 方法,但我收到此错误http://paste2.org/p/1914054

这是我在 ApiController 中使用的代码

public void Put(string id, dynamic model) {
    //do stuff
}

如果我使用普通控制器,我可以使用动态来发布数据。是否可以添加使 api 控制器与动态一起工作,或者我是否需要构建自己的模型绑定器?

看起来有些人认为即使在 MVC 3 中输入参数也不能是动态的,但事实并非如此,这就是我问这个问题的原因。MVC 3 中的这个控制器非常适合作为输入参数使用动态。

4

3 回答 3

3

嗯,我可以使用 ASP.NET Web API 方法做到这一点:

    public string Post(dynamic value)
    {
        string s = "";
        foreach (dynamic item in value)
        {
            s = s + item.content + " ";
        }
        return s;
    }

使用 JSON 数组:

POST http://localhost:6946/api/values HTTP/1.1
User-Agent: Fiddler
Host: localhost:6946
Content-Length: 327
Content-Type: application/json
[{"content":"Hello","editing":false},{"content":"sfsdf","editing":false},{"content":"sadsdfdsf","editing":false},{"content":"dfsdf","editing":false},{"content":"dsfsd","editing":false},{"content":"sdfsdf","editing":false},{"content":"dsf","editing":false},{"content":"dfg","editing":false},{"content":"fsdfsd","editing":false}]

它奏效了......

于 2012-04-19T23:35:19.760 回答
1

看起来有些人认为即使在 MVC 3 中输入参数也不能是动态的

我认同。让我们看一下提供的示例:

[HttpPost]
[ValidateInput(false)]
public virtual ActionResult Update(dynamic editorModel) {

    if (!TryUpdateModel(_model, "CurrentModel")) {
        var parentId = _model.Parent != null ? (string)_model.Parent.Id : null;
        var viewModel = new EditViewModel
        {
            RootModel = _session.Query<IPageModel>()
                .Where(model => model.Parent == null)
                .SingleOrDefault(),
            CurrentModel = _model,
            ParentModel = parentId != null ? _session.Load<IPageModel>(parentId) : null,
        };
        return View("edit", viewModel);
    }

    UpdateModel(_model);

    _model.Metadata.Changed = DateTime.Now;
    _model.Metadata.Published = _model.Metadata.IsPublished ? DateTime.Now : default(DateTime?);
    _model.Metadata.ChangedBy = HttpContext.User.Identity.Name;

    _repository.SaveChanges();
    _repository.Refresh(_model);

    var page = _model as IPageModel;

    if (page.Parent != null) {
        _model = _repository.SingleOrDefault<IPageModel>(m => m.Id == page.Parent.Id);
    }

    return RedirectToAction("index", new { model = _model });
}

你能指出我在这个控制器动作中如何/在哪里editorModel使用这个动态变量吗?

为了进一步简化这个控制器动作,它可以工作,因为它从不使用作为参数传递的动态变量。我已经对其进行了简化,以更好地说明此操作在模型绑定方面大致做了什么(当然,我们在这里不感兴趣的所有基础设施噪音都被丢弃以说明问题):

[HttpPost]
public ActionResult Update(dynamic blablabla)
{
    dynamic model = new MyViewModel();
    UpdateModel(model);
    // at this stage the model will be correctly bound

    return View(model);
}

在此操作中,在实例变量上调用TryUpdateModelUpdateModel方法,该_model实例变量在构造函数中传递并且类型为IPageModel。ASP.NET MVC 不可能知道(当然没有自定义模型绑定器)您的动态操作参数的类型。只需运行此代码,在操作中放置一个断点Update并观察editorModel变量的类型。它只是System.Object。没有奇迹。

所以对我来说,这在 ASP.NET Web API 中同样有效是完全正常的。

于 2012-02-25T09:29:47.690 回答
0

http://www.binaryintellect.net/articles/589f6915-f4c0-4bf9-9f94-4d00bd445c16.aspx

这个解决方案工作得很好。

我有一个 HTML 表单,其中所有的输入控件都是动态的。很难将表单数据连接到 MVC 控制器,然后再连接到 Web Api 2 控制器。

您的服务器端 web api 方法需要像

public string Post(FormDataCollection form){
... }

FormDataCollection 位于 System.Net.Http.Formatting 命名空间中。

如果您直接从网页 (jquery) 发送数据,那么上述链接解决方案可以正常工作。

如果您将数据网页发布到 MVC 页面(c# 代码),然后进一步发布到 web api 方法,则代码如下所示:

[HttpPost]
    public async Task<string> MasterDraw(FormCollection body)
    {
        HttpClient client = new HttpClient();
        KeyValuePair<string, string>[] list = null;
        string url = ConfigurationManager.AppSettings["BaseServiceUrl"] + "/api/MasterOperation/addrecord";

        if (body != null && body.HasKeys())
        {
            list = new KeyValuePair<string, string>[body.AllKeys.Count()];
            for (int ctr = 0; ctr < body.Keys.Count; ctr++ )
            {
                list[ctr] = new KeyValuePair<string, string>(body.Keys[ctr], body.GetValue(body.Keys[ctr]).AttemptedValue);
            }
        }

        var content = new FormUrlEncodedContent(list);

        HttpResponseMessage response = await client.PostAsync(url, content);

        // Check that response was successful or throw exception
        response.EnsureSuccessStatusCode();

        // Read response asynchronously as JToken and write out top facts for each country
        string contentRes = response.Content.ReadAsStringAsync().Result;

        return contentRes;
    }

浏览器端代码:

$('#btn-save').on('click', function (event) {
            var postUrl = "@Url.Action("masterdraw","masterrender")";

            var result = $.ajax({
                type: "POST",
                data: $('#form').serialize(),
                url: postUrl                    
            });

            // insert your jquery .done and .error methods

        });
于 2015-12-04T13:11:48.503 回答