标签: model-binding

ModelMetaData,自定义类属性和难以形容的问题

我想做的事情似乎很简单.

在我的index.cshtml中,我想显示WizardStepAttributeValue

因此,用户将在每个页面的顶部看到 Step 1: Enter User Information


我有一个名为的ViewModel WizardViewModel.这个ViewModel有一个属性IList<IStepViewModel> Steps

每个"步骤"实现接口IStepViewModel,这是一个空接口.

我有一个名为Index.cshtml的视图.此视图显示EditorFor()当前步骤.

我有一个自定义的ModelBinder,它将View绑定到IStepViewModel基于该WizardViewModel.CurrentStepIndex属性实现的具体类的新实例

我创建了一个自定义属性WizardStepAttribute.

我的每个步骤类都是这样定义的.

[WizardStepAttribute(Name="Enter User Information")] 
[Serializable]
public class Step1 : IStepViewModel
....
Run Code Online (Sandbox Code Playgroud)

我有几个问题.

我的视图是强类型的,WizardViewModel不是每一步.我不想为每个具体实现创建一个视图IStepViewModel

我以为我可以在界面中添加属性,但是我必须在每个类中明确地实现它.(所以这不是更好)

我想我可以在界面中使用反射来实现它,但是,你不能在接口中的方法中引用实例.

c# model-binding modelmetadata asp.net-mvc-3

6
推荐指数
1
解决办法
4719
查看次数

在.NET MVC中建模绑定Accept头的最简洁方法

我正在.NET MVC 3中实现REST层.我正在寻找一种干净的方法来获取Accept标头以确定我是否应该返回Json或Xml.

我也希望能够用一个GET参数来欺骗这个头来进行调试(我希望这也可以坚持生产).

这是我目前正在检测到的方式:

if (Request.AcceptTypes.Contains("application/json") || Request.Url.Query.Contains("application/json"))
Run Code Online (Sandbox Code Playgroud)

这是我的控制器代码中唯一直接触及Request对象的地方.我想要一种更清晰,更可测试的方式来阅读它.我理想的解决方案是控制器上的参数.

我尝试了几个关键字来查看默认的模型绑定器是否会接收它,但我尝试过没有尝试过.

那么获取这些信息的最简洁方法是什么?自定义模型绑定器?你能提供一个例子吗?

c# json model-binding asp.net-mvc-3

6
推荐指数
1
解决办法
2975
查看次数

如何防止复杂类型的默认绑定器?

我有一个自定义类型的模型绑定器Money.绑定器工作正常,但内置的绑定/验证正在进行,并将数据标记为无效.

我的活页夹看起来像这样:

public class MoneyModelBinder : DefaultModelBinder 
{
    protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        var money = (Money)bindingContext.Model;
        var value = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Amount").AttemptedValue;
        var currencyCode = bindingContext.ValueProvider.GetValue(bindingContext.ModelName + ".Iso3LetterCode").AttemptedValue;

        Money parsedValue;
        if (String.IsNullOrEmpty(value))
        {
            money.Amount = null;
            return;
        }

        var currency = Currency.FromIso3LetterCode(currencyCode);

        if(!Money.TryParse(value, currency, out parsedValue))
        {
            bindingContext.ModelState.AddModelError("Amount", string.Format("Unable to parse {0} as money", value));
        }
        else
        {
            money.Amount = parsedValue.Amount;
            money.Currency = parsedValue.Currency;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当用户在文本框中键入类似"45,000"的值时,我的绑定器会正确地获取值,解析它并将其设置到模型中.

我遇到的问题是,默认验证然后启动状态The value '45,000' is not …

model-binding asp.net-mvc-4

6
推荐指数
1
解决办法
437
查看次数

Web API ModelBinders - 如何以不同方式绑定对象的一个​​属性

我有以下行动签名

    [ValidateInput(false)]
    public HttpResponseMessage PostParam(Param param)
Run Code Online (Sandbox Code Playgroud)

Param看起来像这样:

public class Param {
  public int Id { get; set;}
  public string Name { get; set; }
  public string Choices { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

这就是故障 - 电线上的内容是这样的

{
  Id: 2,
  Name: "blah",
  Choices: [
    {
      foo: "bar"
    },
    {
      blah: "blo"
      something: 123
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

我不希望"选择"反序列化 - 我希望它存储为字符串(是的,我理解安全隐患).可以理解,我收到一个错误,因为默认的绑定器不知道这个.

现在使用Asp Mvc创建一个特定的ModelBinder会相当简单.ID

  • 继承DefaultModelBinder
  • 用我自己的方法覆盖属性反序列化
  • 在我的Application_Start使用中设置活页夹Binders.Add

看起来像Web Api这是一个不同的过程 - System.Web.DefaultModelBinder没有任何要覆盖的东西,我无法使用它Binders.Add.我试过环顾四周但却找不到如何实际做我想做的事情.这更加复杂,因为显然ModelBinders api在Beta和RTM上发生了相当大的变化,因此有很多过时的信息.

model-binding asp.net-web-api

6
推荐指数
1
解决办法
3298
查看次数

使用RestSharp进行Web API调用 - 将application/json添加到body,从而在操作上导致null参数

我有一个Web API服务,我试图通过控制台使用RestSharp访问.我的RestSharp代码如下所示:

            RestClient client = new RestClient(baseUrlString);
        RestRequest request = new RestRequest("controllername/actionname");
        request.RequestFormat = DataFormat.Json;

        ProcessQuestion model = new ProcessQuestion()
        {
            Id = "123456",
            InstanceId = "123",
            UniqueId = "bfb16a18-d0d6-46ab-a5b3-2f0ebbfe8626",
            PostedAnswer = new Dictionary<string, string>() { { "question_7907_1", "selected" }, { "question_7907_2", "selected" } }
        };
        request.AddBody(model);

        var response = client.Execute(request)
Run Code Online (Sandbox Code Playgroud)

我的Web API操作采用与上述模型具有相同参数的模型.调用执行时,绑定失败,参数为null.我怀疑这是由于RestRequest.AddBody方法将application/json预先添加到body值,如下所示:

{application/json={"Id":"123456","InstanceId":"123","UniqueId":"bfb16a18-d0d6-46ab-a5b3-2f0ebbfe8626","PostedAnswer":{"question_7907_1":"selected","question_7907_2":"selected"}}}
Run Code Online (Sandbox Code Playgroud)

如果我使用Fiddler发布,身体会正确地绑定到模型.以下是我在Fiddler中提供的身体价值:

{'Id':'123456','InstanceId':'123','Uniqueid':'bfb16a18-d0d6-46ab-a5b3-2f0ebbfe8626','PostedAnswer':{'question_7907_1':'selected','question_7907_2':'selected'}}
Run Code Online (Sandbox Code Playgroud)

请注意,fiddler中的body值是相同的,除了preing application/json键.

还要注意:我已经尝试过似乎所有东西......我已经在动作中分离了参数,使用了FromBody和FromUri属性,尝试了自定义DictionaryModelBinder,尝试了自定义ValueBinders,试图改变我使用RestSharp的方式(带有RequestBody参数的AddParameter,AddObject,不同的URL样式等).

有没有其他人遇到这个,如果有的话,你解决了吗?我为这项服务选择了Web API,希望模型绑定能像在MVC中那样工作,但我看到的并非如此.

谢谢

编辑(已解决):RestSharp自动将JsonSerializer用于AddBody方法中传递的对象.我想我错过了一些简单的东西,事实上我是......将Method.Post参数添加到RestRequest实例化解决了这个问题.

rest request model-binding restsharp asp.net-web-api

6
推荐指数
1
解决办法
6484
查看次数

使用GET或POST,DateTime的MVC模型绑定是不同的

我在使用某个DateTime Model属性的"远程"验证属性时遇到了以下不需要的行为.

服务器端,我的应用程序文化定义如下:

protected void Application_PreRequestHandlerExecute()
{
    if (!(Context.Handler is IRequiresSessionState)){ return; }
    Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-BE");
    Thread.CurrentThread.CurrentUICulture = new CultureInfo("nl-BE");
}
Run Code Online (Sandbox Code Playgroud)

客户端,我的应用文化定义如下:

Globalize.culture("nl-BE");
Run Code Online (Sandbox Code Playgroud)

情况1:

  • 型号属性

    [Remote("IsDateValid", "Home")]
    public DateTime? MyDate { get; set; }
    
    Run Code Online (Sandbox Code Playgroud)
  • 控制器动作

    public JsonResult IsDateValid(DateTime? MyDate)
    {
        // some validation code here
        return Json(true, JsonRequestBehavior.AllowGet);
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 在调试IsDateValid方法时,在UI中输入的日期05/10/2013(2013年10月5日)被错误地解释为10/05/2013(2013年5月10日)

案例2:

c# asp.net-mvc internationalization model-binding asp.net-mvc-4

6
推荐指数
1
解决办法
2137
查看次数

为什么ASP.NET Web Api模型绑定使用参数类型来确定值的来源?

几天后我正在尝试创建自己的web api控制器.对其余约定的二重奏我需要使用post请求来创建一个对象.为了得到具体,我有这个控制器这个动作:

public class ReservationController : ApiController
{
    [HttpPost]
    public void Create(int roomId, DateTime arrivalDate)
    {
      //do something with both parameters   
    }
}
Run Code Online (Sandbox Code Playgroud)

当我向它发送一个帖子请求时,这段代码无法正常工作,我收到的404异常是这样的:

在控制器上找不到与请求匹配的"Some"操作.

原因很简单类型从查询字符串,从尸体的复合型阅读,根据本aricle.Web api使用参数将操作与请求进行匹配,因此无法将我的操作映射到请求.

我知道我可以使用[frombody]标签,但你只能将它应用于一个参数而且我有2.我也知道我可以创建一个包含两个参数的包装器对象,但我不愿意为我的所有电话使用包装器.

所以我知道我可以通过这些方法解决这个问题.我还认为这是由于post请求的主体只能读取一次这一事实.但我的实际问题是:

为什么参数的来源是由它的类型决定的,而不是由它的可用性决定的,特别是当约定规定你应该做一个post创建的请求时?在MVC中就是这种情况,为什么不在web api中呢?

最好的祝福,

BHD

最终更新 由于我得到了一些赞成,可能更多人面临同样的问题.最后它是这样的:Web-Api!= MVC.这根本不是一回事,web api团队做出的设计决策与我认为的mvc团队不同.

c# asp.net rest model-binding asp.net-web-api

6
推荐指数
1
解决办法
5317
查看次数

南希模型绑定

嗨,我正在学习南希,我正在尝试绑定模型,但我收到错误:

Error   8   'NancyFxTutorial.CarModule' does not contain a definition for 'Bind' and no extension method 'Bind' accepting a first argument of type 'NancyFxTutorial.CarModule' could be found (are you missing a using directive or an assembly reference?) C:\Development\Projects\C#\Web\Nancy\NancyFxTutorial\NancyFxTutorial\CarModule.cs
Run Code Online (Sandbox Code Playgroud)

模型:

public class BrowseCarQuery
{
    public string Make { get; set; }
    public string Model { get; set; }
}

public class CarModule : NancyModule
{
    public CarModule()
    {
        Get["/status"] = _ => "Hello World";

        Get["/Car/{id}"] = parameters =>
            {
                int id = …
Run Code Online (Sandbox Code Playgroud)

c# model-binding nancy

6
推荐指数
1
解决办法
6746
查看次数

MVC 5中的TryUpdate()和Update()方法有什么区别吗?

MVC 5 TryUpdate()Update()方法之间有什么区别吗?提前致谢

asp.net-mvc model-binding

6
推荐指数
1
解决办法
176
查看次数

在.Net Core 2.2 Web API中绑定JSON的模型

我只是浪费了很多时间来尝试定制ComplexTypeModelBinder工作.无论我做了什么,它都没有奏效.事实证明,这仅在数据作为表单数据发布时有效; 当你发布一个JSON对象(在我的情况下从Swagger"试用"表单)时,ComplexTypeModelBinder永远不会调用该SetProperty方法.

我有很多模型,有些比其他更复杂,我用自定义属性注释了一些属性.每当该属性被绑定时,我希望它" 标准化 "(对它应用一些"格式化"),以便在模型得到验证时,验证器可以看到"标准化"数据而不是用户输入的数据.

我真的,真的,想要保持当前的模型绑定行为,因为它目前工作正常但有一个例外,即注释属性由我实现的一些代码处理.所有其他属性和行为应保持原样.这就是我希望继承的原因ComplexTypeModelBinder,但是,事实证明,如果数据以JSON的形式发布,则这不起作用.

我的(示例)模型看起来像:

public class MyComplexModel
{
    public int Id { get; set; }
    public string Name { get; set; }

    [FormatNumber(NumberFormat.E164)]
    public string PhoneNumber { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我的控制器方法如下所示:

[HttpPost]
public MyComplexModel Post(MyComplexModel model)
{
    return model;
}
Run Code Online (Sandbox Code Playgroud)

我的(不工作)自定义ComplexTypeModelBinder看起来像:

public class MyModelBinder : ComplexTypeModelBinder
{
    private readonly INumberFormatter _numberformatter;

    private static readonly ConcurrentDictionary<Type, Dictionary<string, FormatNumberAttribute>> _formatproperties = new ConcurrentDictionary<Type, Dictionary<string, FormatNumberAttribute>>();

    public MyModelBinder(IDictionary<ModelMetadata, IModelBinder> …
Run Code Online (Sandbox Code Playgroud)

c# model-binding asp.net-web-api asp.net-core asp.net-core-webapi

6
推荐指数
0
解决办法
1090
查看次数